From d0e7edee32a9222094f0a4299ba7cb5317b7b933 Mon Sep 17 00:00:00 2001 From: gimre Date: Tue, 11 Jan 2022 17:20:39 +0100 Subject: [PATCH] move to monorepo --- .dockerignore | 19 - .gitignore | 20 - .gitmodules | 3 - .travis.yml | 45 - CHANGELOG.md | 324 - CODE_OF_CONDUCT.md | 46 - COMPATIBILITY.md | 11 - CONTRIBUTING.md | 92 - COPYING.LESSER | 165 - Dockerfile | 13 - LICENSE.txt | 3 - README.md | 114 +- catapult-sdk/.eslintignore | 1 - catapult-sdk/.eslintrc | 123 - catapult-sdk/package.json | 45 - catapult-sdk/src/crypto/keyPair.js | 75 - catapult-sdk/src/crypto/merkleAuditProof.js | 97 - catapult-sdk/src/crypto/sha3Hasher.js | 78 - catapult-sdk/src/index.js | 107 - catapult-sdk/src/model/EntityType.js | 104 - .../src/model/ModelFormatterBuilder.js | 83 - catapult-sdk/src/model/ModelSchemaBuilder.js | 348 - catapult-sdk/src/model/ModelType.js | 71 - catapult-sdk/src/model/address.js | 130 - catapult-sdk/src/model/idReducer.js | 91 - catapult-sdk/src/model/namespace.js | 53 - catapult-sdk/src/model/networkInfo.js | 76 - catapult-sdk/src/model/restriction.js | 40 - catapult-sdk/src/model/status.js | 211 - .../src/modelBinary/AggregateModelCodec.js | 44 - catapult-sdk/src/modelBinary/ModelCodec.js | 52 - .../src/modelBinary/ModelCodecBuilder.js | 111 - .../src/modelBinary/blockHeaderCodec.js | 71 - .../src/modelBinary/embeddedEntityCodec.js | 59 - .../modelBinary/importanceBlockHeaderCodec.js | 55 - catapult-sdk/src/modelBinary/serialize.js | 57 - catapult-sdk/src/modelBinary/sizes.js | 65 - .../src/modelBinary/transactionCodec.js | 48 - .../src/modelBinary/transactionExtensions.js | 79 - .../src/modelBinary/verifiableEntityCodec.js | 61 - catapult-sdk/src/packet/PacketType.js | 90 - catapult-sdk/src/packet/header.js | 43 - catapult-sdk/src/parser/BinaryParser.js | 180 - catapult-sdk/src/parser/PacketParser.js | 114 - catapult-sdk/src/plugins/CatapultPlugin.js | 49 - catapult-sdk/src/plugins/accountLink.js | 121 - catapult-sdk/src/plugins/aggregate.js | 223 - .../src/plugins/catapultModelSystem.js | 107 - catapult-sdk/src/plugins/lockHash.js | 78 - catapult-sdk/src/plugins/lockSecret.js | 113 - catapult-sdk/src/plugins/metadata.js | 153 - catapult-sdk/src/plugins/mosaic.js | 127 - catapult-sdk/src/plugins/multisig.js | 100 - catapult-sdk/src/plugins/namespace.js | 191 - catapult-sdk/src/plugins/receipts.js | 130 - catapult-sdk/src/plugins/restrictions.js | 268 - catapult-sdk/src/plugins/transfer.js | 94 - .../src/serializer/BinarySerializer.js | 140 - .../serializer/SerializedSizeCalculator.js | 80 - catapult-sdk/src/utils/SchemaType.js | 45 - catapult-sdk/src/utils/arrayUtils.js | 88 - catapult-sdk/src/utils/base32.js | 109 - catapult-sdk/src/utils/charMapping.js | 60 - catapult-sdk/src/utils/convert.js | 219 - catapult-sdk/src/utils/formattingUtils.js | 53 - catapult-sdk/src/utils/future.js | 57 - catapult-sdk/src/utils/objects.js | 69 - catapult-sdk/src/utils/schemaFormatter.js | 106 - catapult-sdk/src/utils/uint64.js | 175 - catapult-sdk/test/.eslintrc | 7 - catapult-sdk/test/binaryTestUtils.js | 100 - catapult-sdk/test/crypto/keyPair_spec.js | 338 - .../test/crypto/merkleAuditProof_spec.js | 283 - catapult-sdk/test/crypto/sha3Hasher_spec.js | 172 - catapult-sdk/test/model/EntityType_spec.js | 67 - .../test/model/ModelFormatterBuilder_spec.js | 295 - .../test/model/ModelSchemaBuilder_spec.js | 561 -- catapult-sdk/test/model/ModelType_spec.js | 48 - catapult-sdk/test/model/address_spec.js | 238 - catapult-sdk/test/model/idReducer_spec.js | 165 - catapult-sdk/test/model/namespace_spec.js | 58 - catapult-sdk/test/model/networkInfo_spec.js | 90 - catapult-sdk/test/model/restriction_spec.js | 48 - catapult-sdk/test/model/status_spec.js | 56 - .../modelBinary/ModelCodecBuilder_spec.js | 255 - .../test/modelBinary/blockHeaderCodec_spec.js | 71 - .../modelBinary/embeddedEntityCodec_spec.js | 50 - .../importanceBlockHeaderCodec_spec.js | 57 - .../test/modelBinary/serialize_spec.js | 80 - .../test/modelBinary/transactionCodec_spec.js | 38 - .../modelBinary/transactionExtensions_spec.js | 164 - .../modelBinary/verifiableEntityCodec_spec.js | 53 - catapult-sdk/test/packet/header_spec.js | 45 - catapult-sdk/test/parser/BinaryParser_spec.js | 187 - catapult-sdk/test/parser/PacketParser_spec.js | 141 - catapult-sdk/test/plugins/accountLink_spec.js | 160 - catapult-sdk/test/plugins/aggregate_spec.js | 407 - .../test/plugins/catapultModelSystem_spec.js | 202 - catapult-sdk/test/plugins/lockHash_spec.js | 101 - catapult-sdk/test/plugins/lockSecret_spec.js | 147 - catapult-sdk/test/plugins/metadata_spec.js | 187 - catapult-sdk/test/plugins/mosaic_spec.js | 164 - catapult-sdk/test/plugins/multisig_spec.js | 175 - catapult-sdk/test/plugins/namespace_spec.js | 330 - catapult-sdk/test/plugins/receipts_spec.js | 291 - .../test/plugins/restrictions_spec.js | 392 - catapult-sdk/test/plugins/transfer_spec.js | 176 - .../test/serializer/BinarySerializer_spec.js | 129 - .../SerializedSizeCalculator_spec.js | 59 - catapult-sdk/test/testUtils.js | 43 - catapult-sdk/test/utils/SchemaType_spec.js | 36 - catapult-sdk/test/utils/arrayUtils_spec.js | 230 - catapult-sdk/test/utils/base32_spec.js | 173 - catapult-sdk/test/utils/charMapping_spec.js | 112 - catapult-sdk/test/utils/convert_spec.js | 439 - .../test/utils/formattingUtils_spec.js | 121 - catapult-sdk/test/utils/future_spec.js | 137 - catapult-sdk/test/utils/objects_spec.js | 210 - .../test/utils/schemaFormatter_spec.js | 333 - catapult-sdk/test/utils/uint64_spec.js | 347 - catapult-sdk/yarn.lock | 2953 ------- docker-build-local.sh | 1 - rest/.eslintrc | 128 - rest/bootstrap-preset-local.yml | 24 - rest/bootstrap-preset-mainnet.yml | 21 - rest/bootstrap-preset-testnet.yml | 21 - rest/package.json | 62 - rest/resources/rest.json | 98 - rest/src/connection/MessageChannelBuilder.js | 120 - rest/src/connection/catapultConnection.js | 92 - rest/src/connection/connectionService.js | 137 - rest/src/connection/serverMessageHandlers.js | 75 - rest/src/connection/zmqService.js | 68 - rest/src/connection/zmqUtils.js | 174 - rest/src/db/CatapultDb.js | 648 -- rest/src/db/connector.js | 36 - rest/src/db/dbFormattingRules.js | 54 - rest/src/db/dbUtils.js | 116 - rest/src/db/entityEmitterFactory.js | 40 - rest/src/index.js | 212 - rest/src/plugins/AccountType.js | 35 - rest/src/plugins/CatapultRestPlugin.js | 70 - rest/src/plugins/aggregate/aggregate.js | 66 - rest/src/plugins/aggregate/aggregateRoutes.js | 51 - rest/src/plugins/empty.js | 36 - rest/src/plugins/lockHash/LockHashDb.js | 74 - rest/src/plugins/lockHash/lockHash.js | 40 - rest/src/plugins/lockHash/lockHashRoutes.js | 67 - rest/src/plugins/lockSecret/LockSecretDb.js | 75 - rest/src/plugins/lockSecret/lockSecret.js | 40 - .../plugins/lockSecret/lockSecretRoutes.js | 68 - rest/src/plugins/metadata/MetadataDb.js | 83 - rest/src/plugins/metadata/metadata.js | 40 - rest/src/plugins/metadata/metadataRoutes.js | 66 - rest/src/plugins/mosaic/MosaicDb.js | 75 - rest/src/plugins/mosaic/mosaic.js | 42 - rest/src/plugins/mosaic/mosaicRoutes.js | 64 - rest/src/plugins/mosaic/supplyRoutes.js | 104 - rest/src/plugins/multisig/MultisigDb.js | 46 - rest/src/plugins/multisig/multisig.js | 40 - rest/src/plugins/multisig/multisigRoutes.js | 59 - rest/src/plugins/multisig/multisigUtils.js | 77 - rest/src/plugins/namespace/NamespaceDb.js | 158 - rest/src/plugins/namespace/namespace.js | 40 - rest/src/plugins/namespace/namespaceRoutes.js | 124 - rest/src/plugins/namespace/namespaceUtils.js | 102 - rest/src/plugins/receipts/ReceiptsDb.js | 132 - rest/src/plugins/receipts/receipts.js | 40 - rest/src/plugins/receipts/receiptsRoutes.js | 64 - .../plugins/restrictions/RestrictionsDb.js | 109 - rest/src/plugins/restrictions/restrictions.js | 40 - .../restrictions/restrictionsRoutes.js | 97 - rest/src/plugins/routeSystem.js | 83 - rest/src/routes/MerkelTree.js | 225 - rest/src/routes/accountRoutes.js | 84 - rest/src/routes/allRoutes.js | 48 - rest/src/routes/blockRoutes.js | 62 - rest/src/routes/chainRoutes.js | 40 - rest/src/routes/dbFacade.js | 95 - rest/src/routes/finalizationRoutes.js | 74 - rest/src/routes/merkleUtils.js | 63 - rest/src/routes/networkRoutes.js | 137 - rest/src/routes/nodeRoutes.js | 205 - rest/src/routes/routeResultTypes.js | 46 - rest/src/routes/routeUtils.js | 400 - rest/src/routes/transactionRoutes.js | 127 - rest/src/routes/transactionStatusRoutes.js | 45 - rest/src/routes/wsRoutes.js | 32 - rest/src/server/SubscriptionManager.js | 98 - rest/src/server/bootstrapper.js | 280 - rest/src/server/errors.js | 64 - rest/src/server/formatters.js | 96 - rest/src/server/messageFormattingRules.js | 41 - rest/src/server/websocketMessageHandler.js | 73 - rest/src/server/websocketUtils.js | 100 - rest/src/sockets/finalizationProofCodec.js | 87 - rest/src/sockets/nodeInfoCodec.js | 50 - rest/src/sockets/nodePeersCodec.js | 40 - rest/src/sockets/nodeTimeCodec.js | 38 - rest/src/sockets/stateTreesCodec.js | 42 - rest/test/.eslintrc | 14 - .../connection/MessageChannelBuilder_spec.js | 278 - rest/test/connection/MockSocket.js | 57 - .../connection/catapultConnection_spec.js | 204 - .../test/connection/connectionService_spec.js | 234 - .../connection/serverMessageHandlers_spec.js | 168 - rest/test/connection/zmqService_spec.js | 282 - rest/test/connection/zmqUtils_spec.js | 540 -- rest/test/db/CatapultDb_spec.js | 2703 ------ rest/test/db/connector_spec.js | 47 - rest/test/db/dbFormattingRules_spec.js | 253 - rest/test/db/dbUtils_spec.js | 213 - rest/test/db/entityEmitterFactory_spec.js | 95 - rest/test/db/utils/dbTestUtils.js | 305 - rest/test/db/utils/testDbOptions.js | 33 - rest/test/merkle/trees.json | 322 - .../plugins/aggregate/aggregateRoutes_spec.js | 92 - rest/test/plugins/aggregate/aggregate_spec.js | 132 - rest/test/plugins/empty_spec.js | 44 - rest/test/plugins/lockHash/LockHashDb_spec.js | 264 - .../plugins/lockHash/lockHashRoutes_spec.js | 218 - rest/test/plugins/lockHash/lockHash_spec.js | 64 - .../plugins/lockSecret/LockSecretDb_spec.js | 242 - .../lockSecret/lockSecretRoutes_spec.js | 243 - .../plugins/lockSecret/lockSecret_spec.js | 64 - rest/test/plugins/metadata/MetadataDb_spec.js | 277 - .../plugins/metadata/metadataRoutes_spec.js | 243 - rest/test/plugins/metadata/metadata_spec.js | 62 - rest/test/plugins/mosaic/MosaicDb_spec.js | 304 - rest/test/plugins/mosaic/mosaicRoutes_spec.js | 230 - rest/test/plugins/mosaic/mosaic_spec.js | 66 - rest/test/plugins/mosaic/supplyRoutes_spec.js | 181 - rest/test/plugins/multisig/MultisigDb_spec.js | 36 - .../multisig/entriesByAccountsTestUtils.js | 102 - .../plugins/multisig/multisigDbTestUtils.js | 48 - .../plugins/multisig/multisigRoutes_spec.js | 218 - rest/test/plugins/multisig/multisig_spec.js | 49 - .../multisig/routeAddressGetTestUtils.js | 65 - .../plugins/namespace/NamespaceDb_spec.js | 606 -- .../plugins/namespace/namespaceDbTestUtils.js | 106 - .../plugins/namespace/namespaceRoutes_spec.js | 610 -- .../plugins/namespace/namespaceUtils_spec.js | 185 - rest/test/plugins/namespace/namespace_spec.js | 65 - rest/test/plugins/receipts/ReceiptsDb_spec.js | 617 -- .../plugins/receipts/receiptsRoutes_spec.js | 594 -- rest/test/plugins/receipts/receipts_spec.js | 49 - .../restrictions/RestrictionsDb_spec.js | 348 - .../restrictions/restrictionsDbTestUtils.js | 123 - .../restrictions/restrictionsRoutes_spec.js | 282 - .../plugins/restrictions/restrictions_spec.js | 67 - rest/test/plugins/routeSystem_spec.js | 172 - rest/test/plugins/utils/pluginTestUtils.js | 83 - rest/test/routes/MerkleTree_spec.js | 313 - rest/test/routes/accountRoutes_spec.js | 463 - rest/test/routes/allRoutes_spec.js | 115 - rest/test/routes/blockRoutes_spec.js | 173 - rest/test/routes/chainRoutes_spec.js | 67 - rest/test/routes/dbFacade_spec.js | 136 - rest/test/routes/finalizationRoutes_spec.js | 242 - rest/test/routes/networkRoutes_spec.js | 393 - rest/test/routes/nodeRoutes_spec.js | 459 - rest/test/routes/routeResultTypes_spec.js | 49 - rest/test/routes/routeUtils_spec.js | 846 -- rest/test/routes/transactionRoutes_spec.js | 646 -- .../routes/transactionStatusRoutes_spec.js | 112 - rest/test/routes/utils/routeTestUtils.js | 651 -- rest/test/routes/wsRoutes_spec.js | 116 - rest/test/server/SubscriptionManager_spec.js | 353 - rest/test/server/bootstrapper_spec.js | 1222 --- rest/test/server/certs/restSSL.crt | 33 - rest/test/server/certs/restSSL.key | 52 - rest/test/server/errors_spec.js | 105 - rest/test/server/formatters_spec.js | 260 - .../server/messageFormattingRules_spec.js | 166 - .../server/websocketMessageHandler_spec.js | 138 - rest/test/server/websocketUtils_spec.js | 222 - .../sockets/finalizationProofCodec_spec.js | 173 - rest/test/sockets/nodeInfoCodec_spec.js | 197 - rest/test/sockets/nodePeersCodec_spec.js | 159 - rest/test/sockets/nodeTimeCodec_spec.js | 43 - rest/test/sockets/stateTreeCodec_spec.js | 48 - rest/test/testUtils.js | 60 - rest/yarn.lock | 7440 ----------------- scripts/.pylintrc | 426 - scripts/eslint-templates/src.eslintrc | 116 - scripts/eslint-templates/test.eslintrc | 7 - scripts/refreshEslintConfiguration.py | 79 - spammer/.eslintrc | 124 - spammer/package.json | 41 - spammer/src/index.js | 201 - spammer/src/model/spammerUtils.js | 39 - spammer/src/model/transactionFactory.js | 55 - spammer/src/utils/networkTime.js | 25 - spammer/src/utils/random.js | 29 - spammer/src/utils/spammerOptions.js | 94 - spammer/test/.eslintrc | 7 - spammer/test/model/spammerUtils_spec.js | 71 - spammer/test/model/transactionFactory_spec.js | 85 - spammer/test/testUtils.js | 36 - spammer/test/utils/networkTime_spec.js | 46 - spammer/test/utils/random_spec.js | 62 - spammer/yarn.lock | 3634 -------- tools/.eslintrc | 124 - tools/package.json | 23 - tools/websocket/.eslintrc | 4 - tools/websocket/client.html | 226 - tools/websocket/client.js | 246 - tools/yarn.lock | 1656 ---- travis | 1 - version.txt | 1 - yarn.lock | 4 - yarn_setup.sh | 9 - 312 files changed, 1 insertion(+), 61340 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .gitignore delete mode 100644 .gitmodules delete mode 100644 .travis.yml delete mode 100644 CHANGELOG.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 COMPATIBILITY.md delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING.LESSER delete mode 100644 Dockerfile delete mode 100644 LICENSE.txt delete mode 100644 catapult-sdk/.eslintignore delete mode 100644 catapult-sdk/.eslintrc delete mode 100644 catapult-sdk/package.json delete mode 100644 catapult-sdk/src/crypto/keyPair.js delete mode 100644 catapult-sdk/src/crypto/merkleAuditProof.js delete mode 100644 catapult-sdk/src/crypto/sha3Hasher.js delete mode 100644 catapult-sdk/src/index.js delete mode 100644 catapult-sdk/src/model/EntityType.js delete mode 100644 catapult-sdk/src/model/ModelFormatterBuilder.js delete mode 100644 catapult-sdk/src/model/ModelSchemaBuilder.js delete mode 100644 catapult-sdk/src/model/ModelType.js delete mode 100644 catapult-sdk/src/model/address.js delete mode 100644 catapult-sdk/src/model/idReducer.js delete mode 100644 catapult-sdk/src/model/namespace.js delete mode 100644 catapult-sdk/src/model/networkInfo.js delete mode 100644 catapult-sdk/src/model/restriction.js delete mode 100644 catapult-sdk/src/model/status.js delete mode 100644 catapult-sdk/src/modelBinary/AggregateModelCodec.js delete mode 100644 catapult-sdk/src/modelBinary/ModelCodec.js delete mode 100644 catapult-sdk/src/modelBinary/ModelCodecBuilder.js delete mode 100644 catapult-sdk/src/modelBinary/blockHeaderCodec.js delete mode 100644 catapult-sdk/src/modelBinary/embeddedEntityCodec.js delete mode 100644 catapult-sdk/src/modelBinary/importanceBlockHeaderCodec.js delete mode 100644 catapult-sdk/src/modelBinary/serialize.js delete mode 100644 catapult-sdk/src/modelBinary/sizes.js delete mode 100644 catapult-sdk/src/modelBinary/transactionCodec.js delete mode 100644 catapult-sdk/src/modelBinary/transactionExtensions.js delete mode 100644 catapult-sdk/src/modelBinary/verifiableEntityCodec.js delete mode 100644 catapult-sdk/src/packet/PacketType.js delete mode 100644 catapult-sdk/src/packet/header.js delete mode 100644 catapult-sdk/src/parser/BinaryParser.js delete mode 100644 catapult-sdk/src/parser/PacketParser.js delete mode 100644 catapult-sdk/src/plugins/CatapultPlugin.js delete mode 100644 catapult-sdk/src/plugins/accountLink.js delete mode 100644 catapult-sdk/src/plugins/aggregate.js delete mode 100644 catapult-sdk/src/plugins/catapultModelSystem.js delete mode 100644 catapult-sdk/src/plugins/lockHash.js delete mode 100644 catapult-sdk/src/plugins/lockSecret.js delete mode 100644 catapult-sdk/src/plugins/metadata.js delete mode 100644 catapult-sdk/src/plugins/mosaic.js delete mode 100644 catapult-sdk/src/plugins/multisig.js delete mode 100644 catapult-sdk/src/plugins/namespace.js delete mode 100644 catapult-sdk/src/plugins/receipts.js delete mode 100644 catapult-sdk/src/plugins/restrictions.js delete mode 100644 catapult-sdk/src/plugins/transfer.js delete mode 100644 catapult-sdk/src/serializer/BinarySerializer.js delete mode 100644 catapult-sdk/src/serializer/SerializedSizeCalculator.js delete mode 100644 catapult-sdk/src/utils/SchemaType.js delete mode 100644 catapult-sdk/src/utils/arrayUtils.js delete mode 100644 catapult-sdk/src/utils/base32.js delete mode 100644 catapult-sdk/src/utils/charMapping.js delete mode 100644 catapult-sdk/src/utils/convert.js delete mode 100644 catapult-sdk/src/utils/formattingUtils.js delete mode 100644 catapult-sdk/src/utils/future.js delete mode 100644 catapult-sdk/src/utils/objects.js delete mode 100644 catapult-sdk/src/utils/schemaFormatter.js delete mode 100644 catapult-sdk/src/utils/uint64.js delete mode 100644 catapult-sdk/test/.eslintrc delete mode 100644 catapult-sdk/test/binaryTestUtils.js delete mode 100644 catapult-sdk/test/crypto/keyPair_spec.js delete mode 100644 catapult-sdk/test/crypto/merkleAuditProof_spec.js delete mode 100644 catapult-sdk/test/crypto/sha3Hasher_spec.js delete mode 100644 catapult-sdk/test/model/EntityType_spec.js delete mode 100644 catapult-sdk/test/model/ModelFormatterBuilder_spec.js delete mode 100644 catapult-sdk/test/model/ModelSchemaBuilder_spec.js delete mode 100644 catapult-sdk/test/model/ModelType_spec.js delete mode 100644 catapult-sdk/test/model/address_spec.js delete mode 100644 catapult-sdk/test/model/idReducer_spec.js delete mode 100644 catapult-sdk/test/model/namespace_spec.js delete mode 100644 catapult-sdk/test/model/networkInfo_spec.js delete mode 100644 catapult-sdk/test/model/restriction_spec.js delete mode 100644 catapult-sdk/test/model/status_spec.js delete mode 100644 catapult-sdk/test/modelBinary/ModelCodecBuilder_spec.js delete mode 100644 catapult-sdk/test/modelBinary/blockHeaderCodec_spec.js delete mode 100644 catapult-sdk/test/modelBinary/embeddedEntityCodec_spec.js delete mode 100644 catapult-sdk/test/modelBinary/importanceBlockHeaderCodec_spec.js delete mode 100644 catapult-sdk/test/modelBinary/serialize_spec.js delete mode 100644 catapult-sdk/test/modelBinary/transactionCodec_spec.js delete mode 100644 catapult-sdk/test/modelBinary/transactionExtensions_spec.js delete mode 100644 catapult-sdk/test/modelBinary/verifiableEntityCodec_spec.js delete mode 100644 catapult-sdk/test/packet/header_spec.js delete mode 100644 catapult-sdk/test/parser/BinaryParser_spec.js delete mode 100644 catapult-sdk/test/parser/PacketParser_spec.js delete mode 100644 catapult-sdk/test/plugins/accountLink_spec.js delete mode 100644 catapult-sdk/test/plugins/aggregate_spec.js delete mode 100644 catapult-sdk/test/plugins/catapultModelSystem_spec.js delete mode 100644 catapult-sdk/test/plugins/lockHash_spec.js delete mode 100644 catapult-sdk/test/plugins/lockSecret_spec.js delete mode 100644 catapult-sdk/test/plugins/metadata_spec.js delete mode 100644 catapult-sdk/test/plugins/mosaic_spec.js delete mode 100644 catapult-sdk/test/plugins/multisig_spec.js delete mode 100644 catapult-sdk/test/plugins/namespace_spec.js delete mode 100644 catapult-sdk/test/plugins/receipts_spec.js delete mode 100644 catapult-sdk/test/plugins/restrictions_spec.js delete mode 100644 catapult-sdk/test/plugins/transfer_spec.js delete mode 100644 catapult-sdk/test/serializer/BinarySerializer_spec.js delete mode 100644 catapult-sdk/test/serializer/SerializedSizeCalculator_spec.js delete mode 100644 catapult-sdk/test/testUtils.js delete mode 100644 catapult-sdk/test/utils/SchemaType_spec.js delete mode 100644 catapult-sdk/test/utils/arrayUtils_spec.js delete mode 100644 catapult-sdk/test/utils/base32_spec.js delete mode 100644 catapult-sdk/test/utils/charMapping_spec.js delete mode 100644 catapult-sdk/test/utils/convert_spec.js delete mode 100644 catapult-sdk/test/utils/formattingUtils_spec.js delete mode 100644 catapult-sdk/test/utils/future_spec.js delete mode 100644 catapult-sdk/test/utils/objects_spec.js delete mode 100644 catapult-sdk/test/utils/schemaFormatter_spec.js delete mode 100644 catapult-sdk/test/utils/uint64_spec.js delete mode 100644 catapult-sdk/yarn.lock delete mode 100644 docker-build-local.sh delete mode 100644 rest/.eslintrc delete mode 100644 rest/bootstrap-preset-local.yml delete mode 100644 rest/bootstrap-preset-mainnet.yml delete mode 100644 rest/bootstrap-preset-testnet.yml delete mode 100644 rest/package.json delete mode 100644 rest/resources/rest.json delete mode 100644 rest/src/connection/MessageChannelBuilder.js delete mode 100644 rest/src/connection/catapultConnection.js delete mode 100644 rest/src/connection/connectionService.js delete mode 100644 rest/src/connection/serverMessageHandlers.js delete mode 100644 rest/src/connection/zmqService.js delete mode 100644 rest/src/connection/zmqUtils.js delete mode 100644 rest/src/db/CatapultDb.js delete mode 100644 rest/src/db/connector.js delete mode 100644 rest/src/db/dbFormattingRules.js delete mode 100644 rest/src/db/dbUtils.js delete mode 100644 rest/src/db/entityEmitterFactory.js delete mode 100644 rest/src/index.js delete mode 100644 rest/src/plugins/AccountType.js delete mode 100644 rest/src/plugins/CatapultRestPlugin.js delete mode 100644 rest/src/plugins/aggregate/aggregate.js delete mode 100644 rest/src/plugins/aggregate/aggregateRoutes.js delete mode 100644 rest/src/plugins/empty.js delete mode 100644 rest/src/plugins/lockHash/LockHashDb.js delete mode 100644 rest/src/plugins/lockHash/lockHash.js delete mode 100644 rest/src/plugins/lockHash/lockHashRoutes.js delete mode 100644 rest/src/plugins/lockSecret/LockSecretDb.js delete mode 100644 rest/src/plugins/lockSecret/lockSecret.js delete mode 100644 rest/src/plugins/lockSecret/lockSecretRoutes.js delete mode 100644 rest/src/plugins/metadata/MetadataDb.js delete mode 100644 rest/src/plugins/metadata/metadata.js delete mode 100644 rest/src/plugins/metadata/metadataRoutes.js delete mode 100644 rest/src/plugins/mosaic/MosaicDb.js delete mode 100644 rest/src/plugins/mosaic/mosaic.js delete mode 100644 rest/src/plugins/mosaic/mosaicRoutes.js delete mode 100644 rest/src/plugins/mosaic/supplyRoutes.js delete mode 100644 rest/src/plugins/multisig/MultisigDb.js delete mode 100644 rest/src/plugins/multisig/multisig.js delete mode 100644 rest/src/plugins/multisig/multisigRoutes.js delete mode 100644 rest/src/plugins/multisig/multisigUtils.js delete mode 100644 rest/src/plugins/namespace/NamespaceDb.js delete mode 100644 rest/src/plugins/namespace/namespace.js delete mode 100644 rest/src/plugins/namespace/namespaceRoutes.js delete mode 100644 rest/src/plugins/namespace/namespaceUtils.js delete mode 100644 rest/src/plugins/receipts/ReceiptsDb.js delete mode 100644 rest/src/plugins/receipts/receipts.js delete mode 100644 rest/src/plugins/receipts/receiptsRoutes.js delete mode 100644 rest/src/plugins/restrictions/RestrictionsDb.js delete mode 100644 rest/src/plugins/restrictions/restrictions.js delete mode 100644 rest/src/plugins/restrictions/restrictionsRoutes.js delete mode 100644 rest/src/plugins/routeSystem.js delete mode 100644 rest/src/routes/MerkelTree.js delete mode 100644 rest/src/routes/accountRoutes.js delete mode 100644 rest/src/routes/allRoutes.js delete mode 100644 rest/src/routes/blockRoutes.js delete mode 100644 rest/src/routes/chainRoutes.js delete mode 100644 rest/src/routes/dbFacade.js delete mode 100644 rest/src/routes/finalizationRoutes.js delete mode 100644 rest/src/routes/merkleUtils.js delete mode 100644 rest/src/routes/networkRoutes.js delete mode 100644 rest/src/routes/nodeRoutes.js delete mode 100644 rest/src/routes/routeResultTypes.js delete mode 100644 rest/src/routes/routeUtils.js delete mode 100644 rest/src/routes/transactionRoutes.js delete mode 100644 rest/src/routes/transactionStatusRoutes.js delete mode 100644 rest/src/routes/wsRoutes.js delete mode 100644 rest/src/server/SubscriptionManager.js delete mode 100644 rest/src/server/bootstrapper.js delete mode 100644 rest/src/server/errors.js delete mode 100644 rest/src/server/formatters.js delete mode 100644 rest/src/server/messageFormattingRules.js delete mode 100644 rest/src/server/websocketMessageHandler.js delete mode 100644 rest/src/server/websocketUtils.js delete mode 100644 rest/src/sockets/finalizationProofCodec.js delete mode 100644 rest/src/sockets/nodeInfoCodec.js delete mode 100644 rest/src/sockets/nodePeersCodec.js delete mode 100644 rest/src/sockets/nodeTimeCodec.js delete mode 100644 rest/src/sockets/stateTreesCodec.js delete mode 100644 rest/test/.eslintrc delete mode 100644 rest/test/connection/MessageChannelBuilder_spec.js delete mode 100644 rest/test/connection/MockSocket.js delete mode 100644 rest/test/connection/catapultConnection_spec.js delete mode 100644 rest/test/connection/connectionService_spec.js delete mode 100644 rest/test/connection/serverMessageHandlers_spec.js delete mode 100644 rest/test/connection/zmqService_spec.js delete mode 100644 rest/test/connection/zmqUtils_spec.js delete mode 100644 rest/test/db/CatapultDb_spec.js delete mode 100644 rest/test/db/connector_spec.js delete mode 100644 rest/test/db/dbFormattingRules_spec.js delete mode 100644 rest/test/db/dbUtils_spec.js delete mode 100644 rest/test/db/entityEmitterFactory_spec.js delete mode 100644 rest/test/db/utils/dbTestUtils.js delete mode 100644 rest/test/db/utils/testDbOptions.js delete mode 100644 rest/test/merkle/trees.json delete mode 100644 rest/test/plugins/aggregate/aggregateRoutes_spec.js delete mode 100644 rest/test/plugins/aggregate/aggregate_spec.js delete mode 100644 rest/test/plugins/empty_spec.js delete mode 100644 rest/test/plugins/lockHash/LockHashDb_spec.js delete mode 100644 rest/test/plugins/lockHash/lockHashRoutes_spec.js delete mode 100644 rest/test/plugins/lockHash/lockHash_spec.js delete mode 100644 rest/test/plugins/lockSecret/LockSecretDb_spec.js delete mode 100644 rest/test/plugins/lockSecret/lockSecretRoutes_spec.js delete mode 100644 rest/test/plugins/lockSecret/lockSecret_spec.js delete mode 100644 rest/test/plugins/metadata/MetadataDb_spec.js delete mode 100644 rest/test/plugins/metadata/metadataRoutes_spec.js delete mode 100644 rest/test/plugins/metadata/metadata_spec.js delete mode 100644 rest/test/plugins/mosaic/MosaicDb_spec.js delete mode 100644 rest/test/plugins/mosaic/mosaicRoutes_spec.js delete mode 100644 rest/test/plugins/mosaic/mosaic_spec.js delete mode 100644 rest/test/plugins/mosaic/supplyRoutes_spec.js delete mode 100644 rest/test/plugins/multisig/MultisigDb_spec.js delete mode 100644 rest/test/plugins/multisig/entriesByAccountsTestUtils.js delete mode 100644 rest/test/plugins/multisig/multisigDbTestUtils.js delete mode 100644 rest/test/plugins/multisig/multisigRoutes_spec.js delete mode 100644 rest/test/plugins/multisig/multisig_spec.js delete mode 100644 rest/test/plugins/multisig/routeAddressGetTestUtils.js delete mode 100644 rest/test/plugins/namespace/NamespaceDb_spec.js delete mode 100644 rest/test/plugins/namespace/namespaceDbTestUtils.js delete mode 100644 rest/test/plugins/namespace/namespaceRoutes_spec.js delete mode 100644 rest/test/plugins/namespace/namespaceUtils_spec.js delete mode 100644 rest/test/plugins/namespace/namespace_spec.js delete mode 100644 rest/test/plugins/receipts/ReceiptsDb_spec.js delete mode 100644 rest/test/plugins/receipts/receiptsRoutes_spec.js delete mode 100644 rest/test/plugins/receipts/receipts_spec.js delete mode 100644 rest/test/plugins/restrictions/RestrictionsDb_spec.js delete mode 100644 rest/test/plugins/restrictions/restrictionsDbTestUtils.js delete mode 100644 rest/test/plugins/restrictions/restrictionsRoutes_spec.js delete mode 100644 rest/test/plugins/restrictions/restrictions_spec.js delete mode 100644 rest/test/plugins/routeSystem_spec.js delete mode 100644 rest/test/plugins/utils/pluginTestUtils.js delete mode 100644 rest/test/routes/MerkleTree_spec.js delete mode 100644 rest/test/routes/accountRoutes_spec.js delete mode 100644 rest/test/routes/allRoutes_spec.js delete mode 100644 rest/test/routes/blockRoutes_spec.js delete mode 100644 rest/test/routes/chainRoutes_spec.js delete mode 100644 rest/test/routes/dbFacade_spec.js delete mode 100644 rest/test/routes/finalizationRoutes_spec.js delete mode 100644 rest/test/routes/networkRoutes_spec.js delete mode 100644 rest/test/routes/nodeRoutes_spec.js delete mode 100644 rest/test/routes/routeResultTypes_spec.js delete mode 100644 rest/test/routes/routeUtils_spec.js delete mode 100644 rest/test/routes/transactionRoutes_spec.js delete mode 100644 rest/test/routes/transactionStatusRoutes_spec.js delete mode 100644 rest/test/routes/utils/routeTestUtils.js delete mode 100644 rest/test/routes/wsRoutes_spec.js delete mode 100644 rest/test/server/SubscriptionManager_spec.js delete mode 100644 rest/test/server/bootstrapper_spec.js delete mode 100644 rest/test/server/certs/restSSL.crt delete mode 100644 rest/test/server/certs/restSSL.key delete mode 100644 rest/test/server/errors_spec.js delete mode 100644 rest/test/server/formatters_spec.js delete mode 100644 rest/test/server/messageFormattingRules_spec.js delete mode 100644 rest/test/server/websocketMessageHandler_spec.js delete mode 100644 rest/test/server/websocketUtils_spec.js delete mode 100644 rest/test/sockets/finalizationProofCodec_spec.js delete mode 100644 rest/test/sockets/nodeInfoCodec_spec.js delete mode 100644 rest/test/sockets/nodePeersCodec_spec.js delete mode 100644 rest/test/sockets/nodeTimeCodec_spec.js delete mode 100644 rest/test/sockets/stateTreeCodec_spec.js delete mode 100644 rest/test/testUtils.js delete mode 100644 rest/yarn.lock delete mode 100644 scripts/.pylintrc delete mode 100644 scripts/eslint-templates/src.eslintrc delete mode 100644 scripts/eslint-templates/test.eslintrc delete mode 100644 scripts/refreshEslintConfiguration.py delete mode 100644 spammer/.eslintrc delete mode 100644 spammer/package.json delete mode 100644 spammer/src/index.js delete mode 100644 spammer/src/model/spammerUtils.js delete mode 100644 spammer/src/model/transactionFactory.js delete mode 100644 spammer/src/utils/networkTime.js delete mode 100644 spammer/src/utils/random.js delete mode 100644 spammer/src/utils/spammerOptions.js delete mode 100644 spammer/test/.eslintrc delete mode 100644 spammer/test/model/spammerUtils_spec.js delete mode 100644 spammer/test/model/transactionFactory_spec.js delete mode 100644 spammer/test/testUtils.js delete mode 100644 spammer/test/utils/networkTime_spec.js delete mode 100644 spammer/test/utils/random_spec.js delete mode 100644 spammer/yarn.lock delete mode 100644 tools/.eslintrc delete mode 100644 tools/package.json delete mode 100644 tools/websocket/.eslintrc delete mode 100644 tools/websocket/client.html delete mode 100644 tools/websocket/client.js delete mode 100644 tools/yarn.lock delete mode 160000 travis delete mode 100644 version.txt delete mode 100644 yarn.lock delete mode 100755 yarn_setup.sh diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index fe6a12860..000000000 --- a/.dockerignore +++ /dev/null @@ -1,19 +0,0 @@ -Dockerfile -.dockerignore -docker.sh - -.idea -.vscode -.git -.gitignore -.travis.yml - -*/node_modules -*/_build - -**/npm-*.log -**/yarn-*.log -**/catapult-*.log - -/rest/target/ -/rest/logs.log diff --git a/.gitignore b/.gitignore deleted file mode 100644 index cfabe844d..000000000 --- a/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -*~ -_build*/ -node_modules/ -__pycache__/ -catapult-*.log* -npm-*.log* -yarn-*.log* -.idea -.vscode/ -typings.json -typings/ -jsconfig.json -.nyc_output/ -.DS_Store -rest-*.json - -rest/coverage -/rest/target* -/rest/logs.log -/catapult-rest.iml diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index dcf374d36..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "travis"] - path = travis - url = https://github.com/nemgrouplimited/travis-functions.git diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 786dae07c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,45 +0,0 @@ -language: node_js - -node_js: - - "12" -services: - - docker - - mongodb -env: - global: - - RELEASE_BRANCH=main - - POST_RELEASE_BRANCH=main - - RELEASE_MESSAGE=release - matrix: - - SUBPROJECT=catapult-sdk - - SUBPROJECT=rest - - SUBPROJECT=spammer -cache: yarn - -before_script: -- . ./travis/docker-functions.sh -- log_env_variables -- echo '$SUBPROJECT' -- mongo mydb_test --eval 'db.createUser({user:"travis",pwd:"test",roles:["readWrite"]});' -- if [[ ! -z "$DOCKER_USERNAME" ]] ; then echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin; fi -- sh yarn_setup.sh - -script: cd ${SUBPROJECT} && yarn run lint && yarn run test:travis && cd .. - -jobs: - include: - - stage: test - name: docker test build - script: docker_build $(load_version_from_file) - - stage: publish - name: docker publish alpha - script: docker_build $(load_version_from_file) publish - if: branch = env(DEV_BRANCH) AND type = push - - stage: release - name: docker publish release - script: docker_build $(load_version_from_file) release - if: branch = env(RELEASE_BRANCH) AND type = api AND commit_message = env(RELEASE_MESSAGE) - - stage: post release - name: tag and version upgrade - script: post_release_version_file - if: branch = env(RELEASE_BRANCH) AND type = api AND commit_message = env(RELEASE_MESSAGE) diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index cba876d83..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,324 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -## [v2.4.0] - 16-Nov-2021 - -### Fixed - -- Fixed total, circulating and max supply. -- Remove cmc plugin and move `cmcRoutes` into `mosaic:supplyRoutes`. - -## [v2.3.9] - 8-Nov-2021 - -### Added - -- Added mosaic supply revocation transaction support. -- Added new catapult 1.0.3.0 new status codes. - -## [v2.3.8] - 1-Nov-2021 - -### Added - -- Removed private network type support. -- Renamed network names to from `public` to `mainnet` and from `publicTest` to `testnet`. - -## [v2.3.7] - 31-Oct-2021 - -### Added - -- Native HTTPS support by providing SSL certificates. -- `timestamp` in recipients payload. -- `timestamp` and `feeMultipler`in transactions payloads. - -### Fixed - -- Removed babel from local `catapult-sdk` module. -- Docker image migrated to ubuntu v20.04. - -## [v2.3.6] - 24-May-2021 - -### Added - -- Tokenomics endpoints. -- Symbol-bootstrap version in server version endpoints. This requires node operator to update rest.json configuration file with the correct bootstrap version details. - -### Fixed - -- Fixed zero median network transaction fee issue - -## [v2.3.5] - 13-Mar-2021 - -### Updated - -- Updated catapult-server (v1.0.0.0) status codes. - -## [v2.3.4] - 5-Mar-2021 - -### Fixed - -- Account endpoint pagination issue. - -### Added - -- Max zmq socket connection cap. - -## [v2.3.3] - 15-Feb-2021 - -### Fixed - -- Fixed duplicate alias names returned from namespace endpoint issue. -- Fixed duplicated status results. The status is now retrieved by priority. - -### Changed - -- Set default connection pool size to 10. -- Changed `node/storage` endpoint to use estimated counts from mongo collections. -- Allow all transaction groups to be queried by cosigners. -- Allow address aliases in web socket listener subscriptions. - -## [v2.3.2] - 02-Feb-2021 - -### Added - -- `FromHeight` and `ToHeight` to receipt search endpoint. - -### Fixed - -- Fixed issues on only multisig and aggregate initiator can query partial transactions. - -## [v2.3.1] - 19-Jan-2021 - -### Fixed - -- Fixed aggregate transaction codec issue. - -**We are fixing the [multisig cosignature nofitifcation issue](https://github.com/nemtech/catapult-rest/issues/278) which will be included in the next release. - -## [v2.3.0] - 14-Jan-2021 - -### Added - -- `minFeeMultiplier` from the current connected Node in transaction fees endpoint -- Added new `nodePropertyFilePath` in `rest.json`. - -### Updated - -- Moved `config-network.properties` path config from `network` to `apiNode`. -- Updated `PrivateTest` network type from `0x80` to `0xA8`. -- Re tracked to catapult-server `main` branches. - -## [v2.2.1] - 9-Dec-2020 - -### Fixed - -- Fixed v1 voting key issue in finalization route. - -## [v2.2.2] - 31-Dec-2020 - -### Updated - -- Voting key v1 to track mainnet (catapult-server). - -## [v2.2.0] - 8-Dec-2020 - -### Added - -- Catapult-server finality (0.10.0.4 - testnet/v3) support. -- Added state model versions. -- Added state merkle proof endpoints (`/merkle`) which returns deserialized merkle-patricia tree. -- Added multi-version transaction support. -- Added Symbol Bootstrap support for development and unit testing purposes. -- Added V1 and V2 voting key link transaction support. - -### Updated - -- Updated `latest` flag in namespace's collection and endpoints. -- Updated finality proof endpoints to match the latest Testnet changes. -- Updated `bmTreeSignature` schema with only `top` and `bottom` levels. -- Updated server status codes. -- Simplified search endpoints. - -### Fixed - -- Fixed `transferMosaicId`, `fromHeight` and `toHeight` transaction search filters. - -## [v2.1.0] - 25-Sept-2020 - -### Added - -- Added `totalTransactionsCount` to the block meta. - -### Changed - -- Removed `type` interpretation from the transfer transaction messages. -- Renamed `numTransactions` and `numStatements` to `transactionsCount` and `statementsCount` in the block meta. - -## [v2.0.0] - 21-Sept-2020 - -### Added - -- New `fromHeight` and `toHeight` filters to the transaction endpoints. -- Added finalization information (latest finalized block) to the new `/chain/info` endpoint. -- New WS channel subscription available: `finalizedBlock`. -- Added endpoints to get finalization proof information by height and epoch. - -### Changed - -- Reviewed account and mosaic restrictions endpoints. -- Updated voting key link's finalization points to be epochs instead. -- Merged the old `/chain/height` and `/chain/score` endpoints into `/chain/info`. - -### Fixed - -- Added missing `level` field from the multisig graph endpoint. - -## [v1.3.1] - 5-Sept-2020 - -### Fixed - -- Fixed empty node health and server endpoints. - -## [v1.3.0] - 1-Sept-2020 - -### Added - -- Added a config option to set the mongodb connection pool size. - -### Fixed - -- Greatly improved paginated endpoints performance. - -### Changed - -- Removed `totalEntries` and `totalPages` from paginated results. - -## [v1.2.1] - 21-Aug-2020 - -### Changed - -- Removed `topic` (address) from transactionStatus WS responses. -- Removed `channelName` from WS transaction metadata. -- Wrapped WS responses so that the `topic` the client subscribed to is also returned. - -## [v1.2.0] - 6-Aug-2020 - -### Added - -- TLS installation notes. -- Dockerfile. -- Automatic Travis to DockerHub releases. -- Transaction statements endpoint now accepts multiple filtered `receitpType`s. - -### Changed - -- Reviewed hash lock, secret lock, namespace, account, metadata, and receipt endpoints. -- Renamed the `master` branch to `main`. - -### Fixed - -- Height comparison towards current chain height, for height related endpoints. -- Pagination offsets sometimes were being ignored. -- `namespaces/names` endpoint did not work for some provided addresses. - -## [v1.1.3] - 27-Jun-2020 - -### Changed (since v1.0.20.50) - -- New project versioning that allows pinning on compatible core server versions and makes it easier to track REST changes. -- Resized addresses from 25 to 24 bytes. - -## [0.7.14] - 27-Mar-2019 - -### Added - -- Receipts, AccountProperties, and AccountLink plugins were activated. - -### Changed - -- Block schema field beneficiaryPublicKey has been renamed to beneficiary. -- Transaction schema fee field has been renamed to max_fee. -- createLong function from CatapultDB was moved to a new dbUtils file. - -## [0.7.13] - 27-Feb-2019 - -### Changed - -- LockHash secret hash from sha-512 to sha-256. - -### Fixed - -- Merkle tree endpoint does not return a server error when the transaction is inside the block. - -### Removed - -- Active condition from meta in mosaic mongodb collection. - -## [0.7.12] - 27-Feb-2019 - -### Added - -- Fallback when formatting receipts of unknown type. - -### Changed - -- Namespace schema to add the new alias field. - -## [0.7.11] - 8-Feb-2019 - -### Added - -- Plugin to handle AccountPropertiesTransaction. -- Plugin to support AliasTransaction. -- Plugin to handle AccountLinkTransaction. -- Plugin to handle Receipts. -- Endpoint to retrieve the account properties associated with an account. -- Endpoint to get the receipts associated with a block. -- Endpoints returning transactions now allow defining if the results should be ordered in ascending or descending order (id). - -### Changed - -- Enumeration types for hashLock, secretLock, accountPropertiesMosaic, and accountPropertiesEntityType to match the catapult-server 0.2 entity types. -- Split mosaics from namespaces to match catapult-server 0.3. -- Status error codes (status.js) to match catapult-server 0.3. -- Refactor of variables and file names. - -### Removed - -- merkleRootHash field from the block schema. - -## [0.7.8] - 3-Aug-2018 - -### Added - -- Endpoint to get an audit path for a transaction Merkle tree. -- Endpoints to get node info and node time. - -### Changed - -- zeromq dependency is used instead of zmq. - -## [0.7.7] - 17-May-2018 - -### Added -- Basic code coverage support (via nyc + coveralls) . - -### Removed - -- Script to increment the SDK version (incrementSdkVersion.py). - -## [0.7.5] - 17-May-2018 - -### Added - -- Initial code release. - -[0.7.14]: https://github.com/nemtech/catapult-rest/compare/v0.7.13...v0.7.14 -[0.7.13]: https://github.com/nemtech/catapult-rest/compare/v0.7.12...v0.7.13 -[0.7.12]: https://github.com/nemtech/catapult-rest/compare/v0.7.11...v0.7.12 -[0.7.11]: https://github.com/nemtech/catapult-rest/compare/v0.7.8...v0.7.11 -[0.7.8]: https://github.com/nemtech/catapult-rest/compare/v0.7.7...v0.7.8 -[0.7.7]: https://github.com/nemtech/catapult-rest/compare/v0.7.5...v0.7.7 -[0.7.5]: https://github.com/nemtech/catapult-rest/releases/tag/v0.7.5 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 229067f6e..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at aleix@nemeurope.eu. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md deleted file mode 100644 index 8b8cb0adb..000000000 --- a/COMPATIBILITY.md +++ /dev/null @@ -1,11 +0,0 @@ -# Server compatibility -_Note that this table just reflects compatibility with catapult-server, other breaking changes in regards to the API may be released -in-between the listed versions_ - -| catapult-rest | catapult-server | Highlighted notes | -|---------------|-----------------|--------------------------------------------------------------------| -| v2.1.0 | v10.0.3 | Finalization support | -| v1.1.3 | v9.6.2 | Address resized (25 -> 24 bytes)
Updated REST version numbering | -| v1.0.20.50 | v9.5.1 | VRF support | -| v1.0.20.31 | v9.4.1 | TLS support | -| v1.0.20.24 | v9.3.1 | - | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index d25b97059..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,92 +0,0 @@ -# Contributing to catapult-rest - -First off, thank you for considering contributing to catapult-rest. -It’s people like you that make catapult-rest such a great tool. - -catapult-rest is an open source project and we love to receive contributions from -our community — you! There are many ways to contribute, from writing tutorials or blog -posts, improving the documentation, submitting bug reports and feature requests or -writing code which can be incorporated into catapult-rest itself. - -Following these guidelines helps to communicate that you respect the time of -the developers managing and developing this open source project. In return, -they should reciprocate that respect in addressing your issue, assessing changes, -and helping you finalize your pull requests. - -Please, **don't use the issue tracker for support questions**. - -## Bug reports - -If you think you have found a bug in catapult-rest, first make sure that you -are testing against the latest version of catapult-rest - your issue may already -have been fixed. If not, search our issues list on GitHub in case a similar -issue has already been opened. - -It is very helpful if you can prepare a reproduction of the bug. In other words, -provide a small test case which we can run to confirm your bug. It makes it easier to -find the problem and to fix it. - -Please, take in consideration the next template to report your issue: - -> **Expected Behaviour**\ -> Short and expressive sentence explaining what the code should do.\ -> **Current Behaviour**\ -> A short sentence enplaning what the code does. \ -> **Steps to reproduce**\ -> For faster issue detection, we would need a step by step description do reproduce the issue. - - -Provide as much information as you can. - -Open a new issue [here][github-issues]. - -## Feature requests - -If you find yourself wishing for a feature that doesn't exist in catapult-rest, -you are probably not alone. There are bound to be others out there with similar -needs. Many of the features that catapult-rest has today have been added because -our users saw the need. Open an [issue][github-issues] on our issues list on GitHub which describes -the feature you would like to see, why you need it, and how it should work. - -## Contributing code and documentation changes - -If you have a bugfix or new feature that you would like to contribute to catapult-rest, please find or open an issue -about it first. Talk about what you would like to do. It may be that somebody is already working on it, or that there -are particular issues that you should know about before implementing the change. - -We enjoy working with contributors to get their code accepted. There are many approaches to fixing a problem and it is -important to find the best approach before writing too much code. - -### Contributing License Notice - -Due to dual licensing of catapult and possible future easing of selected open source license, when you contribute code, -you'll be required to provide signed waiver of copyrights. - -Whether or not you state this explicitly, by submitting any copyrighted material via pull request, email, or other means -you agree to license the material under the project's licenses and warrant that you have the legal authority to do so. - -### Fork and clone the repository - -You will need to fork the main catapult-rest code or documentation repository and clone -it to your local machine. See [github help page](https://help.github.com/articles/fork-a-repo/) for help. - -Further instructions for specific projects are given below. - -### Submitting your changes - -Once your changes and tests are ready to submit for review: - -1. Test your changes - - Run the test suite to make sure that nothing is broken. - -2. Submit a pull request - - Push your local changes to your forked copy of the repository and [submit a pull request](https://help.github.com/articles/about-pull-requests/). In the pull request, choose a title which sums up the changes that you have made, and in the body provide more details about what your changes do. Also mention the number of the issue where discussion has taken place, eg "Closes #123". - -Then sit back and wait. There will probably be discussion about the pull request and, if any changes are needed, we would love to work with you to get your pull request merged into catapult-rest. - -*CONTRIBUTING.md is based on [CONTRIBUTING-template.md](https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md)* , [elasticsearch/CONTRIBUTING](https://github.com/elastic/elasticsearch/blob/master/CONTRIBUTING.md) and [spark/CONTRIBUTING](https://github.com/apache/spark/blob/master/CONTRIBUTING.md) - -[pull-request]: https://help.github.com/articles/about-pull-requests/ -[github-issues]: https://github.com/nemtech/catapult-rest/issues diff --git a/COPYING.LESSER b/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 90233915f..000000000 --- a/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ubuntu:20.04 - -RUN apt-get update && apt-get install -y curl \ - && curl -fsSL https://deb.nodesource.com/setup_12.x | bash - \ - && apt-get install -y nodejs \ - && node --version \ - && npm --version \ - && npm install -g yarn - -WORKDIR /app -COPY . /app/catapult-rest -RUN cd catapult-rest && ./yarn_setup.sh -WORKDIR /app/catapult-rest/rest diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index c28077508..000000000 --- a/LICENSE.txt +++ /dev/null @@ -1,3 +0,0 @@ -Source code in this repository is variously licensed under the LGPL v3 license, or the Tech Bureau Commercial License. -Source code in a given file is licensed under the LGPL v3 license, unless otherwise noted at the beginning of the file or a -LICENSE file present in the directory subtree declares a separate license. The LGPL v3 license details are located under the COPYING.LESSER file. diff --git a/README.md b/README.md index fc404f363..89e62670c 100644 --- a/README.md +++ b/README.md @@ -1,115 +1,3 @@ # catapult-rest -[![Build Status](https://api.travis-ci.com/nemtech/catapult-rest.svg?branch=main)](https://travis-ci.com/nemtech/catapult-rest) -[![Coverage Status](https://coveralls.io/repos/github/nemtech/catapult-rest/badge.svg?branch=main)](https://coveralls.io/github/nemtech/catapult-rest?branch=main) - -Catapult REST gateway combines HTTP and WebSockets to perform read and write actions on the blockchain. - -## Requirements - -- Node.js 12 LTS -- [yarn][yarn] dependency manager -- [docker][docker] -- [symbol-bootstrap][symbol-bootstrap] - -## Installation - -1. Validate you are able to run Bootstrap by following the [requirements](https://github.com/nemtech/symbol-bootstrap#requirements). - -2. Install the project dependencies: - -``` -./yarn_setup.sh -``` - -3. Run a Symbol private network using Bootstrap: - -``` -cd rest -yarn bootstrap-start -``` - -This Symbol network is a [light](https://github.com/nemtech/symbol-bootstrap#out-of-the-box-presets) preset network without rest. -Rest will be running from source code, so you can test your changes! -Mongo DB (27017), Server (7900) and Broker (7902) ports are open to localhost. - -4. Run catapult-rest: - -In another terminal: - -``` -yarn start:dev -``` - -If everything goes well, you should see catapult-rest running by opening ``http://localhost:3000/node/info`` in a new browser tab. - -Alternatively, you can run bootstrap in `detached` mode to avoid opening a new terminal. - -``` -cd rest -yarn bootstrap-start-detached -yarn start:dev -yarn bootstrap-stop -``` - -Useful for test automation: - -``` -cd rest -yarn bootstrap-start-detached -yarn test -yarn bootstrap-stop -``` - -## Testnet - -Another alternative, is having bootstrap creating a Testnet node without rest that you can run from code: - -``` -yarn bootstrap-start-testnet -``` - -In another terminal - -``` -yarn start:dev -``` - - -## Usage - -Please refer to the [documentation](https://nemtech.github.io/api.html) for more information. - -## Versioning - -Make sure you choose a [version compatible](COMPATIBILITY.md) with the [catapult-server][catapult-server] node you want to use it with. - -Starting on `v1.1.0`, version numbers are described as follows: - -`vX.Y.Z` - -- X: This serves to lock for compatibility with `catapult-server`, thus it is safe to update by keeping this number without REST -losing server compatibility. Additionally, any breaking change to the server should require to upgrade this number. -- Y: This serves to lock on safe updates to this project, thus it is safe to update by keeping this number without worrying about -introducing breaking changes. -- Z: Represents minor changes progress, used to identify specific versions when reporting bugs, or to get extensions to the code. - -## Contributing - -Before contributing please [read this](CONTRIBUTING.md) and consider the following guidelines: -- Submit small and concise PRs that address a single and clear feature or issue -- Submit only fully tested code -- Split test scope areas with _Arrange/Act/Assert_ comments -- Use spontaneous comments only when necessary -- Follow linting rules - tests are set to fail if those aren't followed -- Notify or update related API resources of accepted changes ([OpenAPI](https://github.com/nemtech/symbol-openapi)) - -## License - -Copyright (c) 2018 Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp Licensed under the [GNU Lesser General Public License v3](LICENSE) - -[yarn]: https://yarnpkg.com/lang/en/ -[catapult-server]: https://github.com/nemtech/catapult-server -[symbol-bootstrap]: https://github.com/nemtech/symbol-bootstrap -[docker]: https://www.docker.com -[api-node]: https://nemtech.github.io/server.html#installation +Repository moved into [symbol/symbol](//github.com/symbol/symbol) monorepo. diff --git a/catapult-sdk/.eslintignore b/catapult-sdk/.eslintignore deleted file mode 100644 index d79fc0c71..000000000 --- a/catapult-sdk/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -src/external/** diff --git a/catapult-sdk/.eslintrc b/catapult-sdk/.eslintrc deleted file mode 100644 index 2429c56a1..000000000 --- a/catapult-sdk/.eslintrc +++ /dev/null @@ -1,123 +0,0 @@ ---- -env: - es6: true -extends: airbnb -parserOptions: - sourceType: module - -rules: - indent: - - error - - tab - linebreak-style: - - error - - unix - quotes: - - error - - single - semi: - - error - - always - yoda: - - error - - always - curly: - - error - - multi-or-nest - - consistent - max-len: - - error - - code: 140 - - max-classes-per-file: - - off - prefer-object-spread: - - off - - nonblock-statement-body-position: - - error - - below - implicit-arrow-linebreak: - - off - - no-tabs: - - off - no-bitwise: - - off - no-plusplus: - - off - no-mixed-operators: - - error - - allowSamePrecedence: true - no-param-reassign: - - error - - props: false - no-underscore-dangle: - - error - - allow: - - _id # mongodb identifier - - camelcase: - - off # for consts, e.g. Foo_Bar - comma-dangle: - - error - - never - default-case: - - off - - arrow-parens: - - error - - as-needed - func-names: - - error - - never - func-style: - - error - - expression - wrap-iife: - - error - - inside - - prefer-destructuring: - - error - - object: true - array: false - - valid-jsdoc: - - error - - requireReturn: false - prefer: - arg: param - argument: param - class: constructor - return: returns - preferType: - Boolean: boolean - Number: number - Object: object - String: string - - import/order: - - error - - newlines-between: never - groups: - - index - - sibling - - parent - - internal - - external - - builtin - alphabetize: - order: asc - - import/extensions: - - error - - never - import/no-absolute-path: - - error - import/no-unresolved: - - 2 - import/no-deprecated: - - error - import/named: - - error diff --git a/catapult-sdk/package.json b/catapult-sdk/package.json deleted file mode 100644 index 5535a427c..000000000 --- a/catapult-sdk/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "catapult-sdk", - "version": "0.0.0", - "description": "Catapult SDK core", - "main": "src/index.js", - "scripts": { - "test": "mocha --full-trace --recursive", - "test:coverage": "nyc npm test && nyc report --reporter=text-lcov", - "test:jenkins": "cross-env JUNIT_REPORT_PATH=test-results.xml mocha --reporter mocha-jenkins-reporter --forbid-only --full-trace --recursive test || exit 0", - "test:travis": "nyc npm test && nyc report --reporter=text-lcov | coveralls", - "lint": "eslint src test", - "lint:fix": "eslint src test --fix", - "lint:jenkins": "eslint -o tests.catapult.lint.xml -f junit src test || exit 0" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "chai": "^4.2.0", - "coveralls": "^3.1.1", - "cross-env": "^5.2.0", - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.1.0", - "eslint-plugin-import": "^2.19.1", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.19.0", - "eslint-plugin-react-hooks": "^2.5.0", - "mocha": "^9.1.0", - "mocha-jenkins-reporter": "^0.4.6", - "nyc": "^14.1.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "js-sha3": "^0.8.0", - "long": "^4.0.0", - "ripemd160": "^2.0.2", - "tweetnacl": "^1.0.1" - }, - "nyc": { - "exclude": [ - "src/external/*.js", - "test/**/*" - ] - } -} diff --git a/catapult-sdk/src/crypto/keyPair.js b/catapult-sdk/src/crypto/keyPair.js deleted file mode 100644 index 5cc9469d2..000000000 --- a/catapult-sdk/src/crypto/keyPair.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module crypto/keyPair */ -const convert = require('../utils/convert'); -const tweetnacl = require('tweetnacl'); - -// region exported functions - -/** - * A catapult public key. - * @typedef {Uint8Array} PublicKey - */ - -/** - * A catapult key pair composed of a public, a private, and a secret keys. - * @typedef {object} KeyPair - * @property {module:crypto/keyPair~PublicKey} publicKey Public key. - * @property {Uint8Array} privateKey Private key. - * @property {Uint8Array} secretKey Secret key. - */ - -const keyPairModule = { - /** - * Creates a key pair from a private key string. - * @param {string} privateKeyString A hex encoded private key string. - * @returns {module:crypto/keyPair~KeyPair} Key pair. - */ - createKeyPairFromPrivateKeyString: privateKeyString => { - const privateKey = convert.hexToUint8(privateKeyString); - if (32 !== privateKey.length) - throw Error(`private key has unexpected size: ${privateKey.length}`); - - return Object.assign({ privateKey }, tweetnacl.sign.keyPair.fromSeed(privateKey)); - }, - - /** - * Signs a data buffer with a key pair. - * @param {module:crypto/keyPair~KeyPair} keyPair Key pair to use for signing. - * @param {Uint8Array} data Data to sign. - * @returns {Uint8Array} Signature. - */ - sign: (keyPair, data) => tweetnacl.sign.detached(data, keyPair.secretKey), - - /** - * Verifies a signature. - * @param {module:crypto/keyPair~PublicKey} publicKey Public key to use for verification. - * @param {Uint8Array} data Data to verify. - * @param {Uint8Array} signature Signature to verify. - * @returns {boolean} true if the signature is verifiable, false otherwise. - */ - verify: (publicKey, data, signature) => tweetnacl.sign.detached.verify(data, signature, publicKey) -}; - -// endregion - -module.exports = keyPairModule; diff --git a/catapult-sdk/src/crypto/merkleAuditProof.js b/catapult-sdk/src/crypto/merkleAuditProof.js deleted file mode 100644 index 8af54447a..000000000 --- a/catapult-sdk/src/crypto/merkleAuditProof.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const arrayUtils = require('../utils/arrayUtils'); - -const NodePosition = Object.freeze({ - left: 'left', - right: 'right' -}); - -class HashNotFoundError extends Error {} -class InvalidTree extends Error {} - -const evenify = number => (number % 2 ? number + 1 : number); - -/** - * Returns the index of a hash in a Merkle tree. - * @param {Uint8Array} hash Hash to look up in the tree. - * @param {object} tree Merkle tree object containing the number of hashed elements and the tree of hashes. - * @returns {array} Index of the first element in the tree matching the given hash, otherwise -1 is returned. - */ -const indexOfLeafWithHash = (hash, tree) => tree.nodes - .slice(0, evenify(tree.count)) - .findIndex(element => arrayUtils.deepEqual(element, hash)); - -const siblingOf = nodeIndex => { - if (nodeIndex % 2) { - return { - position: NodePosition.left, - index: nodeIndex - 1 - }; - } - return { - position: NodePosition.right, - index: nodeIndex + 1 - }; -}; - -/** - * Given a Merkle tree and a hashed element in it, returns the audit path required for a consistency check. - * @param {Uint8Array} hash Element's hash for which to build the audit path. - * @param {object} tree Merkle tree object containing the number of elements and the tree of hashes. - * @returns {array} Array of objects containing the Merkle tree hash, and its relative position (left or right). - */ -const buildAuditPath = (hash, tree) => { - if (0 === tree.count) - throw new InvalidTree(); - - let layerStart = 0; - let currentLayerCount = tree.count; - let layerSubindexOfHash = indexOfLeafWithHash(hash, tree); - if (-1 === layerSubindexOfHash) - throw new HashNotFoundError(); - - const auditPath = []; - while (1 !== currentLayerCount) { - currentLayerCount = evenify(currentLayerCount); - const sibling = siblingOf(layerStart + layerSubindexOfHash); - const siblingPathNode = { - hash: tree.nodes[sibling.index], - position: sibling.position - }; - auditPath.push(siblingPathNode); - layerStart += currentLayerCount; - currentLayerCount /= 2; - layerSubindexOfHash = Math.floor(layerSubindexOfHash / 2); - } - return auditPath; -}; - -module.exports = { - buildAuditPath, - evenify, - indexOfLeafWithHash, - siblingOf, - NodePosition, - HashNotFoundError, - InvalidTree -}; diff --git a/catapult-sdk/src/crypto/sha3Hasher.js b/catapult-sdk/src/crypto/sha3Hasher.js deleted file mode 100644 index b7e9642ad..000000000 --- a/catapult-sdk/src/crypto/sha3Hasher.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module crypto/sha3Hasher */ -const arrayUtils = require('../utils/arrayUtils'); -const convert = require('../utils/convert'); -const jsSha3 = require('js-sha3'); - -const hashFunction256 = jsSha3.sha3_256; -const hashFunction512 = jsSha3.sha3_512; - -const getHasher = (length = 64) => ({ 32: hashFunction256, 64: hashFunction512 }[length]); - -const sha3Hasher = { - /** - * Calculates the hash of data. - * @param {Uint8Array} dest Computed hash destination. - * @param {Uint8Array} data Data to hash. - * @param {numeric} length Hash length in bytes. - */ - func: (dest, data, length) => { - const hasher = getHasher(length); - const hash = hasher.arrayBuffer(data); - arrayUtils.copy(dest, arrayUtils.uint8View(hash)); - }, - - /** - * Returns the currently used hasher library for this build. - * @param {numeric} length Hash length in bytes. - * @returns {object} Hasher. - */ - getHasher, - - /** - * Creates a hasher object. - * @param {numeric} length Hash length in bytes. - * @returns {object} Hasher. - */ - createHasher: length => { - let hash; - return { - reset: () => { - hash = getHasher(length).create(); - }, - update: data => { - if (data instanceof Uint8Array) - hash.update(data); - else if ('string' === typeof data) - hash.update(convert.hexToUint8(data)); - else - throw Error('unsupported data type'); - }, - finalize: result => { - arrayUtils.copy(result, arrayUtils.uint8View(hash.arrayBuffer())); - } - }; - } -}; - -module.exports = sha3Hasher; diff --git a/catapult-sdk/src/index.js b/catapult-sdk/src/index.js deleted file mode 100644 index 26ad9dd35..000000000 --- a/catapult-sdk/src/index.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { createKeyPairFromPrivateKeyString, sign, verify } = require('./crypto/keyPair'); -const merkle = require('./crypto/merkleAuditProof'); -const sha3Hasher = require('./crypto/sha3Hasher'); -const EntityType = require('./model/EntityType'); -const ModelType = require('./model/ModelType'); -const address = require('./model/address'); -const idReducer = require('./model/idReducer'); -const namespace = require('./model/namespace'); -const networkInfo = require('./model/networkInfo'); -const restriction = require('./model/restriction'); -const status = require('./model/status'); -const serialize = require('./modelBinary/serialize'); -const sizes = require('./modelBinary/sizes'); -const transactionExtensions = require('./modelBinary/transactionExtensions'); -const { PacketType, StatePathPacketTypes } = require('./packet/PacketType'); -const packetHeader = require('./packet/header'); -const BinaryParser = require('./parser/BinaryParser'); -const PacketParser = require('./parser/PacketParser'); -const catapultModelSystem = require('./plugins/catapultModelSystem'); -const BinarySerializer = require('./serializer/BinarySerializer'); -const SerializedSizeCalculator = require('./serializer/SerializedSizeCalculator'); -const SchemaType = require('./utils/SchemaType'); -const arrayUtils = require('./utils/arrayUtils'); -const base32 = require('./utils/base32'); -const convert = require('./utils/convert'); -const formattingUtils = require('./utils/formattingUtils'); -const future = require('./utils/future'); -const objects = require('./utils/objects'); -const schemaFormatter = require('./utils/schemaFormatter'); -const uint64 = require('./utils/uint64'); - -const catapultSdk = { - constants: { - sizes - }, - crypto: { - createKeyPairFromPrivateKeyString, - merkle, - sha3Hasher, - sign, - verify - }, - model: { - address, - EntityType, - idReducer, - ModelType, - restriction, - namespace, - networkInfo, - status - }, - modelBinary: { - serialize, - transactionExtensions - }, - packet: { - header: packetHeader, - PacketType, - StatePathPacketTypes - }, - parser: { - BinaryParser, - PacketParser - }, - plugins: { - catapultModelSystem - }, - serializer: { - BinarySerializer, - SerializedSizeCalculator - }, - utils: { - array: arrayUtils, - base32, - convert, - formattingUtils, - future, - objects, - schemaFormatter, - SchemaType, - uint64 - } -}; - -module.exports = catapultSdk; diff --git a/catapult-sdk/src/model/EntityType.js b/catapult-sdk/src/model/EntityType.js deleted file mode 100644 index 4b4d9d0c7..000000000 --- a/catapult-sdk/src/model/EntityType.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** - * Catapult model entity types. - * @enum {numeric} - * @exports model/EntityType - */ -const EntityType = { - /** Transfer transaction. */ - transfer: 0x4154, - - /** Register namespace transaction. */ - registerNamespace: 0x414E, - - /** Alias address transaction. */ - aliasAddress: 0x424E, - - /** Alias mosaic transaction. */ - aliasMosaic: 0x434E, - - /** Mosaic definition transaction. */ - mosaicDefinition: 0x414D, - - /** Mosaic supply change transaction. */ - mosaicSupplyChange: 0x424D, - - /** Mosaic supply revocation transaction. */ - mosaicSupplyRevocation: 0x434d, - - /** Modify multisig account transaction. */ - modifyMultisigAccount: 0x4155, - - /** Aggregate complete transaction. */ - aggregateComplete: 0x4141, - - /** Aggregate bonded transaction. */ - aggregateBonded: 0x4241, - - /** Hash lock transaction. */ - hashLock: 0x4148, - - /** Secret lock transaction. */ - secretLock: 0x4152, - - /** Secret proof transaction. */ - secretProof: 0x4252, - - /** Account address restriction modification transaction. */ - accountRestrictionAddress: 0x4150, - - /** Account mosaic restriction modification transaction. */ - accountRestrictionMosaic: 0x4250, - - /** Account operation restriction modification transaction. */ - accountRestrictionOperation: 0x4350, - - /** Mosaic address restriction modification transaction. */ - mosaicRestrictionAddress: 0x4251, - - /** Mosaic global restriction modification transaction. */ - mosaicRestrictionGlobal: 0x4151, - - /** Account link transaction. */ - accountLink: 0x414C, - - /** Node key link transaction. */ - nodeKeyLink: 0x424C, - - /** Voting key link transaction. */ - votingKeyLink: 0x4143, - - /** VRF key link transaction. */ - vrfKeyLink: 0x4243, - - /** Account metadata transaction */ - accountMetadata: 0x4144, - - /** Mosaic metadata transaction */ - mosaicMetadata: 0x4244, - - /** Namespace metadata transaction */ - namespaceMetadata: 0x4344 -}; - -module.exports = EntityType; diff --git a/catapult-sdk/src/model/ModelFormatterBuilder.js b/catapult-sdk/src/model/ModelFormatterBuilder.js deleted file mode 100644 index a4073773e..000000000 --- a/catapult-sdk/src/model/ModelFormatterBuilder.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module model/ModelFormatterBuilder */ -const schemaFormatter = require('../utils/schemaFormatter'); - -const createFormatter = (type, modelSchema, formattingRules) => ({ - format: entity => schemaFormatter.format(entity, modelSchema[type], modelSchema, formattingRules) -}); - -/** - * Builder for creating a model formatter. - */ -class ModelFormatterBuilder { - /** - * Creates a model formatter builder. - */ - constructor() { - this.subFormatterTypes = new Set([ - 'accountWithMetadata', - 'blockHeaderWithMetadata', - 'transactionWithMetadata', - - 'chainInfo', - 'merkleProofInfo', - 'finalizedBlock', - 'finalizationProof', - 'nodeHealth', - 'nodeInfo', - 'nodeTime', - 'serverInfo', - 'stateTree', - 'storageInfo', - 'transactionStatus' - ]); - } - - /** - * Adds support for a named formatter. - * @param {string} type Formatter type. - */ - addFormatter(type) { - if (this.subFormatterTypes.has(type)) - throw Error(`formatter already registered for '${type}'`); - - this.subFormatterTypes.add(type); - } - - /** - * Returns an appropriate aggregate formatter object. - * @param {object} modelSchema Model schema. - * @param {object} formattingRules A map for looking up formatting rules given a schema property type. - * @returns {object} Aggregate formatter object. - */ - build(modelSchema, formattingRules) { - const formatter = {}; - this.subFormatterTypes.forEach(type => { - formatter[type] = createFormatter(type, modelSchema, formattingRules); - }); - - return formatter; - } -} - -module.exports = ModelFormatterBuilder; diff --git a/catapult-sdk/src/model/ModelSchemaBuilder.js b/catapult-sdk/src/model/ModelSchemaBuilder.js deleted file mode 100644 index a335c0757..000000000 --- a/catapult-sdk/src/model/ModelSchemaBuilder.js +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module model/ModelSchemaBuilder */ -const EntityType = require('./EntityType'); -const ModelType = require('./ModelType'); - -/** - * Builder for creating a model schema. - */ -class ModelSchemaBuilder { - /** - * Creates a model schema builder. - */ - constructor() { - this.schema = { - // region verifiable entity - - verifiableEntity: { - signature: ModelType.binary, - signerPublicKey: ModelType.binary - }, - - // endregion - - // region block - blockHeader: { - size: ModelType.int, - version: ModelType.uint8, - network: ModelType.uint8, - type: ModelType.int, - height: ModelType.uint64, - timestamp: ModelType.uint64, - difficulty: ModelType.uint64, - proofGamma: ModelType.binary, - proofVerificationHash: ModelType.binary, - proofScalar: ModelType.binary, - previousBlockHash: ModelType.binary, - transactionsHash: ModelType.binary, - receiptsHash: ModelType.binary, - stateHash: ModelType.binary, - beneficiaryAddress: ModelType.encodedAddress, - feeMultiplier: ModelType.uint32, - // optional. How to create subclasses? - votingEligibleAccountsCount: ModelType.uint32, - harvestingEligibleAccountsCount: ModelType.uint64, - totalVotingBalance: ModelType.uint64, - previousImportanceBlockHash: ModelType.binary - }, - blockHeaderMetadata: { - hash: ModelType.binary, - generationHash: ModelType.binary, - totalFee: ModelType.uint64, - stateHashSubCacheMerkleRoots: { type: ModelType.array, schemaName: ModelType.binary }, - totalTransactionsCount: ModelType.int, - transactionsCount: ModelType.int, - statementsCount: ModelType.int - }, - blockHeaderWithMetadata: { - id: ModelType.objectId, - meta: { type: ModelType.object, schemaName: 'blockHeaderMetadata' }, - block: { type: ModelType.object, schemaName: 'blockHeader' } - }, - merkleProofInfo: { - merklePath: { type: ModelType.array, schemaName: 'merkleProofInfoPathNode' } - }, - merkleProofInfoPathNode: { - hash: ModelType.binary, - position: ModelType.string - }, - - finalizedBlock: { - height: ModelType.uint64, - hash: ModelType.binary, - finalizationEpoch: ModelType.uint32, - finalizationPoint: ModelType.uint32 - }, - - finalizationProof: { - version: ModelType.uint32, - finalizationEpoch: ModelType.uint32, - finalizationPoint: ModelType.uint32, - height: ModelType.uint64, - hash: ModelType.binary, - messageGroups: { type: ModelType.array, schemaName: 'messageGroup' } - }, - messageGroup: { - stage: ModelType.uint32, - height: ModelType.uint64, - hashes: { type: ModelType.array, schemaName: ModelType.binary }, - signatures: { type: ModelType.array, schemaName: 'bmTreeSignature' } - }, - bmTreeSignature: { - root: { type: ModelType.object, schemaName: 'parentPublicKeySignaturePair' }, - bottom: { type: ModelType.object, schemaName: 'parentPublicKeySignaturePair' } - }, - parentPublicKeySignaturePair: { - parentPublicKey: ModelType.binary, - signature: ModelType.binary - }, - - // endregion - - // region transaction - - transaction: { - size: ModelType.int, - version: ModelType.uint8, - network: ModelType.uint8, - type: ModelType.int, - deadline: ModelType.uint64, - maxFee: ModelType.uint64 - }, - transactionMetadata: { - aggregateHash: ModelType.binary, - aggregateId: ModelType.objectId, - height: ModelType.uint64, - hash: ModelType.binary, - merkleComponentHash: ModelType.binary, - index: ModelType.int, - timestamp: ModelType.uint64, - feeMultiplier: ModelType.uint32 - }, - transactionWithMetadata: { - id: ModelType.objectId, - meta: { type: ModelType.object, schemaName: 'transactionMetadata' }, - transaction: { - type: ModelType.object, - // notice that this needs to be set in build to allow graceful fallback when some txes are not registered - schemaName: undefined - } - }, - - // endregion - - // region transactionStatus - - transactionStatus: { - group: ModelType.string, - hash: ModelType.binary, - code: ModelType.statusCode, - deadline: ModelType.uint64, - height: ModelType.uint64 - }, - - // endregion - - // region account - - accountWithMetadata: { - id: ModelType.objectId, - account: { type: ModelType.object, schemaName: 'account' } - }, - account: { - version: ModelType.uint16, - address: ModelType.encodedAddress, - addressHeight: ModelType.uint64, - publicKey: ModelType.binary, - publicKeyHeight: ModelType.uint64, - accountType: ModelType.uint8, - supplementalPublicKeys: { type: ModelType.object, schemaName: 'supplementalPublicKey' }, - importance: ModelType.uint64, - importanceHeight: ModelType.uint64, - activityBuckets: { type: ModelType.array, schemaName: 'activityBucket' }, - mosaics: { type: ModelType.array, schemaName: 'mosaic' } - }, - supplementalPublicKey: { - linked: { type: ModelType.object, schemaName: 'accountLinkPublicKey' }, - node: { type: ModelType.object, schemaName: 'accountLinkPublicKey' }, - vrf: { type: ModelType.object, schemaName: 'accountLinkPublicKey' }, - voting: { type: ModelType.object, schemaName: 'accountLinkPublicKey.voting' } - }, - activityBucket: { - startHeight: ModelType.uint64, - totalFeesPaid: ModelType.uint64, - beneficiaryCount: ModelType.uint32, - rawScore: ModelType.uint64 - }, - mosaic: { - id: ModelType.uint64HexIdentifier, - amount: ModelType.uint64 - }, - accountLinkPublicKey: { - publicKey: ModelType.binary - }, - 'accountLinkPublicKey.voting': { - publicKeys: { type: ModelType.array, schemaName: 'votingPublicKey' } - }, - votingPublicKey: { - publicKey: ModelType.binary, - startEpoch: ModelType.uint32, - endEpoch: ModelType.uint32 - }, - - // endregion - - // region other - - chainInfo: { - height: ModelType.uint64, - scoreLow: ModelType.uint64, - scoreHigh: ModelType.uint64, - latestFinalizedBlock: { type: ModelType.object, schemaName: 'finalizedBlock' } - }, - nodeHealth: { - status: { type: ModelType.object, schemaName: 'nodeHealthStatus' } - }, - nodeHealthStatus: { - apiNode: ModelType.string, - db: ModelType.string - }, - nodeInfo: { - version: ModelType.uint8, - roles: ModelType.int, - port: ModelType.int, - networkIdentifier: ModelType.int, - friendlyName: ModelType.string, - host: ModelType.string, - publicKey: ModelType.binary, - networkGenerationHashSeed: ModelType.binary, - nodePublicKey: ModelType.binary - }, - communicationTimestamps: { - receiveTimestamp: ModelType.uint64, - sendTimestamp: ModelType.uint64 - }, - nodeTime: { - communicationTimestamps: { type: ModelType.object, schemaName: 'communicationTimestamps' } - }, - serverInfo: { - serverInfo: { type: ModelType.object, schemaName: 'serverInfoData' } - }, - serverInfoData: { - restVersion: ModelType.string, - sdkVersion: ModelType.string, - deployment: { type: ModelType.object, schemaName: 'deploymentData' } - }, - deploymentData: { - deploymentTool: ModelType.string, - deploymentToolVersion: ModelType.string, - lastUpdatedDate: ModelType.string - }, - stateTree: { - tree: { type: ModelType.array, schemaName: ModelType.binary } - }, - storageInfo: { - numBlocks: ModelType.int, - numTransactions: ModelType.int, - numAccounts: ModelType.int - } - - // endregion - }; - - Object.assign(this.schema.blockHeader, this.schema.verifiableEntity); - Object.assign(this.schema.transaction, this.schema.verifiableEntity); - - this.setAllowedTransactions(EntityType); - } - - /** - * Sets transactions allowed by addTransactionSupport. - * @param {object} allowedTransactions Allowed transactions. - */ - setAllowedTransactions(allowedTransactions) { - // prepare reverse mapping id => string - this.entityTypeToString = Object.keys(allowedTransactions).reduce((state, name) => { - state[allowedTransactions[name]] = name; - return state; - }, {}); - } - - /** - * Returns name for allowed transaction. - * @param {module:model/EntityType} transactionType Transaction type. - * @returns {string} Transaction name corresponding to type. - */ - typeToName(transactionType) { - if (!(transactionType in this.entityTypeToString)) - throw Error(`transactionType is not in the list of allowed transactions '${transactionType}'`); - - return this.entityTypeToString[transactionType]; - } - - /** - * Adds support for a transaction type. - * @param {module:model/EntityType} transactionType Transaction type. - * @param {object} schema Transaction schema. - */ - addTransactionSupport(transactionType, schema) { - const name = this.typeToName(transactionType); - this.addSchema(name, schema); - Object.assign(this.schema[name], this.schema.transaction); - } - - /** - * Adds support for a named schema. - * @param {string} name Schema name. - * @param {object} schema Schema. - */ - addSchema(name, schema) { - if (this.schema[name]) - throw Error(`schema already registered for '${name}'`); - - this.schema[name] = schema; - } - - /** - * Returns a function that returns the best known schema for a given transaction. - * @returns {function} Transaction schema lookup function. - */ - transactionSchemaNameSupplier() { - // default to transaction - return transaction => { - const transactionName = this.entityTypeToString[transaction.type]; - return transactionName && this.schema[transactionName] ? transactionName : 'transaction'; - }; - } - - /** - * Builds the schema and returns an appropriate aggregate schema object. - * @returns {object} Aggregate schema object. - */ - build() { - this.schema.transactionWithMetadata.transaction.schemaName = this.transactionSchemaNameSupplier(); - return this.schema; - } -} - -module.exports = ModelSchemaBuilder; diff --git a/catapult-sdk/src/model/ModelType.js b/catapult-sdk/src/model/ModelType.js deleted file mode 100644 index 38e3ddc40..000000000 --- a/catapult-sdk/src/model/ModelType.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const SchemaType = require('../utils/SchemaType'); - -/** - * Catapult model extended schema property types. - * @enum {numeric} - * @extends module:utils/SchemaType - * @exports model/ModelType - */ -const ModelType = { - /** Schema property type indicating a binary value. */ - binary: SchemaType.max + 1, - - /** Schema property type indicating an object identifier. */ - objectId: SchemaType.max + 2, - - /** Schema property type indicating a status code. */ - statusCode: SchemaType.max + 3, - - /** Schema property type indicating a string value. */ - string: SchemaType.max + 4, - - /** Schema property type indicating an uint byte value. */ - uint8: SchemaType.max + 5, - - /** Schema property type indicating an uint16 value. */ - uint16: SchemaType.max + 6, - - /** Schema property type indicating an uint32 value. */ - uint32: SchemaType.max + 7, - - /** Schema property type indicating a uint64 value as string. */ - uint64: SchemaType.max + 8, - - /** Schema property type indicating a uint64 identifier as hexadecimal. */ - uint64HexIdentifier: SchemaType.max + 9, - - /** Schema property type indicating an int value. */ - int: SchemaType.max + 10, - - /** Schema property type indicating a boolean value. */ - boolean: SchemaType.max + 11, - - /** Schema property type indicating a binary value as base32Address. */ - encodedAddress: SchemaType.max + 12 -}; - -Object.assign(ModelType, SchemaType); -ModelType.max = ModelType.encodedAddress; - -module.exports = ModelType; diff --git a/catapult-sdk/src/model/address.js b/catapult-sdk/src/model/address.js deleted file mode 100644 index f5e4e495f..000000000 --- a/catapult-sdk/src/model/address.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const arrayUtils = require('../utils/arrayUtils'); -const base32 = require('../utils/base32'); -const convert = require('../utils/convert'); -const jsSha3 = require('js-sha3'); -const Ripemd160 = require('ripemd160'); - -const constants = { - sizes: { - ripemd160: 20, - addressDecoded: 24, - addressEncoded: 39, - key: 32, - checksum: 3 - } -}; - -/** @exports model/address */ -const address = { - /** - * Converts an encoded address string to a decoded address. - * @param {string} encoded Encoded address string. - * @returns {Uint8Array} Decoded address corresponding to the input. - */ - - stringToAddress: encoded => { - if (constants.sizes.addressEncoded !== encoded.length) - throw Error(`${encoded} does not represent a valid encoded address`); - - // base32 module cannot manage arbitrary size conversion so some ugly temporary padding is required - return base32.decode(`${encoded}A`).subarray(0, constants.sizes.addressDecoded); - }, - - /** - * Converts a decoded address to an encoded address string. - * @param {Uint8Array} decoded Decoded address. - * @returns {string} Encoded address string corresponding to the input. - */ - addressToString: decoded => { - if (constants.sizes.addressDecoded !== decoded.length) - throw Error(`${convert.uint8ToHex(decoded)} does not represent a valid decoded address`); - - // base32 module cannot manage arbitrary size conversion so some ugly temporary padding is required - const paddedDecodedAddress = new Uint8Array(constants.sizes.addressDecoded + 1); - paddedDecodedAddress.set(decoded); - return base32.encode(paddedDecodedAddress).slice(0, -1); - }, - - /** - * Converts a public key to a decoded address for a specific network. - * @param {module:crypto/keyPair~PublicKey} publicKey Public key. - * @param {numeric} networkIdentifier Network identifier. - * @returns {Uint8Array} Decoded address corresponding to the inputs. - */ - publicKeyToAddress: (publicKey, networkIdentifier) => { - // step 1: sha3 hash of the public key - const publicKeyHash = jsSha3.sha3_256.arrayBuffer(publicKey); - - // step 2: ripemd160 hash of (1) - const ripemdHash = new Ripemd160().update(Buffer.from(publicKeyHash)).digest(); - - // step 3: add network identifier byte in front of (2) - const decodedAddress = new Uint8Array(constants.sizes.addressDecoded); - decodedAddress[0] = networkIdentifier; - arrayUtils.copy(decodedAddress, ripemdHash, constants.sizes.ripemd160, 1); - - // step 4: concatenate (3) and the checksum of (3) - const hash = jsSha3.sha3_256.arrayBuffer(decodedAddress.subarray(0, constants.sizes.ripemd160 + 1)); - arrayUtils.copy(decodedAddress, arrayUtils.uint8View(hash), constants.sizes.checksum, constants.sizes.ripemd160 + 1); - - return decodedAddress; - }, - - /** - * Determines the validity of a decoded address. - * @param {Uint8Array} decoded Decoded address. - * @returns {boolean} true if the decoded address is valid, false otherwise. - */ - isValidAddress: decoded => { - const hash = jsSha3.sha3_256.create(); - const checksumBegin = constants.sizes.addressDecoded - constants.sizes.checksum; - hash.update(decoded.subarray(0, checksumBegin)); - const checksum = new Uint8Array(constants.sizes.checksum); - arrayUtils.copy(checksum, arrayUtils.uint8View(hash.arrayBuffer()), constants.sizes.checksum); - return arrayUtils.deepEqual(checksum, decoded.subarray(checksumBegin)); - }, - - /** - * Determines the validity of an encoded address string. - * @param {string} encoded Encoded address string. - * @returns {boolean} true if the encoded address string is valid, false otherwise. - */ - isValidEncodedAddress: encoded => { - if (constants.sizes.addressEncoded !== encoded.length) - return false; - - try { - const decoded = address.stringToAddress(encoded); - const paddedDecoded = base32.decode(`${encoded}A`); - - // when decoding an address we will always get a valid address, however, when encoding an address the result may not always be - // correct, thus a two-way check is required to see that the original address was valid (padded with 0) - return address.isValidAddress(decoded) && 0 === paddedDecoded[constants.sizes.addressDecoded]; - } catch (err) { - return false; - } - } -}; - -module.exports = address; diff --git a/catapult-sdk/src/model/idReducer.js b/catapult-sdk/src/model/idReducer.js deleted file mode 100644 index f3ea9e4c6..000000000 --- a/catapult-sdk/src/model/idReducer.js +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module model/idReducer */ -const uint64 = require('../utils/uint64'); - -const idReducer = { - /** - * Creates an id to name lookup object around namespace name tuples. - * @param {array} nameTuples Namespace name tuples. - * @returns {object} An id to name lookup object. - */ - createIdToNameLookup: nameTuples => { - let nextRoundKeys = []; - - // copy all tuples into an id -> value dictionary - const lookupMap = {}; - nameTuples.forEach(nameTuple => { - const key = uint64.toHex(nameTuple.namespaceId); - - // give preference to first of conflicts - if (!lookupMap[key]) { - lookupMap[key] = Object.assign({ fqn: nameTuple.name }, nameTuple); - if (!uint64.isZero(nameTuple.parentId)) { - lookupMap[key].nextId = nameTuple.parentId; - nextRoundKeys.push(key); - } - } - }); - - // each round processes the tuples from the previous round that have a nonzero parent - const processRoundKeys = roundKeys => { - const additionalProcessingKeys = []; - roundKeys.forEach(key => { - const nameTuple = lookupMap[key]; - const parentEntry = lookupMap[uint64.toHex(nameTuple.nextId)]; - nameTuple.fqn = parentEntry ? `${parentEntry.name}.${nameTuple.fqn}` : undefined; - - if (!parentEntry || uint64.isZero(parentEntry.parentId)) { - delete nameTuple.nextId; - } else { - // if the nextId is nonzero, additional processing is required - nameTuple.nextId = parentEntry.parentId; - additionalProcessingKeys.push(key); - } - }); - - return additionalProcessingKeys; - }; - - while (0 !== nextRoundKeys.length) { - const currentRoundKeys = nextRoundKeys.slice(); - nextRoundKeys = processRoundKeys(currentRoundKeys); - } - - return { - /** - * Number of id to name mappings known by this object. - * @property {numeric} - */ - length: nameTuples.length, - - /** - * Returns the name for an id or undefined if no mapping exists - * @param {module:utils/uint64~uint64} id A uint64 value representing a namespace id. - * @returns {string} Fully qualified namespace name corresponding to the id. - */ - findName: id => (lookupMap[uint64.toHex(id)] || {}).fqn - }; - } -}; - -module.exports = idReducer; diff --git a/catapult-sdk/src/model/namespace.js b/catapult-sdk/src/model/namespace.js deleted file mode 100644 index 2fada0b70..000000000 --- a/catapult-sdk/src/model/namespace.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const convert = require('../utils/convert'); -/** - * Catapult model namespace. - * @enum {numeric} - * @exports model/namespace - */ -const namespace = { - /** Namespace alias type. */ - aliasType: { - /** Mosaic alias. */ - mosaic: 1, - - /** Address alias. */ - address: 2 - }, - /** - * Format a namespaceId *alias* into a valid recipient field value. - * @param {Uint8Array} namespaceId The namespaceId - * @param {number} networkIdentifier network identifier serialized in the output. - * @returns {Uint8Array} The padded notation of the alias - */ - encodeNamespace(namespaceId, networkIdentifier) { - // 0x91 | namespaceId on 8 bytes | 15 bytes 0-pad = 24 bytes - const padded = new Uint8Array(1 + 8 + 15); - padded.set([networkIdentifier | 0x01], 0); - padded.set(namespaceId.reverse(), 1); - padded.set(convert.hexToUint8('00'.repeat(15)), 9); - return padded; - } -}; - -module.exports = namespace; diff --git a/catapult-sdk/src/model/networkInfo.js b/catapult-sdk/src/model/networkInfo.js deleted file mode 100644 index 38f7f71e3..000000000 --- a/catapult-sdk/src/model/networkInfo.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module model/networkInfo */ -const base32 = require('../utils/base32'); -const convert = require('../utils/convert'); - -/** - * Information about a catapult network. - * @typedef {object} NetworkInfo - * @property {numeric} id Network id. - * @property {numeric} bytePrefix First byte of a compatible network (decoded) address. - * @property {string} charPrefix First character of a compatible network (encoded) address. - */ - -const networks = (() => { - const createNetworkInfo = id => ({ - id, bytePrefix: convert.uint8ToHex([id]), charPrefix: base32.encode(Uint8Array.of(id, 0, 0, 0, 0))[0] - }); - - /** - * Information about well known catapult networks. - * @typedef {object} WellKnownNetworks - * @property {NetworkInfo} mainnet Public network information. - * @property {NetworkInfo} testnet Public test network information. - */ - return { - mainnet: createNetworkInfo(0x68), - testnet: createNetworkInfo(0x98) - }; -})(); - -const findNetwork = (key, value) => { - const matchNetworkName = Object.keys(networks).find(name => value === networks[name][key]); - return undefined === matchNetworkName ? undefined : networks[matchNetworkName]; -}; - -const networkInfo = { - /** @property {module:model/networkInfo~WellKnownNetworks} networks Information about well known networks. */ - networks, - - /** - * Finds network information given a network id. - * @param {numeric} id Network id. - * @returns {module:model/networkInfo~NetworkInfo} Network with the specified id or undefined if unknown. - */ - findById: id => findNetwork('id', id), - - /** - * Finds network information given a network address character prefix. - * @param {string} charPrefix Address character prefix. - * @returns {module:model/networkInfo~NetworkInfo} Network with the specified address character prefix - * or undefined if unknown. - */ - findByCharPrefix: charPrefix => findNetwork('charPrefix', charPrefix) -}; - -module.exports = networkInfo; diff --git a/catapult-sdk/src/model/restriction.js b/catapult-sdk/src/model/restriction.js deleted file mode 100644 index 620e156ab..000000000 --- a/catapult-sdk/src/model/restriction.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** - * Catapult model restriction. - * @enum {numeric} - * @exports model/restriction - */ -const restriction = { - mosaicRestriction: { - /** Mosaic restriction type. */ - restrictionType: { - /** Address restriction. */ - address: 0, - - /** Global restriction. */ - global: 1 - } - } -}; - -module.exports = restriction; diff --git a/catapult-sdk/src/model/status.js b/catapult-sdk/src/model/status.js deleted file mode 100644 index 4fdc0ae66..000000000 --- a/catapult-sdk/src/model/status.js +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module model/status */ - -/* istanbul ignore next */ -const toStringInternal = code => { - switch (code) { - case 0x00000000: return 'Success'; - case 0x40000000: return 'Neutral'; - case 0x80000000: return 'Failure'; - case 0x80430001: return 'Failure_Core_Past_Deadline'; - case 0x80430002: return 'Failure_Core_Future_Deadline'; - case 0x80430003: return 'Failure_Core_Insufficient_Balance'; - case 0x80430004: return 'Failure_Core_Too_Many_Transactions'; - case 0x80430005: return 'Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block'; - case 0x80430006: return 'Failure_Core_Wrong_Network'; - case 0x80430007: return 'Failure_Core_Invalid_Address'; - case 0x80430008: return 'Failure_Core_Invalid_Version'; - case 0x80430009: return 'Failure_Core_Invalid_Transaction_Fee'; - case 0x8043000A: return 'Failure_Core_Block_Harvester_Ineligible'; - case 0x8043000B: return 'Failure_Core_Zero_Address'; - case 0x8043000C: return 'Failure_Core_Zero_Public_Key'; - case 0x8043000D: return 'Failure_Core_Nonzero_Internal_Padding'; - case 0x8043000E: return 'Failure_Core_Address_Collision'; - case 0x8043000F: return 'Failure_Core_Importance_Block_Mismatch'; - case 0x80430010: return 'Failure_Core_Unexpected_Block_Type'; - case 0x80430011: return 'Failure_Core_Block_Explicit_Transactions_Hash_Mismatch'; - case 0x80430065: return 'Failure_Core_Invalid_Link_Action'; - case 0x80430066: return 'Failure_Core_Link_Already_Exists'; - case 0x80430067: return 'Failure_Core_Inconsistent_Unlink_Data'; - case 0x80430068: return 'Failure_Core_Invalid_Link_Range'; - case 0x80430069: return 'Failure_Core_Too_Many_Links'; - case 0x8043006A: return 'Failure_Core_Link_Start_Epoch_Invalid'; - case 0x81490001: return 'Failure_Hash_Already_Exists'; - case 0x80530001: return 'Failure_Signature_Not_Verifiable'; - case 0x804C0001: return 'Failure_AccountLink_Link_Already_Exists'; - case 0x804C0002: return 'Failure_AccountLink_Inconsistent_Unlink_Data'; - case 0x804C0003: return 'Failure_AccountLink_Unknown_Link'; - case 0x804C0004: return 'Failure_AccountLink_Remote_Account_Ineligible'; - case 0x804C0005: return 'Failure_AccountLink_Remote_Account_Signer_Prohibited'; - case 0x804C0006: return 'Failure_AccountLink_Remote_Account_Participant_Prohibited'; - case 0x80410001: return 'Failure_Aggregate_Too_Many_Transactions'; - case 0x80410002: return 'Failure_Aggregate_No_Transactions'; - case 0x80410003: return 'Failure_Aggregate_Too_Many_Cosignatures'; - case 0x80410004: return 'Failure_Aggregate_Redundant_Cosignatures'; - case 0x80410005: return 'Failure_Aggregate_Ineligible_Cosignatories'; - case 0x80410006: return 'Failure_Aggregate_Missing_Cosignatures'; - case 0x80410007: return 'Failure_Aggregate_Transactions_Hash_Mismatch'; - case 0x80480001: return 'Failure_LockHash_Invalid_Mosaic_Id'; - case 0x80480002: return 'Failure_LockHash_Invalid_Mosaic_Amount'; - case 0x80480003: return 'Failure_LockHash_Hash_Already_Exists'; - case 0x80480004: return 'Failure_LockHash_Unknown_Hash'; - case 0x80480005: return 'Failure_LockHash_Inactive_Hash'; - case 0x80480006: return 'Failure_LockHash_Invalid_Duration'; - case 0x80520001: return 'Failure_LockSecret_Invalid_Hash_Algorithm'; - case 0x80520002: return 'Failure_LockSecret_Hash_Already_Exists'; - case 0x80520003: return 'Failure_LockSecret_Proof_Size_Out_Of_Bounds'; - case 0x80520004: return 'Failure_LockSecret_Secret_Mismatch'; - case 0x80520005: return 'Failure_LockSecret_Unknown_Composite_Key'; - case 0x80520006: return 'Failure_LockSecret_Inactive_Secret'; - case 0x80520007: return 'Failure_LockSecret_Hash_Algorithm_Mismatch'; - case 0x80520008: return 'Failure_LockSecret_Invalid_Duration'; - case 0x80440001: return 'Failure_Metadata_Value_Too_Small'; - case 0x80440002: return 'Failure_Metadata_Value_Too_Large'; - case 0x80440003: return 'Failure_Metadata_Value_Size_Delta_Too_Large'; - case 0x80440004: return 'Failure_Metadata_Value_Size_Delta_Mismatch'; - case 0x80440005: return 'Failure_Metadata_Value_Change_Irreversible'; - case 0x804D0001: return 'Failure_Mosaic_Invalid_Duration'; - case 0x804D0002: return 'Failure_Mosaic_Invalid_Name'; - case 0x804D0003: return 'Failure_Mosaic_Name_Id_Mismatch'; - case 0x804D0004: return 'Failure_Mosaic_Expired'; - case 0x804D0005: return 'Failure_Mosaic_Owner_Conflict'; - case 0x804D0006: return 'Failure_Mosaic_Id_Mismatch'; - case 0x804D0064: return 'Failure_Mosaic_Parent_Id_Conflict'; - case 0x804D0065: return 'Failure_Mosaic_Invalid_Property'; - case 0x804D0066: return 'Failure_Mosaic_Invalid_Flags'; - case 0x804D0067: return 'Failure_Mosaic_Invalid_Divisibility'; - case 0x804D0068: return 'Failure_Mosaic_Invalid_Supply_Change_Action'; - case 0x804D0069: return 'Failure_Mosaic_Invalid_Supply_Change_Amount'; - case 0x804D006A: return 'Failure_Mosaic_Invalid_Id'; - case 0x804D006B: return 'Failure_Mosaic_Modification_Disallowed'; - case 0x804D006C: return 'Failure_Mosaic_Modification_No_Changes'; - case 0x804D006D: return 'Failure_Mosaic_Supply_Immutable'; - case 0x804D006E: return 'Failure_Mosaic_Supply_Negative'; - case 0x804D006F: return 'Failure_Mosaic_Supply_Exceeded'; - case 0x804D0070: return 'Failure_Mosaic_Non_Transferable'; - case 0x804D0071: return 'Failure_Mosaic_Max_Mosaics_Exceeded'; - case 0x804D0072: return 'Failure_Mosaic_Required_Property_Flag_Unset'; - case 0x80550001: return 'Failure_Multisig_Account_In_Both_Sets'; - case 0x80550002: return 'Failure_Multisig_Multiple_Deletes'; - case 0x80550003: return 'Failure_Multisig_Redundant_Modification'; - case 0x80550004: return 'Failure_Multisig_Unknown_Multisig_Account'; - case 0x80550005: return 'Failure_Multisig_Not_A_Cosignatory'; - case 0x80550006: return 'Failure_Multisig_Already_A_Cosignatory'; - case 0x80550007: return 'Failure_Multisig_Min_Setting_Out_Of_Range'; - case 0x80550008: return 'Failure_Multisig_Min_Setting_Larger_Than_Num_Cosignatories'; - case 0x80550009: return 'Failure_Multisig_Invalid_Modification_Action'; - case 0x8055000A: return 'Failure_Multisig_Max_Cosigned_Accounts'; - case 0x8055000B: return 'Failure_Multisig_Max_Cosignatories'; - case 0x8055000C: return 'Failure_Multisig_Loop'; - case 0x8055000D: return 'Failure_Multisig_Max_Multisig_Depth'; - case 0x8055000E: return 'Failure_Multisig_Operation_Prohibited_By_Account'; - case 0x804E0001: return 'Failure_Namespace_Invalid_Duration'; - case 0x804E0002: return 'Failure_Namespace_Invalid_Name'; - case 0x804E0003: return 'Failure_Namespace_Name_Id_Mismatch'; - case 0x804E0004: return 'Failure_Namespace_Expired'; - case 0x804E0005: return 'Failure_Namespace_Owner_Conflict'; - case 0x804E0006: return 'Failure_Namespace_Id_Mismatch'; - case 0x804E0064: return 'Failure_Namespace_Invalid_Registration_Type'; - case 0x804E0065: return 'Failure_Namespace_Root_Name_Reserved'; - case 0x804E0066: return 'Failure_Namespace_Too_Deep'; - case 0x804E0067: return 'Failure_Namespace_Unknown_Parent'; - case 0x804E0068: return 'Failure_Namespace_Already_Exists'; - case 0x804E0069: return 'Failure_Namespace_Already_Active'; - case 0x804E006A: return 'Failure_Namespace_Eternal_After_Nemesis_Block'; - case 0x804E006B: return 'Failure_Namespace_Max_Children_Exceeded'; - case 0x804E006C: return 'Failure_Namespace_Alias_Invalid_Action'; - case 0x804E006D: return 'Failure_Namespace_Unknown'; - case 0x804E006E: return 'Failure_Namespace_Alias_Already_Exists'; - case 0x804E006F: return 'Failure_Namespace_Unknown_Alias'; - case 0x804E0070: return 'Failure_Namespace_Alias_Inconsistent_Unlink_Type'; - case 0x804E0071: return 'Failure_Namespace_Alias_Inconsistent_Unlink_Data'; - case 0x804E0072: return 'Failure_Namespace_Alias_Invalid_Address'; - case 0x80500001: return 'Failure_RestrictionAccount_Invalid_Restriction_Flags'; - case 0x80500002: return 'Failure_RestrictionAccount_Invalid_Modification_Action'; - case 0x80500003: return 'Failure_RestrictionAccount_Invalid_Modification_Address'; - case 0x80500004: return 'Failure_RestrictionAccount_Modification_Operation_Type_Incompatible'; - case 0x80500005: return 'Failure_RestrictionAccount_Redundant_Modification'; - case 0x80500006: return 'Failure_RestrictionAccount_Invalid_Modification'; - case 0x80500007: return 'Failure_RestrictionAccount_Modification_Count_Exceeded'; - case 0x80500008: return 'Failure_RestrictionAccount_No_Modifications'; - case 0x80500009: return 'Failure_RestrictionAccount_Values_Count_Exceeded'; - case 0x8050000A: return 'Failure_RestrictionAccount_Invalid_Value'; - case 0x8050000B: return 'Failure_RestrictionAccount_Address_Interaction_Prohibited'; - case 0x8050000C: return 'Failure_RestrictionAccount_Mosaic_Transfer_Prohibited'; - case 0x8050000D: return 'Failure_RestrictionAccount_Operation_Type_Prohibited'; - case 0x80510001: return 'Failure_RestrictionMosaic_Invalid_Restriction_Type'; - case 0x80510002: return 'Failure_RestrictionMosaic_Previous_Value_Mismatch'; - case 0x80510003: return 'Failure_RestrictionMosaic_Previous_Value_Must_Be_Zero'; - case 0x80510004: return 'Failure_RestrictionMosaic_Max_Restrictions_Exceeded'; - case 0x80510005: return 'Failure_RestrictionMosaic_Cannot_Delete_Nonexistent_Restriction'; - case 0x80510006: return 'Failure_RestrictionMosaic_Unknown_Global_Restriction'; - case 0x80510007: return 'Failure_RestrictionMosaic_Invalid_Global_Restriction'; - case 0x80510008: return 'Failure_RestrictionMosaic_Account_Unauthorized'; - case 0x80540001: return 'Failure_Transfer_Message_Too_Large'; - case 0x80540002: return 'Failure_Transfer_Out_Of_Order_Mosaics'; - case 0x80FF0001: return 'Failure_Chain_Unlinked'; - case 0x80FF0002: return 'Failure_Chain_Block_Not_Hit'; - case 0x80FF0003: return 'Failure_Chain_Block_Inconsistent_State_Hash'; - case 0x80FF0004: return 'Failure_Chain_Block_Inconsistent_Receipts_Hash'; - case 0x80FF0005: return 'Failure_Chain_Block_Invalid_Vrf_Proof'; - case 0x80FF0006: return 'Failure_Chain_Block_Unknown_Signer'; - case 0x80FF0007: return 'Failure_Chain_Unconfirmed_Cache_Too_Full'; - case 0x80FE0001: return 'Failure_Consumer_Empty_Input'; - case 0x80FE0002: return 'Failure_Consumer_Block_Transactions_Hash_Mismatch'; - case 0x41FE0003: return 'Neutral_Consumer_Hash_In_Recency_Cache'; - case 0x80FE0004: return 'Failure_Consumer_Remote_Chain_Improper_Link'; - case 0x80FE0005: return 'Failure_Consumer_Remote_Chain_Duplicate_Transactions'; - case 0x80FE0006: return 'Failure_Consumer_Remote_Chain_Unlinked'; - case 0x80FE0007: return 'Failure_Consumer_Remote_Chain_Difficulties_Mismatch'; - case 0x80FE0008: return 'Failure_Consumer_Remote_Chain_Score_Not_Better'; - case 0x80FE0009: return 'Failure_Consumer_Remote_Chain_Too_Far_Behind'; - case 0x80FE000A: return 'Failure_Consumer_Remote_Chain_Too_Far_In_Future'; - case 0x80FE000B: return 'Failure_Consumer_Batch_Signature_Not_Verifiable'; - case 0x80FE000C: return 'Failure_Consumer_Remote_Chain_Improper_Importance_Link'; - case 0x80450001: return 'Failure_Extension_Partial_Transaction_Cache_Prune'; - case 0x80450002: return 'Failure_Extension_Partial_Transaction_Dependency_Removed'; - case 0x80450003: return 'Failure_Extension_Read_Rate_Limit_Exceeded'; - default: return undefined; - } -}; - -const status = { - /** - * Converts a status code to a string. - * @param {numeric} code Status code. - * @returns {string} String representation of the status code. - */ - toString: code => { - const str = toStringInternal(code); - if (undefined !== str) - return str; - - let hexString = code.toString(16).toUpperCase(); - if (8 > hexString.length) - hexString = '0'.repeat(8 - hexString.length) + hexString; - - return `unknown status 0x${hexString}`; - } -}; - -module.exports = status; diff --git a/catapult-sdk/src/modelBinary/AggregateModelCodec.js b/catapult-sdk/src/modelBinary/AggregateModelCodec.js deleted file mode 100644 index 3f5e5b6dc..000000000 --- a/catapult-sdk/src/modelBinary/AggregateModelCodec.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/AggregateModelCodec */ - -// this file only contains an interface for prettier documentation, so ignore no-unused-vars warnings - -/* eslint-disable no-unused-vars */ - -/** - * Aggregate codec for serializing and deserializing a model supporting multiple entity types. - * @interface - * @extends {module:modelBinary/ModelCodec} - */ -const AggregateModelCodec = { - /** - * Determines whether or not an entity type is supported. - * @instance - * @param {module:model/EntityType} type Entity type. - * @returns {boolean} true if the type is supported. - */ - supports: type => false -}; - -/* eslint-enable */ -module.exports = AggregateModelCodec; diff --git a/catapult-sdk/src/modelBinary/ModelCodec.js b/catapult-sdk/src/modelBinary/ModelCodec.js deleted file mode 100644 index 31841736e..000000000 --- a/catapult-sdk/src/modelBinary/ModelCodec.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/ModelCodec */ - -// this file only contains an interface for prettier documentation, so ignore no-unused-vars warnings - -/* eslint-disable no-unused-vars */ - -/** - * Codec for serializing and deserializing a model. - * @interface - */ -const ModelCodec = { - /** - * Deserializes a model. - * @instance - * @param {object} parser Parser. - * @param {object} options Optional implementation-dependent deserialization options. - * @returns {object} Parsed model. - */ - deserialize: (parser, options) => undefined, - - /** - * Serializes a model. - * @instance - * @param {object} entity Model. - * @param {object} serializer Serializer. - */ - serialize: (entity, serializer) => {} -}; - -/* eslint-enable */ -module.exports = ModelCodec; diff --git a/catapult-sdk/src/modelBinary/ModelCodecBuilder.js b/catapult-sdk/src/modelBinary/ModelCodecBuilder.js deleted file mode 100644 index 6556785fc..000000000 --- a/catapult-sdk/src/modelBinary/ModelCodecBuilder.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/ModelCodecBuilder */ -const blockHeaderCodec = require('./blockHeaderCodec'); -const importanceBlockHeaderCodec = require('./importanceBlockHeaderCodec'); -const transactionCodec = require('./transactionCodec'); -const verifiableEntityCodec = require('./verifiableEntityCodec'); -const SerializedSizeCalculator = require('../serializer/SerializedSizeCalculator'); - -const isBlockType = entityType => 0 !== (0x8000 & entityType); - -const findCodecs = (entityType, codecs) => { - if (isBlockType(entityType) && (0x8043 === entityType || 0x8243 === entityType)) - return [verifiableEntityCodec, blockHeaderCodec, importanceBlockHeaderCodec]; - - if (isBlockType(entityType)) - return [verifiableEntityCodec, blockHeaderCodec]; - - const codec = codecs[entityType]; - if (!codec) - throw Error(`no codec registered for '${entityType}'`); - - return [verifiableEntityCodec, transactionCodec, codec]; -}; - -/** - * Builder for creating an aggregate model codec. - */ -class ModelCodecBuilder { - /** - * Creates a model codec builder. - */ - constructor() { - this.codecs = []; - } - - /** - * Adds support for a typed transaction. - * @param {module:model/EntityType} type Transaction type. - * @param {object} codec Transaction codec. - * @param {number} version the transaction version - */ - addTransactionSupport(type, codec) { - if (isBlockType(type) || this.codecs[type]) - throw Error(`codec already registered for '${type}'`); - - this.codecs[type] = codec; - } - - /** - * Builds and returns an appropriate aggregate model codec. - * @returns {module:modelBinary/AggregateModelCodec} Aggregate model codec. - */ - build() { - const txCodecs = this.codecs; - return { - supports(type) { - return isBlockType(type) || undefined !== txCodecs[type]; - }, - - deserialize: parser => { - // get codecs for the current entity (and ignore the verifiableEntity codec) - const size = parser.uint32(); - const entity = verifiableEntityCodec.deserialize(parser); - const codecs = findCodecs(entity.type, txCodecs, entity.version); - codecs.shift(); - - codecs.forEach(codec => { - Object.assign(entity, codec.deserialize(parser, size, txCodecs)); - }); - - return entity; - }, - - serialize: (entity, serializer) => { - const codecs = findCodecs(entity.type, txCodecs, entity.version); - - const sizeCalculator = new SerializedSizeCalculator(); - codecs.forEach(codec => { - codec.serialize(entity, sizeCalculator, txCodecs); - }); - - serializer.writeUint32(sizeCalculator.size() + 4); // include size of size field itself - codecs.forEach(codec => { - codec.serialize(entity, serializer, txCodecs); - }); - } - }; - } -} - -module.exports = ModelCodecBuilder; diff --git a/catapult-sdk/src/modelBinary/blockHeaderCodec.js b/catapult-sdk/src/modelBinary/blockHeaderCodec.js deleted file mode 100644 index 88848b924..000000000 --- a/catapult-sdk/src/modelBinary/blockHeaderCodec.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/blockHeaderCodec */ -const sizes = require('./sizes'); - -const constants = { sizes }; - -const blockHeaderCodec = { - /** - * Parses a block header. - * @param {object} parser Parser. - * @returns {object} Parsed block header. - */ - deserialize: parser => { - const blockHeader = {}; - blockHeader.height = parser.uint64(); - blockHeader.timestamp = parser.uint64(); - blockHeader.difficulty = parser.uint64(); - blockHeader.proofGamma = parser.buffer(constants.sizes.vrfProof.gamma); - blockHeader.proofVerificationHash = parser.buffer(constants.sizes.vrfProof.verificationHash); - blockHeader.proofScalar = parser.buffer(constants.sizes.vrfProof.scalar); - blockHeader.previousBlockHash = parser.buffer(constants.sizes.hash256); - blockHeader.transactionsHash = parser.buffer(constants.sizes.hash256); - blockHeader.receiptsHash = parser.buffer(constants.sizes.hash256); - blockHeader.stateHash = parser.buffer(constants.sizes.hash256); - blockHeader.beneficiaryAddress = parser.buffer(constants.sizes.addressDecoded); - blockHeader.feeMultiplier = parser.uint32(); - return blockHeader; - }, - - /** - * Serializes a block header. - * @param {object} blockHeader Block header. - * @param {object} serializer Serializer. - */ - serialize: (blockHeader, serializer) => { - serializer.writeUint64(blockHeader.height); - serializer.writeUint64(blockHeader.timestamp); - serializer.writeUint64(blockHeader.difficulty); - serializer.writeBuffer(blockHeader.proofGamma); - serializer.writeBuffer(blockHeader.proofVerificationHash); - serializer.writeBuffer(blockHeader.proofScalar); - serializer.writeBuffer(blockHeader.previousBlockHash); - serializer.writeBuffer(blockHeader.transactionsHash); - serializer.writeBuffer(blockHeader.receiptsHash); - serializer.writeBuffer(blockHeader.stateHash); - serializer.writeBuffer(blockHeader.beneficiaryAddress); - serializer.writeUint32(blockHeader.feeMultiplier); - } -}; - -module.exports = blockHeaderCodec; diff --git a/catapult-sdk/src/modelBinary/embeddedEntityCodec.js b/catapult-sdk/src/modelBinary/embeddedEntityCodec.js deleted file mode 100644 index 8099ede0e..000000000 --- a/catapult-sdk/src/modelBinary/embeddedEntityCodec.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/embeddedEntityCodec */ -const sizes = require('./sizes'); - -const constants = { sizes }; - -const embeddedEntityCodec = { - /** - * Parses an embedded entity. - * @param {object} parser Parser. - * @returns {object} Parsed entity. - */ - deserialize: parser => { - const entity = {}; - entity.embeddedTransactionHeader_Reserved1 = parser.uint32(); - entity.signerPublicKey = parser.buffer(constants.sizes.signerPublicKey); - entity.entityBody_Reserved1 = parser.uint32(); - entity.version = parser.uint8(); - entity.network = parser.uint8(); - entity.type = parser.uint16(); - return entity; - }, - - /** - * Serializes an embedded entity. - * @param {object} entity Entity. - * @param {object} serializer Serializer. - */ - serialize: (entity, serializer) => { - serializer.writeUint32(entity.embeddedTransactionHeader_Reserved1); - serializer.writeBuffer(entity.signerPublicKey); - serializer.writeUint32(entity.entityBody_Reserved1); - serializer.writeUint8(entity.version); - serializer.writeUint8(entity.network); - serializer.writeUint16(entity.type); - } -}; - -module.exports = embeddedEntityCodec; diff --git a/catapult-sdk/src/modelBinary/importanceBlockHeaderCodec.js b/catapult-sdk/src/modelBinary/importanceBlockHeaderCodec.js deleted file mode 100644 index 43952c94a..000000000 --- a/catapult-sdk/src/modelBinary/importanceBlockHeaderCodec.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/importanceBlockHeaderCodec */ -const sizes = require('./sizes'); - -const constants = { sizes }; - -const importanceBlockHeaderCodec = { - /** - * Parses a block header. - * @param {object} parser Parser. - * @returns {object} Parsed block header. - */ - deserialize: parser => { - const importanceBlockHeader = {}; - importanceBlockHeader.votingEligibleAccountsCount = parser.uint32(); - importanceBlockHeader.harvestingEligibleAccountsCount = parser.uint64(); - importanceBlockHeader.totalVotingBalance = parser.uint64(); - importanceBlockHeader.previousImportanceBlockHash = parser.buffer(constants.sizes.hash256); - return importanceBlockHeader; - }, - - /** - * Serializes a block header. - * @param {object} importanceBlockHeader Block header. - * @param {object} serializer Serializer. - */ - serialize: (importanceBlockHeader, serializer) => { - serializer.writeUint32(importanceBlockHeader.votingEligibleAccountsCount); - serializer.writeUint64(importanceBlockHeader.harvestingEligibleAccountsCount); - serializer.writeUint64(importanceBlockHeader.totalVotingBalance); - serializer.writeBuffer(importanceBlockHeader.previousImportanceBlockHash); - } -}; - -module.exports = importanceBlockHeaderCodec; diff --git a/catapult-sdk/src/modelBinary/serialize.js b/catapult-sdk/src/modelBinary/serialize.js deleted file mode 100644 index 99c547bf5..000000000 --- a/catapult-sdk/src/modelBinary/serialize.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/serialize */ -const BinarySerializer = require('../serializer/BinarySerializer'); -const SerializedSizeCalculator = require('../serializer/SerializedSizeCalculator'); -const convert = require('../utils/convert'); - -const serializeToBuffer = (codec, entity) => { - const calculator = new SerializedSizeCalculator(); - codec.serialize(entity, calculator); - - const serializer = new BinarySerializer(calculator.size()); - codec.serialize(entity, serializer); - return serializer.buffer(); -}; - -/** - * Serializer utility functions. - */ -const serialize = { - /** - * Serializes an entity to a hex string using a codec. - * @param {module:modelBinary/ModelCodec} codec Model codec. - * @param {object} entity Entity to serialize. - * @returns {string} A hex string representing the entity. - */ - toHex: (codec, entity) => convert.uint8ToHex(serializeToBuffer(codec, entity)), - - /** - * Serializes an entity to a buffer using a codec. - * @param {module:modelBinary/ModelCodec} codec Model codec. - * @param {object} entity Entity to serialize. - * @returns {Buffer} A buffer representing the entity. - */ - toBuffer: serializeToBuffer -}; - -module.exports = serialize; diff --git a/catapult-sdk/src/modelBinary/sizes.js b/catapult-sdk/src/modelBinary/sizes.js deleted file mode 100644 index 36916320b..000000000 --- a/catapult-sdk/src/modelBinary/sizes.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/sizes */ - -const sizes = { - /** - * @property {numeric} Size of a signature. - */ - signature: 64, - - /** - * @property {numeric} Size of a signer public key. - */ - signerPublicKey: 32, - - /** - * @property {numeric} Size of a decoded address. - */ - addressDecoded: 24, - - /** - * @property {numeric} Size of a transaction header. - */ - transactionHeader: 4 + 4 + 64 + 32 + 4, - - /** - * @property {numeric} Size of a sha3 256 hash. - */ - hash256: 32, - - /** - * @property {numeric} Size of a sha3 512 hash. - */ - hash512: 64, - - /** - * @property {numeric} Size of VRF proof properties. - */ - vrfProof: { - gamma: 32, - verificationHash: 16, - scalar: 32 - } -}; - -module.exports = sizes; diff --git a/catapult-sdk/src/modelBinary/transactionCodec.js b/catapult-sdk/src/modelBinary/transactionCodec.js deleted file mode 100644 index e26be25ed..000000000 --- a/catapult-sdk/src/modelBinary/transactionCodec.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/transactionCodec */ - -const transactionCodec = { - /** - * Parses a transaction. - * @param {object} parser Parser. - * @returns {object} Parsed transaction. - */ - deserialize: parser => { - const transaction = {}; - transaction.maxFee = parser.uint64(); - transaction.deadline = parser.uint64(); - return transaction; - }, - - /** - * Serializes a transaction. - * @param {object} transaction Transaction. - * @param {object} serializer Serializer. - */ - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.maxFee); - serializer.writeUint64(transaction.deadline); - } -}; - -module.exports = transactionCodec; diff --git a/catapult-sdk/src/modelBinary/transactionExtensions.js b/catapult-sdk/src/modelBinary/transactionExtensions.js deleted file mode 100644 index 6f926fa71..000000000 --- a/catapult-sdk/src/modelBinary/transactionExtensions.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const serialize = require('./serialize'); -const sizes = require('./sizes'); -const crypto = require('../crypto/keyPair'); -const sha3Hasher = require('../crypto/sha3Hasher'); - -// serialize.toBuffer returns a nodejs buffer that does not copy any data when slicing -const serializeToBuffer = (codec, transaction) => serialize.toBuffer(codec, transaction).slice(sizes.transactionHeader); - -const transactionExtensions = { - /** - * Calculates the hash of a transaction. - * @param {module:modelBinary/ModelCodec} codec Transaction codec. - * @param {object} transaction Transaction to hash. - * @returns {Uint8Array} Transaction hash. - */ - hash: (codec, transaction) => { - const transactionHash = new Uint8Array(32); - const hasher = sha3Hasher.createHasher(32); - hasher.reset(); - - // "R" - hasher.update(transaction.signature.slice(0, 32)); - - // pubkey - hasher.update(transaction.signerPublicKey); - - // data - const transactionBuffer = serializeToBuffer(codec, transaction); - hasher.update(transactionBuffer); - hasher.finalize(transactionHash); - - return transactionHash; - }, - - /** - * Signs a transaction using a signer's private key. - * @param {module:modelBinary/ModelCodec} codec Transaction codec. - * @param {object} keyPair Signer's key pair. - * @param {object} transaction Transaction to sign. - */ - sign: (codec, keyPair, transaction) => { - const transactionBuffer = serializeToBuffer(codec, transaction); - transaction.signature = crypto.sign(keyPair, transactionBuffer); - }, - - /** - * Verifies the signature of a transaction. - * @param {module:modelBinary/ModelCodec} codec Transaction codec. - * @param {object} transaction Transaction to verify. - * @returns {boolean} true if the transaction signature is valid. - */ - verify: (codec, transaction) => { - const transactionBuffer = serializeToBuffer(codec, transaction); - return crypto.verify(transaction.signerPublicKey, transactionBuffer, transaction.signature); - } -}; - -module.exports = transactionExtensions; diff --git a/catapult-sdk/src/modelBinary/verifiableEntityCodec.js b/catapult-sdk/src/modelBinary/verifiableEntityCodec.js deleted file mode 100644 index 1637ad31d..000000000 --- a/catapult-sdk/src/modelBinary/verifiableEntityCodec.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module modelBinary/verifiableEntityCodec */ -const sizes = require('./sizes'); - -const constants = { sizes }; - -const verifiableEntityCodec = { - /** - * Parses a verifiable entity. - * @param {object} parser Parser. - * @returns {object} Parsed entity. - */ - deserialize: parser => { - const entity = {}; - entity.verifiableEntityHeader_Reserved1 = parser.uint32(); - entity.signature = parser.buffer(constants.sizes.signature); - entity.signerPublicKey = parser.buffer(constants.sizes.signerPublicKey); - entity.entityBody_Reserved1 = parser.uint32(); - entity.version = parser.uint8(); - entity.network = parser.uint8(); - entity.type = parser.uint16(); - return entity; - }, - - /** - * Serializes a verifiable entity. - * @param {object} entity Entity. - * @param {object} serializer Serializer. - */ - serialize: (entity, serializer) => { - serializer.writeUint32(entity.verifiableEntityHeader_Reserved1); - serializer.writeBuffer(entity.signature); - serializer.writeBuffer(entity.signerPublicKey); - serializer.writeUint32(entity.entityBody_Reserved1); - serializer.writeUint8(entity.version); - serializer.writeUint8(entity.network); - serializer.writeUint16(entity.type); - } -}; - -module.exports = verifiableEntityCodec; diff --git a/catapult-sdk/src/packet/PacketType.js b/catapult-sdk/src/packet/PacketType.js deleted file mode 100644 index d27827f6b..000000000 --- a/catapult-sdk/src/packet/PacketType.js +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module packet/PacketType */ - -const statePathBaseType = 0x200; - -/** - * Packet types. - * @enum {numeric} - */ -const PacketType = { - /** A challenge from a server to a client. */ - serverChallenge: 1, - - /** A challenge from a client to a server. */ - clientChallenge: 2, - - /** Blocks have been pushed by a peer. */ - pushBlock: 3, - - /** Transactions have been pushed by an api-node or a peer. */ - pushTransactions: 9, - - /** Partial aggregate transactions have been pushed by an api-node. */ - pushPartialTransactions: 0x100, - - /** Detached cosignatures have been pushed by an api-node. */ - pushDetachedCosignatures: 0x101, - - /** Node information has been requested by a peer. */ - nodeDiscoveryPullPing: 0x111, - - /** Node peers had been requested by a peer. */ - nodeDiscoveryPullPeers: 0x113, - - /** Node time information has been requested by a peer. */ - timeSyncNodeTime: 0x120, - - /** Finalization proof has been requested by a peer */ - finalizationProofAtEpoch: 0x133, - finalizationProofAtHeight: 0x134, - - /** Unlocked account */ - unlockedAccount: 0x304, - - /** State path has been requested by a peer. */ - accountStatePath: statePathBaseType + 0x43, - hashLockStatePath: statePathBaseType + 0x48, - secretLockStatePath: statePathBaseType + 0x52, - metadataStatePath: statePathBaseType + 0x44, - mosaicStatePath: statePathBaseType + 0x4D, - multisigStatePath: statePathBaseType + 0x55, - namespaceStatePath: statePathBaseType + 0x4E, - accountRestrictionsStatePath: statePathBaseType + 0x50, - mosaicRestrictionsStatePath: statePathBaseType + 0x51 -}; - -module.exports = { - PacketType, - StatePathPacketTypes: [ - PacketType.accountStatePath, - PacketType.hashLockStatePath, - PacketType.secretLockStatePath, - PacketType.metadataStatePath, - PacketType.mosaicStatePath, - PacketType.multisigStatePath, - PacketType.namespaceStatePath, - PacketType.accountRestrictionsStatePath, - PacketType.mosaicRestrictionsStatePath - ] -}; diff --git a/catapult-sdk/src/packet/header.js b/catapult-sdk/src/packet/header.js deleted file mode 100644 index 9fd7fa350..000000000 --- a/catapult-sdk/src/packet/header.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @exports packet/header */ -const packetHeader = { - /** - * @property {numeric} size Size (in bytes) of a packet header. - */ - size: 8, - - /** - * Creates a packet header buffer. - * @param {module:packet/types} type Packet type. - * @param {numeric} size Packet size. - * @returns {Buffer} Packet header buffer. - */ - createBuffer: (type, size) => { - const header = Buffer.alloc(packetHeader.size); - header.writeInt32LE(size, 0); - header.writeInt32LE(type, 4); - return header; - } -}; - -module.exports = packetHeader; diff --git a/catapult-sdk/src/parser/BinaryParser.js b/catapult-sdk/src/parser/BinaryParser.js deleted file mode 100644 index a004862f5..000000000 --- a/catapult-sdk/src/parser/BinaryParser.js +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module parser/BinaryParser */ - -class BufferContainer { - constructor() { - this.offset = 0; - this.buffers = []; - this.numUnprocessedBytes = 0; - } - - current() { - return this.buffers[0]; - } - - push(buffer) { - if (!Buffer.isBuffer(buffer)) - throw Error('BinaryParser only supports aggregating NodeJS Buffer objects'); - - if (0 === buffer.length) - return; - - this.buffers.push(buffer); - this.numUnprocessedBytes += buffer.length; - } - - consume(size) { - this.offset += size; - this.numUnprocessedBytes -= size; - - if (this.offset === this.current().length) { - this.offset = 0; - this.buffers.shift(); - } - } - - requireUnprocessed(size) { - if (this.numUnprocessedBytes < size) - throw Error(`insufficient unprocessed data (${size} bytes required, ${this.numUnprocessedBytes} bytes available)`); - } - - nextByte() { - this.requireUnprocessed(1); - - const buffer = this.current(); - const byte = buffer[this.offset]; - this.consume(1); - return byte; - } - - nextInteger(size) { - this.requireUnprocessed(size); - - let value = 0; - for (let i = 0; i < size; ++i) - value |= this.nextByte() << (i * 8); - - return value >>> 0; - } - - nextBuffer(size) { - this.requireUnprocessed(size); - - return this.nextBufferInPlace(size) || this.nextBufferOutOfPlace(size); - } - - nextBufferInPlace(size) { - const buffer = this.current(); - if (buffer.length - this.offset < size) - return undefined; - - const result = buffer.slice(this.offset, this.offset + size); - this.consume(size); - return result; - } - - nextBufferOutOfPlace(size) { - // the requested buffer spans multiple buffers, so copy into a new buffer - const result = Buffer.allocUnsafe(size); - for (let i = 0; i < size; ++i) - result[i] = this.nextByte(); - - return result; - } - - size() { - return this.numUnprocessedBytes; - } -} - -/** - * Accepts and buffers binary data and provides an interface for reading from it. - */ -class BinaryParser { - /** - * Creates a binary parser. - */ - constructor() { - this.buffers = new BufferContainer(); - } - - /** - * Accepts a binary buffer and appends it to the end of the working buffer. - * @param {Buffer} buffer Binary buffer. - */ - push(buffer) { - this.buffers.push(buffer); - } - - /** - * Reads a uint8 from the working buffer. - * @returns {numeric} Read uint8. - */ - uint8() { - return this.buffers.nextByte(); - } - - /** - * Reads a uint16 from the working buffer. - * @returns {numeric} Read uint16. - */ - uint16() { - return this.buffers.nextInteger(2); - } - - /** - * Reads a uint32 from the working buffer. - * @returns {numeric} Read uint32. - */ - uint32() { - return this.buffers.nextInteger(4); - } - - /** - * Reads a uint64 from the working buffer. - * @returns {module:utils/uint64~uint64} Read uint64. - */ - uint64() { - this.buffers.requireUnprocessed(8); - return [this.uint32(), this.uint32()]; - } - - /** - * Reads a specific number of bytes from the working buffer. - * @param {numeric} size Number of bytes to read. - * @returns {Buffer} Read bytes. - */ - buffer(size) { - return this.buffers.nextBuffer(size); - } - - /** - * Gets the number of unprocessed bytes remaining in the working buffer. - * @returns {numeric} Number of unprocessed bytes. - */ - numUnprocessedBytes() { - return this.buffers.size(); - } -} - -module.exports = BinaryParser; diff --git a/catapult-sdk/src/parser/PacketParser.js b/catapult-sdk/src/parser/PacketParser.js deleted file mode 100644 index 6962fd2b6..000000000 --- a/catapult-sdk/src/parser/PacketParser.js +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module parser/PacketParser */ -const BinaryParser = require('./BinaryParser'); -const EventEmitter = require('events'); - -const Packet_Header_Size = 8; - -class PacketParserImpl { - constructor() { - this.parser = new BinaryParser(); - this.packetHeader = undefined; - this.emitter = new EventEmitter(); - } - - push(buffer) { - this.parser.push(buffer); - - // note: processHeader will process at most one header when called consecutively - do { - this.processHeader(); - this.processBody(); - } while (this.processHeader()); - } - - processHeader() { - if (undefined !== this.packetHeader || this.parser.numUnprocessedBytes() < Packet_Header_Size) - return false; - - const size = this.parser.uint32(); - const type = this.parser.uint32(); - - if (size < Packet_Header_Size) - throw Error(`packet size (${size}) cannot be less than packet header size`); - - this.packetHeader = { size, type }; - return true; - } - - processBody() { - if (undefined === this.packetHeader || this.parser.numUnprocessedBytes() < this.packetHeader.size - Packet_Header_Size) - return false; - - this.raisePacketEvent(); - this.packetHeader = undefined; - return true; - } - - raisePacketEvent() { - // consume the entire payload - const payload = this.packetHeader.size > Packet_Header_Size - ? this.parser.buffer(this.packetHeader.size - Packet_Header_Size) - : Buffer.alloc(0); - - this.emitter.emit('packet', { type: this.packetHeader.type, size: this.packetHeader.size, payload }); - } -} - -/** - * A raw packet composed of header information and a payload. - * @typedef {object} RawPacket - * @property {numeric} type Packet type. - * @property {numeric} size Packet size. - * @property {Buffer} payload Packet payload. - */ - -/** - * Accepts and buffers binary data and emits events when full packets have been received. - */ -class PacketParser { - /** - * Creates a packet parser. - */ - constructor() { - this.impl = new PacketParserImpl(); - } - - /** - * Accepts a binary buffer and appends it to the end of the working buffer. - * @param {Buffer} buffer Binary buffer. - */ - push(buffer) { - this.impl.push(buffer); - } - - /** - * Subscribes a handler to receive notifications when full packets have been received. - * @param {Function} handler Handler function that is called with a {@link module:parser/PacketParser~RawPacket}. - */ - onPacket(handler) { - this.impl.emitter.on('packet', handler); - } -} - -module.exports = PacketParser; diff --git a/catapult-sdk/src/plugins/CatapultPlugin.js b/catapult-sdk/src/plugins/CatapultPlugin.js deleted file mode 100644 index d853b3d31..000000000 --- a/catapult-sdk/src/plugins/CatapultPlugin.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/CatapultPlugin */ - -// this file only contains an interface for prettier documentation, so ignore no-unused-vars warnings - -/* eslint-disable no-unused-vars */ - -/** - * Adds support for a particular subsystem. - * @interface - */ -const CatapultPlugin = { - /** - * Registers schema extensions. - * @instance - * @param {module:model/ModelSchemaBuilder} schemaBuilder Schema builder to augment. - */ - registerSchema: schemaBuilder => {}, - - /** - * Registers codecs for serializing and deserializing transactions. - * @instance - * @param {module:modelBinary/ModelCodecBuilder} codecBuilder Codec builder to augment. - */ - registerCodecs: codecBuilder => {} -}; - -/* eslint-enable */ -module.exports = CatapultPlugin; diff --git a/catapult-sdk/src/plugins/accountLink.js b/catapult-sdk/src/plugins/accountLink.js deleted file mode 100644 index a432f5937..000000000 --- a/catapult-sdk/src/plugins/accountLink.js +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/accountLink */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; - -/** - * Creates an accountLink plugin. - * @type {module:plugins/CatapultPlugin} - */ -const accountLinkPlugin = { - registerSchema: builder => { - builder.addTransactionSupport(EntityType.accountLink, { - linkedPublicKey: ModelType.binary, - linkAction: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.nodeKeyLink, { - linkedPublicKey: ModelType.binary, - linkAction: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.votingKeyLink, { - linkedPublicKey: ModelType.binary, - startEpoch: ModelType.uint32, - endEpoch: ModelType.uint32, - linkAction: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.vrfKeyLink, { - linkedPublicKey: ModelType.binary, - linkAction: ModelType.uint8 - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.accountLink, { - deserialize: parser => { - const transaction = {}; - transaction.linkedPublicKey = parser.buffer(constants.sizes.signerPublicKey); - transaction.linkAction = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.linkedPublicKey); - serializer.writeUint8(transaction.linkAction); - } - }); - - codecBuilder.addTransactionSupport(EntityType.nodeKeyLink, { - deserialize: parser => { - const transaction = {}; - transaction.linkedPublicKey = parser.buffer(constants.sizes.signerPublicKey); - transaction.linkAction = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.linkedPublicKey); - serializer.writeUint8(transaction.linkAction); - } - }); - - codecBuilder.addTransactionSupport(EntityType.votingKeyLink, { - deserialize: parser => { - const transaction = {}; - transaction.linkedPublicKey = parser.buffer(constants.sizes.signerPublicKey); - transaction.startEpoch = parser.uint32(); - transaction.endEpoch = parser.uint32(); - transaction.linkAction = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.linkedPublicKey); - serializer.writeUint32(transaction.startEpoch); - serializer.writeUint32(transaction.endEpoch); - serializer.writeUint8(transaction.linkAction); - } - }); - - codecBuilder.addTransactionSupport(EntityType.vrfKeyLink, { - deserialize: parser => { - const transaction = {}; - transaction.linkedPublicKey = parser.buffer(constants.sizes.signerPublicKey); - transaction.linkAction = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.linkedPublicKey); - serializer.writeUint8(transaction.linkAction); - } - }); - } -}; - -module.exports = accountLinkPlugin; diff --git a/catapult-sdk/src/plugins/aggregate.js b/catapult-sdk/src/plugins/aggregate.js deleted file mode 100644 index e2e51bb00..000000000 --- a/catapult-sdk/src/plugins/aggregate.js +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/aggregate */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const embeddedEntityCodec = require('../modelBinary/embeddedEntityCodec'); -const sizes = require('../modelBinary/sizes'); -const SerializedSizeCalculator = require('../serializer/SerializedSizeCalculator'); - -const constants = { sizes: {} }; -Object.assign(constants.sizes, sizes, { - aggregate: 128 + 32 + 4 + 4, // size passed into deserialize includes full transaction size (even previously processed parts) - embedded: 48, - cosignature: 8 + sizes.signerPublicKey + sizes.signature -}); - -const createSubTransactionCodec = txCodecs => { - const getTxCodec = type => { - // unlike in block case (handled by ModelCodecBuilder), don't fallback to unknown transaction type - const txCodec = txCodecs[type]; - if (!txCodec) - throw Error(`error unsupported transaction type (${type}) in aggregate`); - - return txCodec; - }; - - const serializeAll = (transaction, serializer) => { - const codecs = [embeddedEntityCodec, getTxCodec(transaction.type)]; - codecs.forEach(codec => { - codec.serialize(transaction, serializer); - }); - }; - - // notice that the subTxCodec is not conformant and is slightly different from other codecs - const subTxCodec = { - size: transaction => { - const sizeCalculator = new SerializedSizeCalculator(); - serializeAll(transaction, sizeCalculator); - return sizeCalculator.size() + 4; // include size of size field itself - }, - - deserialize: parser => { - const size = parser.uint32(); - const entity = embeddedEntityCodec.deserialize(parser); - - const txCodec = getTxCodec(entity.type); - Object.assign(entity, txCodec.deserialize(parser)); - return { size, entity }; - }, - - serialize: (transaction, serializer, size) => { - serializer.writeUint32(size); - serializeAll(transaction, serializer); - } - }; - - return subTxCodec; -}; - -const requireCodecs = txCodecs => { - // this check causes rejection of embedded aggregates because aggregate codec intentionally does not forward tx codecs to - // sub transaction codecs - if (undefined === txCodecs) - throw Error('aggregate transaction is not embeddable'); -}; - -// after every inner transaction in an aggregate there's padding up to 8 bytes -const innerAggregateTxPaddingSize = innerTransactionSize => { - const alignment = 8; - return 0 === innerTransactionSize % alignment ? 0 : alignment - (innerTransactionSize % alignment); -}; - -/** - * Creates an aggregate plugin. - * @type {module:plugins/CatapultPlugin} - */ -const aggregatePlugin = { - registerSchema: builder => { - const aggregateSchema = { - transactionsHash: ModelType.binary, - transactions: { type: ModelType.array, schemaName: 'transactionWithMetadata' }, - cosignatures: { type: ModelType.array, schemaName: 'aggregate.cosignature' } - }; - - builder.addTransactionSupport(EntityType.aggregateComplete, aggregateSchema); - builder.addTransactionSupport(EntityType.aggregateBonded, aggregateSchema); - - builder.addSchema('aggregate.cosignature', { - version: ModelType.uint64, - signerPublicKey: ModelType.binary, - signature: ModelType.binary, - parentHash: ModelType.binary - }); - }, - - registerCodecs: codecBuilder => { - const aggregateBuilder = { - deserialize: (parser, size, txCodecs) => { - requireCodecs(txCodecs); - - const transaction = {}; - transaction.transactionsHash = parser.buffer(constants.sizes.hash256); - - if (size < constants.sizes.aggregate) - throw Error('aggregate must contain complete aggregate header'); - - const payloadSize = parser.uint32(); - if (size < payloadSize + constants.sizes.aggregate) - throw Error('aggregate must contain complete payload'); - - transaction.aggregateTransactionHeader_Reserved1 = parser.uint32(); - - // 1. deserialize transactions - if (0 < payloadSize) { - transaction.transactions = []; - - const txCodec = createSubTransactionCodec(txCodecs); - let processedSize = 0; - while (processedSize < payloadSize) { - const subTransaction = txCodec.deserialize(parser); - transaction.transactions.push({ transaction: subTransaction.entity }); - processedSize += subTransaction.size; - - const paddingSize = innerAggregateTxPaddingSize(subTransaction.size); - if (0 < paddingSize) { - parser.buffer(paddingSize); - processedSize += paddingSize; - } - if (subTransaction.size < constants.sizes.embedded) - throw Error('sub transaction must contain complete transaction header'); - } - } - - // 2. deserialize cosignatures - const numCosignatures = (size - payloadSize - constants.sizes.aggregate) / constants.sizes.cosignature; - - if (numCosignatures !== (numCosignatures | 0)) - throw Error('aggregate cannot have partial cosignatures'); - - if (0 < numCosignatures) { - transaction.cosignatures = []; - for (let i = 0; i < numCosignatures; ++i) { - const cosignature = {}; - cosignature.version = parser.uint64(); - cosignature.signerPublicKey = parser.buffer(constants.sizes.signerPublicKey); - cosignature.signature = parser.buffer(constants.sizes.signature); - transaction.cosignatures.push(cosignature); - } - } - - return transaction; - }, - - serialize: (transaction, serializer, txCodecs) => { - requireCodecs(txCodecs); - - serializer.writeBuffer(transaction.transactionsHash); - - // 1. calculate payload size - const txCodec = createSubTransactionCodec(txCodecs); - - // notice that inner tx metadata is not serialized because it is derivable - const transactions = (transaction.transactions || []).map(transactionWithMetadata => transactionWithMetadata.transaction); - const subTransactionSizes = []; - - let payloadSize = 0; - transactions.forEach(subTransaction => { - const subTransactionSize = txCodec.size(subTransaction); - subTransactionSizes.push(subTransactionSize); - const paddingSize = innerAggregateTxPaddingSize(subTransactionSize); - payloadSize += subTransactionSize + paddingSize; - }); - - serializer.writeUint32(payloadSize); - - serializer.writeUint32(transaction.aggregateTransactionHeader_Reserved1); - - // 2. serialize transactions - let i = 0; - transactions.forEach(subTransaction => { - const subTransactionSize = subTransactionSizes[i++]; - txCodec.serialize(subTransaction, serializer, subTransactionSize); - const paddingSize = innerAggregateTxPaddingSize(subTransactionSize); - if (0 < paddingSize) - serializer.writeBuffer(Buffer.alloc(paddingSize)); - }); - - // 3. serialize cosignatures - if (transaction.cosignatures) { - transaction.cosignatures.forEach(cosignature => { - serializer.writeUint64(cosignature.version); - serializer.writeBuffer(cosignature.signerPublicKey); - serializer.writeBuffer(cosignature.signature); - }); - } - } - }; - - codecBuilder.addTransactionSupport(EntityType.aggregateComplete, aggregateBuilder); - codecBuilder.addTransactionSupport(EntityType.aggregateBonded, aggregateBuilder); - } -}; - -module.exports = aggregatePlugin; diff --git a/catapult-sdk/src/plugins/catapultModelSystem.js b/catapult-sdk/src/plugins/catapultModelSystem.js deleted file mode 100644 index 3de1adb87..000000000 --- a/catapult-sdk/src/plugins/catapultModelSystem.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/catapultModelSystem */ -const accountLink = require('./accountLink'); -const aggregate = require('./aggregate'); -const lockHash = require('./lockHash'); -const lockSecret = require('./lockSecret'); -const metadata = require('./metadata'); -const mosaic = require('./mosaic'); -const multisig = require('./multisig'); -const namespace = require('./namespace'); -const receipts = require('./receipts'); -const restrictions = require('./restrictions'); -const transfer = require('./transfer'); -const ModelFormatterBuilder = require('../model/ModelFormatterBuilder'); -const ModelSchemaBuilder = require('../model/ModelSchemaBuilder'); -const ModelCodecBuilder = require('../modelBinary/ModelCodecBuilder'); - -const plugins = { - accountLink, - aggregate, - lockHash, - lockSecret, - metadata, - mosaic, - multisig, - namespace, - receipts, - restrictions, - transfer -}; - -/** - * A complete catapult model system. - * @class CatapultModelSystem - * - * @property {object} schema Complete schema information. - */ -const catapultModelSystem = { - /** - * Gets the names of all supported plugins. - * @returns {array} Names of all supported plugins. - */ - supportedPluginNames: () => Object.keys(plugins), - - /** - * Builds a catapult model system with the specified extensions. - * @param {array} pluginNames Additional extensions to use. - * @param {object} namedFormattingRules A dictionary containing named sets of formatting rules. - * @returns {module:plugins/catapultModelSystem} Configured catapult model system. - */ - configure: (pluginNames, namedFormattingRules) => { - const schemaBuilder = new ModelSchemaBuilder(); - const codecBuilder = new ModelCodecBuilder(); - const formatterBuilder = new ModelFormatterBuilder(); - pluginNames.forEach(pluginName => { - if (!plugins[pluginName]) - throw Error(`plugin '${pluginName}' not supported by model system`); - - const plugin = plugins[pluginName]; - plugin.registerSchema({ - addTransactionSupport: (transactionType, schema) => { - schemaBuilder.addTransactionSupport(transactionType, schema); - formatterBuilder.addFormatter(schemaBuilder.typeToName(transactionType)); - }, - addSchema: (name, schema) => { - schemaBuilder.addSchema(name, schema); - formatterBuilder.addFormatter(name); - } - }); - plugin.registerCodecs(codecBuilder); - }); - - const modelSchema = schemaBuilder.build(); - const formatters = {}; - Object.keys(namedFormattingRules).forEach(key => { - formatters[key] = formatterBuilder.build(modelSchema, namedFormattingRules[key]); - }); - - return { - schema: modelSchema, - codec: codecBuilder.build(), - formatters - }; - } -}; - -module.exports = catapultModelSystem; diff --git a/catapult-sdk/src/plugins/lockHash.js b/catapult-sdk/src/plugins/lockHash.js deleted file mode 100644 index 5277e3e2a..000000000 --- a/catapult-sdk/src/plugins/lockHash.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/lockHash */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; - -/** - * Creates a lock hash plugin. - * @type {module:plugins/CatapultPlugin} - */ -const lockHashPlugin = { - registerSchema: builder => { - builder.addSchema('hashLockInfo', { - id: ModelType.objectId, - lock: { type: ModelType.object, schemaName: 'hashLockInfo.lock' } - }); - builder.addSchema('hashLockInfo.lock', { - version: ModelType.uint16, - ownerAddress: ModelType.encodedAddress, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64, - endHeight: ModelType.uint64, - status: ModelType.int, - hash: ModelType.binary - }); - - builder.addTransactionSupport(EntityType.hashLock, { - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64, - duration: ModelType.uint64, - hash: ModelType.binary - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.hashLock, { - deserialize: parser => { - const transaction = {}; - transaction.mosaicId = parser.uint64(); - transaction.amount = parser.uint64(); - transaction.duration = parser.uint64(); - transaction.hash = parser.buffer(constants.sizes.hash256); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint64(transaction.amount); - serializer.writeUint64(transaction.duration); - serializer.writeBuffer(transaction.hash); - } - }); - } -}; - -module.exports = lockHashPlugin; diff --git a/catapult-sdk/src/plugins/lockSecret.js b/catapult-sdk/src/plugins/lockSecret.js deleted file mode 100644 index 5823e32e8..000000000 --- a/catapult-sdk/src/plugins/lockSecret.js +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/lockSecret */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; - -/** - * Creates a lock secret plugin. - * @type {module:plugins/CatapultPlugin} - */ -const lockSecretPlugin = { - registerSchema: builder => { - builder.addSchema('secretLockInfo', { - id: ModelType.objectId, - lock: { type: ModelType.object, schemaName: 'secretLockInfo.lock' } - }); - builder.addSchema('secretLockInfo.lock', { - version: ModelType.uint16, - ownerAddress: ModelType.encodedAddress, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64, - endHeight: ModelType.uint64, - status: ModelType.uint8, - hashAlgorithm: ModelType.uint8, - secret: ModelType.binary, - recipientAddress: ModelType.encodedAddress, - compositeHash: ModelType.binary - }); - - builder.addTransactionSupport(EntityType.secretLock, { - recipientAddress: ModelType.encodedAddress, - secret: ModelType.binary, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64, - duration: ModelType.uint64, - hashAlgorithm: ModelType.uint8 - }); - builder.addTransactionSupport(EntityType.secretProof, { - secret: ModelType.binary, - recipientAddress: ModelType.encodedAddress, - proof: ModelType.binary, - hashAlgorithm: ModelType.uint8 - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.secretLock, { - deserialize: parser => { - const transaction = {}; - transaction.recipientAddress = parser.buffer(constants.sizes.addressDecoded); - transaction.secret = parser.buffer(constants.sizes.hash256); - transaction.mosaicId = parser.uint64(); - transaction.amount = parser.uint64(); - transaction.duration = parser.uint64(); - transaction.hashAlgorithm = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.recipientAddress); - serializer.writeBuffer(transaction.secret); - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint64(transaction.amount); - serializer.writeUint64(transaction.duration); - serializer.writeUint8(transaction.hashAlgorithm); - } - }); - - codecBuilder.addTransactionSupport(EntityType.secretProof, { - deserialize: parser => { - const transaction = {}; - transaction.recipientAddress = parser.buffer(constants.sizes.addressDecoded); - transaction.secret = parser.buffer(constants.sizes.hash256); - const proofSize = parser.uint16(); - transaction.hashAlgorithm = parser.uint8(); - transaction.proof = parser.buffer(proofSize); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.recipientAddress); - serializer.writeBuffer(transaction.secret); - serializer.writeUint16(transaction.proof.length); - serializer.writeUint8(transaction.hashAlgorithm); - serializer.writeBuffer(transaction.proof); - } - }); - } -}; - -module.exports = lockSecretPlugin; diff --git a/catapult-sdk/src/plugins/metadata.js b/catapult-sdk/src/plugins/metadata.js deleted file mode 100644 index 98c2025d4..000000000 --- a/catapult-sdk/src/plugins/metadata.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/metadata */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); -const convert = require('../utils/convert'); - -const constants = { sizes }; - -/** - * Creates a metadata plugin. - * @type {module:plugins/CatapultPlugin} - */ -const metadataPlugin = { - registerSchema: builder => { - builder.addTransactionSupport(EntityType.accountMetadata, { - targetAddress: ModelType.encodedAddress, - scopedMetadataKey: ModelType.uint64HexIdentifier, - valueSizeDelta: ModelType.int, - valueSize: ModelType.uint16, - value: ModelType.binary - }); - - builder.addTransactionSupport(EntityType.mosaicMetadata, { - targetAddress: ModelType.encodedAddress, - scopedMetadataKey: ModelType.uint64HexIdentifier, - targetMosaicId: ModelType.uint64HexIdentifier, - valueSizeDelta: ModelType.int, - valueSize: ModelType.uint16, - value: ModelType.binary - }); - - builder.addTransactionSupport(EntityType.namespaceMetadata, { - targetAddress: ModelType.encodedAddress, - scopedMetadataKey: ModelType.uint64HexIdentifier, - targetNamespaceId: ModelType.uint64HexIdentifier, - valueSizeDelta: ModelType.int, - valueSize: ModelType.uint16, - value: ModelType.binary - }); - - builder.addSchema('metadata', { - id: ModelType.objectId, - metadataEntry: { type: ModelType.object, schemaName: 'metadataEntry' } - }); - - builder.addSchema('metadataEntry', { - version: ModelType.uint16, - compositeHash: ModelType.binary, - sourceAddress: ModelType.encodedAddress, - targetAddress: ModelType.encodedAddress, - scopedMetadataKey: ModelType.uint64HexIdentifier, - targetId: ModelType.uint64HexIdentifier, - metadataType: ModelType.int, - valueSize: ModelType.uint16, - value: ModelType.binary - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.accountMetadata, { - deserialize: parser => { - const transaction = {}; - transaction.targetAddress = parser.buffer(constants.sizes.addressDecoded); - transaction.scopedMetadataKey = parser.uint64(); - transaction.valueSizeDelta = convert.uint16ToInt16(parser.uint16()); - - const valueSize = parser.uint16(); - transaction.value = 0 < valueSize ? parser.buffer(valueSize) : []; - - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.targetAddress); - serializer.writeUint64(transaction.scopedMetadataKey); - serializer.writeUint16(convert.int16ToUint16(transaction.valueSizeDelta)); - serializer.writeUint16(transaction.value.length); - serializer.writeBuffer(transaction.value); - } - }); - - codecBuilder.addTransactionSupport(EntityType.mosaicMetadata, { - deserialize: parser => { - const transaction = {}; - transaction.targetAddress = parser.buffer(constants.sizes.addressDecoded); - transaction.scopedMetadataKey = parser.uint64(); - transaction.targetMosaicId = parser.uint64(); - transaction.valueSizeDelta = convert.uint16ToInt16(parser.uint16()); - - const valueSize = parser.uint16(); - transaction.value = 0 < valueSize ? parser.buffer(valueSize) : []; - - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.targetAddress); - serializer.writeUint64(transaction.scopedMetadataKey); - serializer.writeUint64(transaction.targetMosaicId); - serializer.writeUint16(convert.int16ToUint16(transaction.valueSizeDelta)); - serializer.writeUint16(transaction.value.length); - serializer.writeBuffer(transaction.value); - } - }); - - codecBuilder.addTransactionSupport(EntityType.namespaceMetadata, { - deserialize: parser => { - const transaction = {}; - transaction.targetAddress = parser.buffer(constants.sizes.addressDecoded); - transaction.scopedMetadataKey = parser.uint64(); - transaction.targetNamespaceId = parser.uint64(); - transaction.valueSizeDelta = convert.uint16ToInt16(parser.uint16()); - - const valueSize = parser.uint16(); - transaction.value = 0 < valueSize ? parser.buffer(valueSize) : []; - - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.targetAddress); - serializer.writeUint64(transaction.scopedMetadataKey); - serializer.writeUint64(transaction.targetNamespaceId); - serializer.writeUint16(convert.int16ToUint16(transaction.valueSizeDelta)); - serializer.writeUint16(transaction.value.length); - serializer.writeBuffer(transaction.value); - } - }); - } -}; - -module.exports = metadataPlugin; diff --git a/catapult-sdk/src/plugins/mosaic.js b/catapult-sdk/src/plugins/mosaic.js deleted file mode 100644 index b6df03977..000000000 --- a/catapult-sdk/src/plugins/mosaic.js +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/mosaic */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; -/** - * Creates a mosaic plugin. - * @type {module:plugins/CatapultPlugin} - */ -const mosaicPlugin = { - registerSchema: builder => { - builder.addTransactionSupport(EntityType.mosaicDefinition, { - id: ModelType.uint64HexIdentifier, - duration: ModelType.uint64, - nonce: ModelType.uint32, - flags: ModelType.uint8, - divisibility: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.mosaicSupplyChange, { - mosaicId: ModelType.uint64HexIdentifier, - delta: ModelType.uint64, - action: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.mosaicSupplyRevocation, { - sourceAddress: ModelType.encodedAddress, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64 - }); - - builder.addSchema('mosaicDescriptor', { - id: ModelType.objectId, - mosaic: { type: ModelType.object, schemaName: 'mosaicDescriptor.mosaic' } - }); - - builder.addSchema('mosaicDescriptor.mosaic', { - version: ModelType.uint16, - id: ModelType.uint64HexIdentifier, - supply: ModelType.uint64, - startHeight: ModelType.uint64, - ownerAddress: ModelType.encodedAddress, - revision: ModelType.int, - flags: ModelType.uint8, - divisibility: ModelType.uint8, - duration: ModelType.uint64 - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.mosaicDefinition, { - deserialize: parser => { - const transaction = {}; - transaction.id = parser.uint64(); - transaction.duration = parser.uint64(); - transaction.nonce = parser.uint32(); - transaction.flags = parser.uint8(); - transaction.divisibility = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.id); - serializer.writeUint64(transaction.duration); - serializer.writeUint32(transaction.nonce); - serializer.writeUint8(transaction.flags); - serializer.writeUint8(transaction.divisibility); - } - }); - - codecBuilder.addTransactionSupport(EntityType.mosaicSupplyChange, { - deserialize: parser => { - const transaction = {}; - transaction.mosaicId = parser.uint64(); - transaction.delta = parser.uint64(); - transaction.action = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint64(transaction.delta); - serializer.writeUint8(transaction.action); - } - }); - - codecBuilder.addTransactionSupport(EntityType.mosaicSupplyRevocation, { - deserialize: parser => { - const transaction = {}; - transaction.sourceAddress = parser.buffer(constants.sizes.addressDecoded); - transaction.mosaicId = parser.uint64(); - transaction.amount = parser.uint64(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.sourceAddress); - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint64(transaction.amount); - } - }); - } -}; - -module.exports = mosaicPlugin; diff --git a/catapult-sdk/src/plugins/multisig.js b/catapult-sdk/src/plugins/multisig.js deleted file mode 100644 index 4776b7951..000000000 --- a/catapult-sdk/src/plugins/multisig.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/multisig */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); -const convert = require('../utils/convert'); - -const constants = { sizes }; - -/** - * Creates a multisig plugin. - * @type {module:plugins/CatapultPlugin} - */ -const multisigPlugin = { - registerSchema: builder => { - builder.addTransactionSupport(EntityType.modifyMultisigAccount, { - minRemovalDelta: ModelType.int, - minApprovalDelta: ModelType.int, - addressAdditions: { type: ModelType.array, schemaName: ModelType.encodedAddress }, - addressDeletions: { type: ModelType.array, schemaName: ModelType.encodedAddress } - }); - - builder.addSchema('multisigEntry', { - multisig: { type: ModelType.object, schemaName: 'multisigEntry.multisig' } - }); - builder.addSchema('multisigEntry.multisig', { - version: ModelType.uint16, - accountAddress: ModelType.encodedAddress, - minApproval: ModelType.int, - minRemoval: ModelType.int, - multisigAddresses: { type: ModelType.array, schemaName: ModelType.encodedAddress }, - cosignatoryAddresses: { type: ModelType.array, schemaName: ModelType.encodedAddress } - }); - builder.addSchema('multisigGraph', { - level: ModelType.none, - multisigEntries: { type: ModelType.array, schemaName: 'multisigEntry' } - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.modifyMultisigAccount, { - deserialize: parser => { - const transaction = {}; - transaction.minRemovalDelta = convert.uint8ToInt8(parser.uint8()); - transaction.minApprovalDelta = convert.uint8ToInt8(parser.uint8()); - - const addressAdditionsCount = parser.uint8(); - const addressDeletionsCount = parser.uint8(); - - transaction.multisigAccountModificationTransactionBody_Reserved1 = parser.uint32(); - - transaction.addressAdditions = []; - for (let i = 0; i < addressAdditionsCount; ++i) - transaction.addressAdditions.push(parser.buffer(constants.sizes.addressDecoded)); - - transaction.addressDeletions = []; - for (let i = 0; i < addressDeletionsCount; ++i) - transaction.addressDeletions.push(parser.buffer(constants.sizes.addressDecoded)); - - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint8(convert.int8ToUint8(transaction.minRemovalDelta)); - serializer.writeUint8(convert.int8ToUint8(transaction.minApprovalDelta)); - serializer.writeUint8(transaction.addressAdditions.length); - serializer.writeUint8(transaction.addressDeletions.length); - serializer.writeUint32(transaction.multisigAccountModificationTransactionBody_Reserved1); - transaction.addressAdditions.forEach(key => { - serializer.writeBuffer(key); - }); - transaction.addressDeletions.forEach(key => { - serializer.writeBuffer(key); - }); - } - }); - } -}; - -module.exports = multisigPlugin; diff --git a/catapult-sdk/src/plugins/namespace.js b/catapult-sdk/src/plugins/namespace.js deleted file mode 100644 index b3bd7945f..000000000 --- a/catapult-sdk/src/plugins/namespace.js +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/namespace */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; - -const isNamespaceTypeRoot = namespaceType => 0 === namespaceType; - -const parseString = (parser, size) => parser.buffer(size).toString('ascii'); - -const writeString = (serializer, str) => { serializer.writeBuffer(Buffer.from(str, 'ascii')); }; - -const AliasType = { - 1: 'namespaceDescriptor.alias.mosaic', - 2: 'namespaceDescriptor.alias.address' -}; - -const getAliasBasicType = type => AliasType[type] || 'namespaceDescriptor.alias.empty'; - -/** - * Creates a namespace plugin. - * @type {module:plugins/CatapultPlugin} - */ -const namespacePlugin = { - registerSchema: builder => { - builder.addTransactionSupport(EntityType.aliasAddress, { - namespaceId: ModelType.uint64HexIdentifier, - address: ModelType.encodedAddress, - aliasAction: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.aliasMosaic, { - namespaceId: ModelType.uint64HexIdentifier, - mosaicId: ModelType.uint64HexIdentifier, - aliasAction: ModelType.uint8 - }); - - builder.addTransactionSupport(EntityType.registerNamespace, { - id: ModelType.uint64HexIdentifier, - registrationType: ModelType.uint8, - parentId: ModelType.uint64HexIdentifier, - duration: ModelType.uint64, - name: ModelType.string - }); - - builder.addSchema('namespaces', { - namespaces: { type: ModelType.array, schemaName: 'namespaceDescriptor' } - }); - - builder.addSchema('namespaceDescriptor', { - id: ModelType.objectId, - meta: { type: ModelType.object, schemaName: 'namespaceDescriptor.meta' }, - namespace: { type: ModelType.object, schemaName: 'namespaceDescriptor.namespace' } - }); - - builder.addSchema('namespaceDescriptor.meta', { - active: ModelType.boolean, - index: ModelType.int - }); - - builder.addSchema('namespaceDescriptor.namespace', { - version: ModelType.uint16, - registrationType: ModelType.uint8, - depth: ModelType.uint8, - level0: ModelType.uint64HexIdentifier, - level1: ModelType.uint64HexIdentifier, - level2: ModelType.uint64HexIdentifier, - - alias: { type: ModelType.object, schemaName: entity => getAliasBasicType(entity.type) }, - - parentId: ModelType.uint64HexIdentifier, - ownerAddress: ModelType.encodedAddress, - - startHeight: ModelType.uint64, - endHeight: ModelType.uint64 - }); - - builder.addSchema('namespaceDescriptor.alias.mosaic', { - type: ModelType.uint8, - mosaicId: ModelType.uint64HexIdentifier - }); - - builder.addSchema('namespaceDescriptor.alias.address', { - type: ModelType.uint8, - address: ModelType.encodedAddress - }); - - builder.addSchema('namespaceDescriptor.alias.empty', { - type: ModelType.uint8 - }); - - builder.addSchema('namespaceNameTuple', { - id: ModelType.uint64HexIdentifier, - name: ModelType.string, - parentId: ModelType.uint64HexIdentifier - }); - - builder.addSchema('mosaicNames', { - mosaicNames: { type: ModelType.array, schemaName: 'mosaicNamesTuple' } - }); - - builder.addSchema('mosaicNamesTuple', { - mosaicId: ModelType.uint64HexIdentifier, - names: { type: ModelType.array, schemaName: ModelType.string } - }); - - builder.addSchema('accountNames', { - accountNames: { type: ModelType.array, schemaName: 'accountNamesTuple' } - }); - - builder.addSchema('accountNamesTuple', { - address: ModelType.encodedAddress, - names: { type: ModelType.array, schemaName: ModelType.string } - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.aliasAddress, { - deserialize: parser => ({ - namespaceId: parser.uint64(), - address: parser.buffer(constants.sizes.addressDecoded), - aliasAction: parser.uint8() - }), - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.namespaceId); - serializer.writeBuffer(transaction.address); - serializer.writeUint8(transaction.aliasAction); - } - }); - - codecBuilder.addTransactionSupport(EntityType.aliasMosaic, { - deserialize: parser => ({ - namespaceId: parser.uint64(), - mosaicId: parser.uint64(), - aliasAction: parser.uint8() - }), - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.namespaceId); - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint8(transaction.aliasAction); - } - }); - - codecBuilder.addTransactionSupport(EntityType.registerNamespace, { - deserialize: parser => { - const transaction = {}; - const parentIdOrDuration = parser.uint64(); - transaction.id = parser.uint64(); - transaction.registrationType = parser.uint8(); - transaction[isNamespaceTypeRoot(transaction.registrationType) ? 'duration' : 'parentId'] = parentIdOrDuration; - const nameSize = parser.uint8(); - transaction.name = parseString(parser, nameSize); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint64(isNamespaceTypeRoot(transaction.registrationType) ? transaction.duration : transaction.parentId); - serializer.writeUint64(transaction.id); - serializer.writeUint8(transaction.registrationType); - serializer.writeUint8(transaction.name.length); - writeString(serializer, transaction.name); - } - }); - } -}; - -module.exports = namespacePlugin; diff --git a/catapult-sdk/src/plugins/receipts.js b/catapult-sdk/src/plugins/receipts.js deleted file mode 100644 index cdbd4ad0d..000000000 --- a/catapult-sdk/src/plugins/receipts.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/receipts */ -const ModelType = require('../model/ModelType'); - -// types 2 (balanceCredit), and 3 (balanceDebit) share the schema `receipts.balanceChange` -const ReceiptType = { - 1: 'receipts.balanceTransfer', - 2: 'receipts.balanceChange', - 3: 'receipts.balanceChange', - 4: 'receipts.artifactExpiry', - 5: 'receipts.inflation' -}; - -const getBasicReceiptType = type => ReceiptType[(type & 0xF000) >> 12] || 'receipts.unknown'; - -/** - * Creates a receipts plugin. - * @type {module:plugins/CatapultPlugin} - */ -const receiptsPlugin = { - registerSchema: builder => { - const addStatementSchema = (statementType, schema) => { - const schemaName = `${statementType}Statement`; - builder.addSchema(schemaName, { - id: ModelType.objectId, - meta: { type: ModelType.object, schemaName: 'statement.meta' }, - statement: { type: ModelType.object, schemaName: `${schemaName}.statement` } - }); - builder.addSchema(`${schemaName}.statement`, schema); - }; - - addStatementSchema('addressResolution', { - height: ModelType.uint64, - unresolved: ModelType.encodedAddress, - resolutionEntries: { type: ModelType.array, schemaName: 'receipts.entry.address' } - }); - addStatementSchema('mosaicResolution', { - height: ModelType.uint64, - unresolved: ModelType.uint64HexIdentifier, - resolutionEntries: { type: ModelType.array, schemaName: 'receipts.entry.mosaic' } - }); - addStatementSchema('transaction', { - height: ModelType.uint64, - source: { type: ModelType.object, schemaName: 'receipts.source' }, - receipts: { type: ModelType.array, schemaName: entity => getBasicReceiptType(entity.type) } - }); - - builder.addSchema('statement.meta', { - timestamp: ModelType.uint64 - }); - - // addressResolution statements - builder.addSchema('receipts.entry.address', { - source: { type: ModelType.object, schemaName: 'receipts.source' }, - resolved: ModelType.encodedAddress - }); - - // mosaicResolution statements - builder.addSchema('receipts.entry.mosaic', { - source: { type: ModelType.object, schemaName: 'receipts.source' }, - resolved: ModelType.uint64HexIdentifier - }); - - // transaction statements - builder.addSchema('receipts.balanceChange', { - version: ModelType.int, - type: ModelType.int, - targetAddress: ModelType.encodedAddress, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64 - }); - - builder.addSchema('receipts.balanceTransfer', { - version: ModelType.int, - type: ModelType.int, - senderAddress: ModelType.encodedAddress, - recipientAddress: ModelType.encodedAddress, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64 - }); - - builder.addSchema('receipts.artifactExpiry', { - version: ModelType.int, - type: ModelType.int, - artifactId: ModelType.uint64HexIdentifier - }); - - builder.addSchema('receipts.inflation', { - version: ModelType.int, - type: ModelType.int, - mosaicId: ModelType.uint64HexIdentifier, - amount: ModelType.uint64 - }); - - builder.addSchema('receipts.unknown', { - version: ModelType.int, - type: ModelType.int - }); - - // receipts source schema - builder.addSchema('receipts.source', { - primaryId: ModelType.int, - secondaryId: ModelType.int - }); - }, - - registerCodecs: () => {} -}; - -module.exports = receiptsPlugin; diff --git a/catapult-sdk/src/plugins/restrictions.js b/catapult-sdk/src/plugins/restrictions.js deleted file mode 100644 index da202d142..000000000 --- a/catapult-sdk/src/plugins/restrictions.js +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/restrictions */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; - -// const accountRestrictionTypeOutgoingOffset = 0x4000; -const accountRestrictionTypeBlockOffset = 0x8000; -const AccountRestrictionTypeFlags = Object.freeze({ - address: 0x0001, - mosaic: 0x0002, - operation: 0x0004 -}); - -const accountRestrictionsCreateBaseCodec = valueCodec => ({ - deserialize: parser => { - const transaction = {}; - transaction.restrictionFlags = parser.uint16(); - const restrictionAdditionsCount = parser.uint8(); - const restrictionDeletionsCount = parser.uint8(); - transaction.accountRestrictionTransactionBody_Reserved1 = parser.uint32(); - - transaction.restrictionAdditions = []; - for (let i = 0; i < restrictionAdditionsCount; ++i) - transaction.restrictionAdditions.push(valueCodec.deserializeValue(parser)); - - transaction.restrictionDeletions = []; - for (let i = 0; i < restrictionDeletionsCount; ++i) - transaction.restrictionDeletions.push(valueCodec.deserializeValue(parser)); - - return transaction; - }, - serialize: (transaction, serializer) => { - serializer.writeUint16(transaction.restrictionFlags); - serializer.writeUint8(transaction.restrictionAdditions.length); - serializer.writeUint8(transaction.restrictionDeletions.length); - serializer.writeUint32(transaction.accountRestrictionTransactionBody_Reserved1); - transaction.restrictionAdditions.forEach(key => { - valueCodec.serializeValue(serializer, key); - }); - transaction.restrictionDeletions.forEach(key => { - valueCodec.serializeValue(serializer, key); - }); - } -}); - -const accountRestrictionTypeDescriptors = [ - { - entityType: EntityType.accountRestrictionAddress, - schemaPrefix: 'address', - valueType: ModelType.binary, - flag: AccountRestrictionTypeFlags.address - }, - { - entityType: EntityType.accountRestrictionMosaic, - schemaPrefix: 'mosaic', - valueType: ModelType.uint64HexIdentifier, - flag: AccountRestrictionTypeFlags.mosaic - }, - { - entityType: EntityType.accountRestrictionOperation, - schemaPrefix: 'operation', - valueType: ModelType.uint16, - flag: AccountRestrictionTypeFlags.operation - } -]; - -/** - * Creates a restrictions plugin. - * @type {module:plugins/CatapultPlugin} - */ -const restrictionsPlugin = { - AccountRestrictionType: Object.freeze({ - addressAllow: AccountRestrictionTypeFlags.address, - addressBlock: AccountRestrictionTypeFlags.address + accountRestrictionTypeBlockOffset, - mosaicAllow: AccountRestrictionTypeFlags.mosaic, - mosaicBlock: AccountRestrictionTypeFlags.mosaic + accountRestrictionTypeBlockOffset, - operationAllow: AccountRestrictionTypeFlags.operation, - operationBlock: AccountRestrictionTypeFlags.operation + accountRestrictionTypeBlockOffset - }), - - registerSchema: builder => { - /** - * Account restrictions scope - */ - accountRestrictionTypeDescriptors.forEach(restrictionTypeDescriptor => { - // transaction schemas - builder.addTransactionSupport(restrictionTypeDescriptor.entityType, { - restrictionFlags: ModelType.uint16, - restrictionAdditions: { type: ModelType.array, schemaName: restrictionTypeDescriptor.valueType }, - restrictionDeletions: { type: ModelType.array, schemaName: restrictionTypeDescriptor.valueType } - }); - - // aggregated account restriction subschemas - builder.addSchema(`accountRestriction.${restrictionTypeDescriptor.schemaPrefix}AccountRestriction`, { - restrictionFlags: ModelType.uint16, - values: { type: ModelType.array, schemaName: restrictionTypeDescriptor.valueType } - }); - }); - - // aggregated account restrictions schemas - builder.addSchema('accountRestrictions', { - accountRestrictions: { type: ModelType.object, schemaName: 'accountRestriction.restrictions' } - }); - builder.addSchema('accountRestriction.restrictions', { - version: ModelType.uint16, - address: ModelType.encodedAddress, - restrictions: { - type: ModelType.array, - schemaName: entity => { - for (let i = 0; i < accountRestrictionTypeDescriptors.length; i++) { - if ((entity.restrictionFlags & 0x3FFF) === accountRestrictionTypeDescriptors[i].flag) - // the following schemas were added in the previous loop - return `accountRestriction.${accountRestrictionTypeDescriptors[i].schemaPrefix}AccountRestriction`; - } - return 'accountRestriction.fallback'; - } - } - }); - builder.addSchema('accountRestriction.fallback', {}); - - /** - * Mosaic restrictions scope - */ - // MosaicAddressRestrictionTransaction transaction schema - builder.addTransactionSupport(EntityType.mosaicRestrictionAddress, { - mosaicId: ModelType.uint64HexIdentifier, - restrictionKey: ModelType.uint64HexIdentifier, - targetAddress: ModelType.encodedAddress, - previousRestrictionValue: ModelType.uint64, - newRestrictionValue: ModelType.uint64 - }); - - // MosaicGlobalRestrictionTransaction transaction schema - builder.addTransactionSupport(EntityType.mosaicRestrictionGlobal, { - mosaicId: ModelType.uint64HexIdentifier, - referenceMosaicId: ModelType.uint64HexIdentifier, - restrictionKey: ModelType.uint64HexIdentifier, - previousRestrictionValue: ModelType.uint64, - newRestrictionValue: ModelType.uint64, - previousRestrictionType: ModelType.uint8, - newRestrictionType: ModelType.uint8 - }); - - // mosaic restriction schemas - builder.addSchema('mosaicRestrictions', { - id: ModelType.objectId, - mosaicRestrictionEntry: { type: ModelType.object, schemaName: 'mosaicRestrictions.entry' } - }); - builder.addSchema('mosaicRestrictions.entry', { - version: ModelType.uint16, - compositeHash: ModelType.binary, - entryType: ModelType.uint32, - mosaicId: ModelType.uint64HexIdentifier, - targetAddress: ModelType.encodedAddress, - restrictions: { type: ModelType.array, schemaName: 'mosaicRestrictions.entry.restrictions' } - }); - builder.addSchema('mosaicRestrictions.entry.restrictions', { - key: ModelType.uint64, - value: ModelType.uint64, - restriction: { type: ModelType.object, schemaName: 'mosaicRestrictions.entry.restrictions.restriction' } - }); - builder.addSchema('mosaicRestrictions.entry.restrictions.restriction', { - referenceMosaicId: ModelType.uint64HexIdentifier, - restrictionValue: ModelType.uint64, - restrictionType: ModelType.uint8 - }); - }, - - registerCodecs: codecBuilder => { - // account restrictions address - codecBuilder.addTransactionSupport( - EntityType.accountRestrictionAddress, - accountRestrictionsCreateBaseCodec({ - deserializeValue: parser => parser.buffer(constants.sizes.addressDecoded), - serializeValue: (serializer, value) => serializer.writeBuffer(value) - }) - ); - - // account restrictions mosaic - codecBuilder.addTransactionSupport( - EntityType.accountRestrictionMosaic, - accountRestrictionsCreateBaseCodec({ - deserializeValue: parser => parser.uint64(), - serializeValue: (serializer, value) => serializer.writeUint64(value) - }) - ); - - // account restrictions operation - codecBuilder.addTransactionSupport( - EntityType.accountRestrictionOperation, - accountRestrictionsCreateBaseCodec({ - deserializeValue: parser => parser.uint16(), - serializeValue: (serializer, value) => serializer.writeUint16(value) - }) - ); - - // mosaic restrictions address - codecBuilder.addTransactionSupport(EntityType.mosaicRestrictionAddress, { - deserialize: parser => { - const transaction = {}; - transaction.mosaicId = parser.uint64(); - transaction.restrictionKey = parser.uint64(); - transaction.previousRestrictionValue = parser.uint64(); - transaction.newRestrictionValue = parser.uint64(); - transaction.targetAddress = parser.buffer(constants.sizes.addressDecoded); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint64(transaction.restrictionKey); - serializer.writeUint64(transaction.previousRestrictionValue); - serializer.writeUint64(transaction.newRestrictionValue); - serializer.writeBuffer(transaction.targetAddress); - } - }); - - // mosaic restrictions global - codecBuilder.addTransactionSupport(EntityType.mosaicRestrictionGlobal, { - deserialize: parser => { - const transaction = {}; - transaction.mosaicId = parser.uint64(); - transaction.referenceMosaicId = parser.uint64(); - transaction.restrictionKey = parser.uint64(); - transaction.previousRestrictionValue = parser.uint64(); - transaction.newRestrictionValue = parser.uint64(); - transaction.previousRestrictionType = parser.uint8(); - transaction.newRestrictionType = parser.uint8(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint64(transaction.mosaicId); - serializer.writeUint64(transaction.referenceMosaicId); - serializer.writeUint64(transaction.restrictionKey); - serializer.writeUint64(transaction.previousRestrictionValue); - serializer.writeUint64(transaction.newRestrictionValue); - serializer.writeUint8(transaction.previousRestrictionType); - serializer.writeUint8(transaction.newRestrictionType); - } - }); - } -}; - -module.exports = restrictionsPlugin; diff --git a/catapult-sdk/src/plugins/transfer.js b/catapult-sdk/src/plugins/transfer.js deleted file mode 100644 index 9ff420011..000000000 --- a/catapult-sdk/src/plugins/transfer.js +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/transfer */ -const EntityType = require('../model/EntityType'); -const ModelType = require('../model/ModelType'); -const sizes = require('../modelBinary/sizes'); - -const constants = { sizes }; - -/** - * Creates a transfer plugin. - * @type {module:plugins/CatapultPlugin} - */ -const transferPlugin = { - registerSchema: builder => { - builder.addTransactionSupport(EntityType.transfer, { - recipientAddress: ModelType.encodedAddress, - message: ModelType.binary, - mosaics: { type: ModelType.array, schemaName: 'mosaic' } - }); - }, - - registerCodecs: codecBuilder => { - codecBuilder.addTransactionSupport(EntityType.transfer, { - deserialize: parser => { - const transaction = {}; - transaction.recipientAddress = parser.buffer(constants.sizes.addressDecoded); - - const messageSize = parser.uint16(); - const numMosaics = parser.uint8(); - - transaction.transferTransactionBody_Reserved1 = parser.uint32(); - transaction.transferTransactionBody_Reserved2 = parser.uint8(); - - if (0 < numMosaics) { - transaction.mosaics = []; - while (transaction.mosaics.length < numMosaics) { - const id = parser.uint64(); - const amount = parser.uint64(); - transaction.mosaics.push({ id, amount }); - } - } - - if (0 < messageSize) - transaction.message = parser.buffer(messageSize); - - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeBuffer(transaction.recipientAddress); - - serializer.writeUint16(transaction.message ? transaction.message.length : 0); - - const numMosaics = transaction.mosaics ? transaction.mosaics.length : 0; - serializer.writeUint8(numMosaics); - - serializer.writeUint32(transaction.transferTransactionBody_Reserved1); - serializer.writeUint8(transaction.transferTransactionBody_Reserved2); - - if (0 < numMosaics) { - transaction.mosaics.forEach(mosaic => { - serializer.writeUint64(mosaic.id); - serializer.writeUint64(mosaic.amount); - }); - } - - if (transaction.message) - serializer.writeBuffer(transaction.message); - } - }); - } -}; - -module.exports = transferPlugin; diff --git a/catapult-sdk/src/serializer/BinarySerializer.js b/catapult-sdk/src/serializer/BinarySerializer.js deleted file mode 100644 index 6765df5a3..000000000 --- a/catapult-sdk/src/serializer/BinarySerializer.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module serializer/BinarySerializer */ - -class BufferContainer { - constructor(size) { - this.buffer = Buffer.alloc(size, 0); - this.offset = 0; - } - - requireBufferSpace(size) { - const bytesLeft = this.buffer.length - this.offset; - if (size > bytesLeft) - throw Error(`insufficient buffer space left (${size} bytes required, ${bytesLeft} bytes available)`); - } - - writeUint8(value) { - this.requireBufferSpace(1); - this.buffer.writeUInt8(value, this.offset); - ++this.offset; - } - - writeUint16(value) { - this.requireBufferSpace(2); - this.buffer.writeUInt16LE(value, this.offset); - this.offset += 2; - } - - writeUint32(value) { - this.requireBufferSpace(4); - this.buffer.writeUInt32LE(value, this.offset); - this.offset += 4; - } - - writeUint64(value) { - this.requireBufferSpace(8); - this.writeUint32(value[0]); - this.writeUint32(value[1]); - } - - writeBuffer(buffer) { - this.requireBufferSpace(buffer.length); - buffer.forEach(byte => { - this.writeUint8(byte); - }); - } -} - -/** - * Provides an interface for writing to a fixed size buffer. - */ -class BinarySerializer { - /** - * Creates a binary serializer. - * @param {numeric} size Size of the underlying fixed size buffer. - */ - constructor(size) { - if (!Number.isInteger(size) || 0 >= size) - throw Error('BinarySerializer constructor needs integer size > 0'); - - this.container = new BufferContainer(size); - } - - /** - * Gets the size of the underlying fixed size buffer. - * @returns {Numeric} Size of the underlying buffer. - */ - bufferSize() { - return this.container.buffer.length; - } - - /** - * Gets the underlying fixed size buffer. - * @returns {Buffer} Underlying buffer. - */ - buffer() { - return this.container.buffer; - } - - /** - * Writes a uint8 to the working buffer. - * @param {numeric} value Value to write. - */ - writeUint8(value) { - this.container.writeUint8(value); - } - - /** - * Writes a uint16 to the working buffer. - * @param {numeric} value Value to write. - */ - writeUint16(value) { - this.container.writeUint16(value); - } - - /** - * Writes a uint32 to the working buffer. - * @param {numeric} value Value to write. - */ - writeUint32(value) { - this.container.writeUint32(value); - } - - /** - * Writes a uint64 to the working buffer. - * @param {numeric} value Value to write. - */ - writeUint64(value) { - this.container.writeUint64(value); - } - - /** - * Writes a buffer of bytes to the working buffer. - * @param {Buffer} buffer Buffer to write. - */ - writeBuffer(buffer) { - this.container.writeBuffer(buffer); - } -} - -module.exports = BinarySerializer; diff --git a/catapult-sdk/src/serializer/SerializedSizeCalculator.js b/catapult-sdk/src/serializer/SerializedSizeCalculator.js deleted file mode 100644 index dbf61b283..000000000 --- a/catapult-sdk/src/serializer/SerializedSizeCalculator.js +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module serializer/SerializedSizeCalculator */ - -/** - * Calculates serialized size using builder pattern. - */ -class SerializedSizeCalculator { - /** - * Creates a serialized size calculator. - */ - constructor() { - this.totalSize = 0; - } - - /** - * Gets the calculated size. - * @returns {numeric} Calculated size. - */ - size() { - return this.totalSize; - } - - /** - * Writes a uint8 to the working buffer. - */ - writeUint8() { - ++this.totalSize; - } - - /** - * Writes a uint16 to the working buffer. - */ - writeUint16() { - this.totalSize += 2; - } - - /** - * Writes a uint32 to the working buffer. - */ - writeUint32() { - this.totalSize += 4; - } - - /** - * Writes a uint64 to the working buffer. - */ - writeUint64() { - this.totalSize += 8; - } - - /** - * Writes a buffer of bytes to the working buffer. - * @param {Buffer} buffer Buffer to write. - */ - writeBuffer(buffer) { - this.totalSize += buffer.length; - } -} - -module.exports = SerializedSizeCalculator; diff --git a/catapult-sdk/src/utils/SchemaType.js b/catapult-sdk/src/utils/SchemaType.js deleted file mode 100644 index 3394ff2a8..000000000 --- a/catapult-sdk/src/utils/SchemaType.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/SchemaType */ - -/** - * Basic schema property types. - * @enum {numeric} - */ -const SchemaType = { - /** Default schema property type. */ - none: 0, - - /** Schema property type indicating an array. */ - array: 1, - - /** Schema property type indicating a dictionary. */ - dictionary: 2, - - /** Schema property type indicating an object. */ - object: 3, - - /** Maximum value in this enumeration. */ - max: 3 -}; - -module.exports = SchemaType; diff --git a/catapult-sdk/src/utils/arrayUtils.js b/catapult-sdk/src/utils/arrayUtils.js deleted file mode 100644 index 331d86a54..000000000 --- a/catapult-sdk/src/utils/arrayUtils.js +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/array */ - -const arrayUtils = { - /** - * Creates a Uint8Array view on top of input. - * @param {ArrayBuffer|Uint8Array} input Input array. - * @returns {Uint8Array} A Uint8Array view on top of input. - */ - uint8View: input => { - if (ArrayBuffer === input.constructor) - return new Uint8Array(input); // note that wrapping an ArrayBuffer in an Uint8Array does not make a copy - if (Uint8Array === input.constructor) - return input; - - throw Error('unsupported type passed to uint8View'); - }, - - /** - * Copies elements from a source array to a destination array. - * @param {Array} dest Destination array. - * @param {Array} src Source array. - * @param {numeric} [numElementsToCopy=undefined] Number of elements to copy. - * @param {numeric} [destOffset=0] First index of the destination to write. - * @param {numeric} [srcOffset=0] First index of the source to read. - */ - copy: (dest, src, numElementsToCopy, destOffset = 0, srcOffset = 0) => { - const length = undefined === numElementsToCopy ? dest.length : numElementsToCopy; - for (let i = 0; i < length; ++i) - dest[destOffset + i] = src[srcOffset + i]; - }, - - /** - * Determines whether or not an array is zero-filled. - * @param {Array} array Array to check. - * @returns {boolean} true if the array is zero-filled, false otherwise. - */ - isZero: array => array.every(value => 0 === value), - - /** - * Deeply checks the equality of two arrays. - * @param {Array} lhs First array to compare. - * @param {Array} rhs Second array to compare. - * @param {numeric} [numElementsToCompare=undefined] Number of elements to compare. - * @returns {boolean} true if all compared elements are equal, false otherwise. - */ - deepEqual: (lhs, rhs, numElementsToCompare) => { - let length = numElementsToCompare; - if (undefined === length) { - if (lhs.length !== rhs.length) - return false; - - ({ length } = lhs); - } - - if (length > lhs.length || length > rhs.length) - return false; - - for (let i = 0; i < length; ++i) { - if (lhs[i] !== rhs[i]) - return false; - } - - return true; - } -}; - -module.exports = arrayUtils; diff --git a/catapult-sdk/src/utils/base32.js b/catapult-sdk/src/utils/base32.js deleted file mode 100644 index aed8aae8a..000000000 --- a/catapult-sdk/src/utils/base32.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/base32 */ -const charMapping = require('./charMapping'); - -const Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; -const Decoded_Block_Size = 5; -const Encoded_Block_Size = 8; - -// region encode - -const encodeBlock = (input, inputOffset, output, outputOffset) => { - output[outputOffset + 0] = Alphabet[input[inputOffset + 0] >> 3]; - output[outputOffset + 1] = Alphabet[((input[inputOffset + 0] & 0x07) << 2) | (input[inputOffset + 1] >> 6)]; - output[outputOffset + 2] = Alphabet[(input[inputOffset + 1] & 0x3E) >> 1]; - output[outputOffset + 3] = Alphabet[((input[inputOffset + 1] & 0x01) << 4) | (input[inputOffset + 2] >> 4)]; - output[outputOffset + 4] = Alphabet[((input[inputOffset + 2] & 0x0F) << 1) | (input[inputOffset + 3] >> 7)]; - output[outputOffset + 5] = Alphabet[(input[inputOffset + 3] & 0x7F) >> 2]; - output[outputOffset + 6] = Alphabet[((input[inputOffset + 3] & 0x03) << 3) | (input[inputOffset + 4] >> 5)]; - output[outputOffset + 7] = Alphabet[input[inputOffset + 4] & 0x1F]; -}; - -// endregion - -// region decode - -const Char_To_Decoded_Char_Map = (() => { - const builder = charMapping.createBuilder(); - builder.addRange('A', 'Z', 0); - builder.addRange('2', '7', 26); - return builder.map; -})(); - -const decodeChar = c => { - const decodedChar = Char_To_Decoded_Char_Map[c]; - if (undefined !== decodedChar) - return decodedChar; - - throw Error(`illegal base32 character ${c}`); -}; - -const decodeBlock = (input, inputOffset, output, outputOffset) => { - const bytes = new Uint8Array(Encoded_Block_Size); - for (let i = 0; i < Encoded_Block_Size; ++i) - bytes[i] = decodeChar(input[inputOffset + i]); - - output[outputOffset + 0] = (bytes[0] << 3) | (bytes[1] >> 2); - output[outputOffset + 1] = ((bytes[1] & 0x03) << 6) | (bytes[2] << 1) | (bytes[3] >> 4); - output[outputOffset + 2] = ((bytes[3] & 0x0F) << 4) | (bytes[4] >> 1); - output[outputOffset + 3] = ((bytes[4] & 0x01) << 7) | (bytes[5] << 2) | (bytes[6] >> 3); - output[outputOffset + 4] = ((bytes[6] & 0x07) << 5) | bytes[7]; -}; - -// endregion - -const base32 = { - /** - * Base32 encodes a binary buffer. - * @param {Uint8Array} data Binary data to encode. - * @returns {string} Base32 encoded string corresponding to the input data. - */ - encode: data => { - if (0 !== data.length % Decoded_Block_Size) - throw Error(`decoded size must be multiple of ${Decoded_Block_Size}`); - - const output = new Array(data.length / Decoded_Block_Size * Encoded_Block_Size); - for (let i = 0; i < data.length / Decoded_Block_Size; ++i) - encodeBlock(data, i * Decoded_Block_Size, output, i * Encoded_Block_Size); - - return output.join(''); - }, - - /** - * Base32 decodes a base32 encoded string. - * @param {string} encoded Base32 encoded string to decode. - * @returns {Uint8Array} Binary data corresponding to the input string. - */ - decode: encoded => { - if (0 !== encoded.length % Encoded_Block_Size) - throw Error(`encoded size must be multiple of ${Encoded_Block_Size}`); - - const output = new Uint8Array(encoded.length / Encoded_Block_Size * Decoded_Block_Size); - for (let i = 0; i < encoded.length / Encoded_Block_Size; ++i) - decodeBlock(encoded, i * Encoded_Block_Size, output, i * Decoded_Block_Size); - - return output; - } -}; - -module.exports = base32; diff --git a/catapult-sdk/src/utils/charMapping.js b/catapult-sdk/src/utils/charMapping.js deleted file mode 100644 index 338b57343..000000000 --- a/catapult-sdk/src/utils/charMapping.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/charMapping */ - -/** - * Builder for building a character map. - * @class CharacterMapBuilder - * - * @property {object} map Character map. - */ - -const charMapping = { - /** - * Creates a builder for building a character map. - * @returns {module:utils/charMapping~CharacterMapBuilder} A character map builder. - */ - createBuilder: () => { - const map = {}; - return { - map, - - /** - * Adds a range mapping to the map. - * @param {string} start Start character. - * @param {string} end End character. - * @param {numeric} base Value corresponding to the start character. - * @memberof module:utils/charMapping~CharacterMapBuilder - * @instance - */ - addRange: (start, end, base) => { - const startCode = start.charCodeAt(0); - const endCode = end.charCodeAt(0); - - for (let code = startCode; code <= endCode; ++code) - map[String.fromCharCode(code)] = code - startCode + base; - } - }; - } -}; - -module.exports = charMapping; diff --git a/catapult-sdk/src/utils/convert.js b/catapult-sdk/src/utils/convert.js deleted file mode 100644 index f2be2a460..000000000 --- a/catapult-sdk/src/utils/convert.js +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const charMapping = require('./charMapping'); - -const Char_To_Nibble_Map = (() => { - const builder = charMapping.createBuilder(); - builder.addRange('0', '9', 0); - builder.addRange('a', 'f', 10); - builder.addRange('A', 'F', 10); - return builder.map; -})(); - -const Char_To_Digit_Map = (() => { - const builder = charMapping.createBuilder(); - builder.addRange('0', '9', 0); - return builder.map; -})(); - -const Nibble_To_Char_Map = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; - -const tryParseByte = (char1, char2) => { - const nibble1 = Char_To_Nibble_Map[char1]; - const nibble2 = Char_To_Nibble_Map[char2]; - return undefined === nibble1 || undefined === nibble2 - ? undefined - : (nibble1 << 4) | nibble2; -}; - -/** @exports utils/convert */ -const convert = { - /** - * Decodes two hex characters into a byte. - * @param {string} char1 First hex digit. - * @param {string} char2 Second hex digit. - * @returns {numeric} Decoded byte. - */ - toByte: (char1, char2) => { - const byte = tryParseByte(char1, char2); - if (undefined === byte) - throw Error(`unrecognized hex char '${char1}${char2}'`); - - return byte; - }, - - /** - * Determines whether or not a string is a hex string. - * @param {string} input String to test. - * @returns {boolean} true if the input is a hex string, false otherwise. - */ - isHexString: input => { - if (0 !== input.length % 2) - return false; - - for (let i = 0; i < input.length; i += 2) { - if (undefined === tryParseByte(input[i], input[i + 1])) - return false; - } - - return true; - }, - - /** - * Converts a hex string to a uint8 array. - * @param {string} input A hex encoded string. - * @returns {Uint8Array} A uint8 array corresponding to the input. - */ - hexToUint8: input => { - if (0 !== input.length % 2) - throw Error(`hex string has unexpected size '${input.length}'`); - - const output = new Uint8Array(input.length / 2); - for (let i = 0; i < input.length; i += 2) - output[i / 2] = convert.toByte(input[i], input[i + 1]); - - return output; - }, - - /** - * Converts a uint8 array to a hex string. - * @param {Uint8Array} input A uint8 array. - * @returns {string} A hex encoded string corresponding to the input. - */ - uint8ToHex: input => { - let s = ''; - input.forEach(byte => { - s += Nibble_To_Char_Map[byte >> 4]; - s += Nibble_To_Char_Map[byte & 0x0F]; - }); - - return s; - }, - - /** - * Tries to parse a string representing an unsigned integer. - * @param {string} str String to parse. - * @returns {numeric} Number represented by the input or undefined. - */ - tryParseUint: str => { - if ('0' === str) - return 0; - - let value = 0; - for (let i = 0; i < str.length; ++i) { - const char = str[i]; - const digit = Char_To_Digit_Map[char]; - if (undefined === digit || (0 === value && 0 === digit)) - return undefined; - - value *= 10; - value += digit; - - if (value > Number.MAX_SAFE_INTEGER) - return undefined; - } - - return value; - }, - - /** - * Converts a uint8 array to a uint32 array. - * @param {Uint8Array} input A uint8 array. - * @returns {Uint32Array} A uint32 array created from the input. - */ - uint8ToUint32: input => new Uint32Array(input.buffer), - - /** - * Converts a uint32 array to a uint8 array. - * @param {Uint32Array} input A uint32 array. - * @returns {Uint8Array} A uint8 array created from the input. - */ - uint32ToUint8: input => new Uint8Array(input.buffer), - - /** Converts an unsigned byte to a signed byte with the same binary representation. - * @param {Numeric} input An unsigned byte. - * @returns {Numeric} A signed byte with the same binary representation as the input. - */ - uint8ToInt8: input => { - if (0xFF < input) - throw Error(`input '${input}' is out of range`); - - return input << 24 >> 24; - }, - - /** Converts a signed byte to an unsigned byte with the same binary representation. - * @param {Numeric} input A signed byte. - * @returns {Numeric} An unsigned byte with the same binary representation as the input. - */ - int8ToUint8: input => { - if (127 < input || -128 > input) - throw Error(`input '${input}' is out of range`); - - return input & 0xFF; - }, - - /** Converts an unsigned 16bits integer to a signed 16bits integer with the same binary representation. - * @param {Numeric} input An unsigned 16bits integer. - * @returns {Numeric} A signed 16bits integer with the same binary representation as the input. - */ - uint16ToInt16: input => { - if (0xFFFF < input) - throw Error(`input '${input}' is out of range`); - - return input << 48 >> 48; - }, - - /** Converts a signed 16bits integer to an unsigned 16bits integer with the same binary representation. - * @param {Numeric} input A signed 16bits integer. - * @returns {Numeric} An unsigned 16bits integer with the same binary representation as the input. - */ - int16ToUint16: input => { - if (32767 < input || -32768 > input) - throw Error(`input '${input}' is out of range`); - - return input & 0xFFFF; - }, - - /** Converts an unsigned 32bits integer to a signed 32bits integer with the same binary representation. - * @param {Numeric} input An unsigned 32bits integer. - * @returns {Numeric} A signed 32bits integer with the same binary representation as the input. - */ - uint32ToInt32: input => { - if (0xFFFFFFFF < input) - throw Error(`input '${input}' is out of range`); - - return input << 96 >> 96; - }, - - /** Converts a signed 32bits integer to an unsigned 32bits integer with the same binary representation. - * @param {Numeric} input A signed 32bits integer. - * @returns {Numeric} An unsigned 32bits integer with the same binary representation as the input. - */ - int32ToUint32: input => { - if (2147483647 < input || -2147483648 > input) - throw Error(`input '${input}' is out of range`); - - return (input & 0xFFFFFFFF) >>> 0; - } -}; - -module.exports = convert; diff --git a/catapult-sdk/src/utils/formattingUtils.js b/catapult-sdk/src/utils/formattingUtils.js deleted file mode 100644 index 4464b536b..000000000 --- a/catapult-sdk/src/utils/formattingUtils.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/formattingUtils */ - -const formattingUtils = { - /** - * Formats all the entities in an array. - * @param {module:utils/schemaFormatter~EntityFormatter} formatter Formatter. - * @param {Array} collection Array. - * @returns {Array} A new array of formatted entities. - */ - formatArray: (formatter, collection) => { - const formattedEntities = []; - collection.forEach(entity => { formattedEntities.push(formatter.format(entity)); }); - return formattedEntities; - }, - - /** - * Formats all the entities in a page. - * @param {module:utils/schemaFormatter~EntityFormatter} formatter Formatter. - * @param {object} collection Page collection containing the `data` array of results, and the `pagination` information object - * @returns {object} A new object of formatted page. - */ - formatPage: (formatter, collection) => { - const formattedEntities = []; - collection.data.forEach(entity => { formattedEntities.push(formatter.format(entity)); }); - return { - data: formattedEntities, - pagination: collection.pagination - }; - } -}; - -module.exports = formattingUtils; diff --git a/catapult-sdk/src/utils/future.js b/catapult-sdk/src/utils/future.js deleted file mode 100644 index 396b2c0e9..000000000 --- a/catapult-sdk/src/utils/future.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/future */ - -const future = { - /** - * Makes a future retryable. - * @param {Function} futureSupplier Function that returns a new instance of the wrapped future. - * @param {Numeric} maxAttempts Maximum number of attempts. - * @param {Function} waitTimeSupplier Function that calculates the amount of time to wait after a failure. - * @returns {Promise} A promise that is resolved when the future succeeds or the maximum number of attempts have failed. - */ - makeRetryable: (futureSupplier, maxAttempts, waitTimeSupplier) => { - let numRemainingAttempts = maxAttempts; - const step = (resolve, reject) => { - --numRemainingAttempts; - futureSupplier() - .then(o => { - resolve(o); - }) - .catch(err => { - if (0 === numRemainingAttempts) { - reject(err); - return; - } - - const waitTime = waitTimeSupplier(maxAttempts - numRemainingAttempts, err); - setTimeout(() => { step(resolve, reject); }, waitTime); - }); - }; - - return new Promise((resolve, reject) => { - step(resolve, reject); - }); - } -}; - -module.exports = future; diff --git a/catapult-sdk/src/utils/objects.js b/catapult-sdk/src/utils/objects.js deleted file mode 100644 index 5822515c4..000000000 --- a/catapult-sdk/src/utils/objects.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -// differentiate between object, array and null even though they all report the same type ('object') -const isObject = object => 'object' === typeof object && !Array.isArray(object) && null !== object; - -const areCompatible = (lhs, rhs) => - typeof lhs === typeof rhs && ((null === lhs) === (null === rhs)) && (Array.isArray(lhs) === Array.isArray(rhs)); - -/** @exports utils/objects */ -const objects = { - /** - * Deeply assigns properties in target from one or more source objects. - * @param {object} target Target object. - * @param {...object} sources Source objects with latter objects having precedence. - * @returns {object} Target object (for chaining). - */ - deepAssign: (target, ...sources) => { - sources.forEach(source => Object.keys(source).forEach(key => { - if (isObject(target[key]) && isObject(source[key])) - objects.deepAssign(target[key], source[key]); - else - target[key] = source[key]; - })); - - return target; - }, - - /** - * Checks an object against a template and ensures that the object does not contain any properties not in the template - * and that all of its properties have the correct types as defined by the template. - * @param {object} template Template. - * @param {object} object Object to check against the template. - */ - checkSchemaAgainstTemplate: (template, object) => { - // object can contain a subset of template properties but cannot contain any that template does not - Object.keys(object).forEach(key => { - if (isObject(template[key]) && isObject(object[key])) { - objects.checkSchemaAgainstTemplate(template[key], object[key]); - } else { - if (undefined === template[key]) - throw new Error(`unknown '${key}' key in config`); - - if (!areCompatible(template[key], object[key])) - throw new Error(`override '${key}' property has wrong type`); - } - }); - } -}; - -module.exports = objects; diff --git a/catapult-sdk/src/utils/schemaFormatter.js b/catapult-sdk/src/utils/schemaFormatter.js deleted file mode 100644 index dd34879fb..000000000 --- a/catapult-sdk/src/utils/schemaFormatter.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/schemaFormatter */ -const SchemaType = require('./SchemaType'); - -// if 'definition' is a number, it is the type -// otherwise, it is an object with an optional type property (default type is undefined) -const getSchemaType = definition => ('number' === typeof definition ? definition : definition.type); - -const getDefinition = (schema, key) => { - const definition = undefined === schema[key] ? {} : schema[key]; - const type = getSchemaType(definition); - - return { - type, - resultKey: definition.resultKey || key, - schemaName: definition.schemaName - }; -}; - -const getSchemaName = (schemaName, entity) => ('function' === typeof schemaName ? schemaName(entity) : schemaName); - -/** - * Formatter for formatting a catapult entity. - * @class EntityFormatter - */ - -/** - * @function format - * @param {object} entity Entity to format. - * @returns {object} Formatted entity. - * @memberof module:utils/schemaFormatter~EntityFormatter - * @instance - */ - -/** @exports utils/schemaFormatter */ -const schemaFormatter = { - /** - * Formats an entity according to a schema and rules. - * @param {object} entity Entity to format. - * @param {object} entitySchema Schema corresponding to the entity. - * @param {object} schemaDictionary A map of schema names to schemas for looking up component schemas. - * @param {object} formattingRules A map for looking up formatting rules given a schema property type. - * @returns {object} Formatted entity. - */ - format: (entity, entitySchema, schemaDictionary, formattingRules) => { - formattingRules[SchemaType.object] = (value, format) => format(value); - formattingRules[SchemaType.dictionary] = (dictionary, format) => { - const result = {}; - Object.keys(dictionary).forEach(key => { - result[key] = format(dictionary[key]); - }); - - return result; - }; - - const result = {}; - Object.keys(entity).forEach(key => { - const valueFormatter = schemaName => ( - 'number' === typeof schemaName // if numeric, interpret as a rule id and format child parts as values - ? formattingRules[schemaName] - : value => schemaFormatter.format(value, schemaDictionary[schemaName], schemaDictionary, formattingRules)); - - const definition = getDefinition(entitySchema, key); - if (definition.type === SchemaType.array) { - result[definition.resultKey] = entity[key].map(arrayElementEntity => { - const schemaName = getSchemaName(definition.schemaName, arrayElementEntity); - return valueFormatter(schemaName)(arrayElementEntity); - }); - } else { - const rule = formattingRules[definition.type]; - // if no rule is found, the field is dropped from the entity - if (rule) { - const schemaName = getSchemaName(definition.schemaName, entity[key]); - result[definition.resultKey] = rule( - entity[key], - valueFormatter(schemaName) - ); - } - } - }); - - return result; - } -}; - -module.exports = schemaFormatter; diff --git a/catapult-sdk/src/utils/uint64.js b/catapult-sdk/src/utils/uint64.js deleted file mode 100644 index 7ca50fc05..000000000 --- a/catapult-sdk/src/utils/uint64.js +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module utils/uint64 */ - -const convert = require('./convert'); -const Long = require('long'); - -const readUint32At = (bytes, i) => (bytes[i] + (bytes[i + 1] << 8) + (bytes[i + 2] << 16) + (bytes[i + 3] << 24)) >>> 0; - -/** - * An exact uint64 representation composed of two 32bit values. - * @typedef {Array} uint64 - * @property {numeric} 0 Low 32bit value. - * @property {numeric} 1 High 32bit value. - */ -const uint64Module = { - /** - * Tries to compact a uint64 into a simple numeric. - * @param {module:utils/uint64~uint64} uint64 A uint64 value. - * @returns {numeric|module:utils/uint64~uint64} - * A numeric if the uint64 is no greater than Number.MAX_SAFE_INTEGER or the original uint64 value otherwise. - */ - compact: uint64 => { - const low = uint64[0]; - const high = uint64[1]; - - // don't compact if the value is >= 2^53 - if (0x00200000 <= high) - return uint64; - - // multiply because javascript bit operations operate on 32bit values - return (high * 0x100000000) + low; - }, - - /** - * Converts a numeric unsigned integer into a uint64. - * @param {Numeric} number Unsigned integer. - * @returns {module:utils/uint64~uint64} Uint64 representation of the input. - */ - fromUint: number => { - const value = [(number & 0xFFFFFFFF) >>> 0, (number / 0x100000000) >>> 0]; - if (0x00200000 <= value[1] || 0 > number || 0 !== (number % 1)) - throw Error(`number cannot be converted to uint '${number}'`); - - return value; - }, - - /** - * Compares two UInt64, returning 1 if a is grater, -1 if b is grater, 0 if they are equals - * @param {module:utils/uint64~uint64} a this object - * @param {module:utils/uint64~uint64} b the other - * @returns {number} - -1, 0, 1 - */ - compare(a, b) { - const long_a = Long.fromBits(a[0], a[1], true); - const long_b = Long.fromBits(b[0], b[1], true); - return long_a.compare(long_b); - }, - - /** - * Converts a (64bit) uint8 array into a uint64. - * @param {Uint8Array} uint8Array A uint8 array. - * @returns {module:utils/uint64~uint64} Uint64 representation of the input. - */ - fromBytes: uint8Array => { - if (8 !== uint8Array.length) - throw Error(`byte array has unexpected size '${uint8Array.length}'`); - - return [readUint32At(uint8Array, 0), readUint32At(uint8Array, 4)]; - }, - - toBytes: uint64 => { - const uint32Array = new Uint32Array(uint64); - return convert.uint32ToUint8(uint32Array); - }, - - /** - * Converts a (32bit) uint8 array into a uint64. - * @param {Uint8Array} uint8Array A uint8 array. - * @returns {module:utils/uint64~uint64} Uint64 representation of the input. - */ - fromBytes32: uint8Array => { - if (4 !== uint8Array.length) - throw Error(`byte array has unexpected size '${uint8Array.length}'`); - - return [readUint32At(uint8Array, 0), 0]; - }, - - /** - * Parses a hex string into a uint64. - * @param {string} input A hex encoded string. - * @returns {module:utils/uint64~uint64} Uint64 representation of the input. - */ - fromHex: input => { - if (16 !== input.length) - throw Error(`hex string has unexpected size '${input.length}'`); - - const uint8Array = convert.hexToUint8(input); - const view = new DataView(uint8Array.buffer); - return [view.getUint32(4), view.getUint32(0)]; - }, - - /** - * Converts a uint64 into a hex string. - * @param {module:utils/uint64~uint64} uint64 A uint64 value. - * @returns {string} A hex encoded string representing the uint64. - */ - toHex: uint64 => { - const uint32Array = new Uint32Array(uint64); - const uint8Array = convert.uint32ToUint8(uint32Array).reverse(); - return convert.uint8ToHex(uint8Array); - }, - - /** - * Returns true if a uint64 is zero. - * @param {module:utils/uint64~uint64} uint64 A uint64 value. - * @returns {boolean} true if the value is zero. - */ - isZero: uint64 => 0 === uint64[0] && 0 === uint64[1], - - /** - * Converts a uint64 into a numeric string. - * @param {module:utils/uint64~uint64} uint64 A uint64 value. - * @returns {string} A numeric string representation of the input. - */ - toString: uint64 => (new Long(uint64[0], uint64[1], true).toString(10)), - - /** - * Converts a numeric string representing an unsigned integer into uint64. - * @param {string} input A string representing the uint64. - * @returns {module:utils/uint64~uint64} A uint64 value. - */ - fromString: input => { - if (!/^\d+$/.test(input) || ('' === input) || (undefined === input) || (null === input)) - throw Error(`input string is not a valid numeric string '${input}'`); - - const inputLong = Long.fromString(input, true, 10); - return ([inputLong.getLowBitsUnsigned(), inputLong.getHighBitsUnsigned()]); - }, - - /** - * Multiplies two uint64 values. - * @param {module:utils/uint64~uint64} multiplier A uint64 value. - * @param {module:utils/uint64~uint64} multiplicand A uint64 value. - * @returns {module:utils/uint64~uint64} A uint64 value. - */ - multiply: (multiplier, multiplicand) => { - const factorA = new Long(multiplier[0], multiplier[1], true); - const factorB = new Long(multiplicand[0], multiplicand[1], true); - - const result = factorA.multiply(factorB); - return ([result.getLowBitsUnsigned(), result.getHighBitsUnsigned()]); - } -}; - -module.exports = uint64Module; diff --git a/catapult-sdk/test/.eslintrc b/catapult-sdk/test/.eslintrc deleted file mode 100644 index a7e146518..000000000 --- a/catapult-sdk/test/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ ---- -env: - mocha: true -rules: - import/no-extraneous-dependencies: - - error - - devDependencies: true diff --git a/catapult-sdk/test/binaryTestUtils.js b/catapult-sdk/test/binaryTestUtils.js deleted file mode 100644 index 9fa64c057..000000000 --- a/catapult-sdk/test/binaryTestUtils.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const test = require('./testUtils'); -const BinaryParser = require('../src/parser/BinaryParser'); -const BinarySerializer = require('../src/serializer/BinarySerializer'); -const { expect } = require('chai'); - -const binaryTestUtils = { - binary: { - assertSerialization(codec, size, object, buffer, txCodecs) { - // Arrange: create a serializer - const serializer = new BinarySerializer(size); - - // Act: - codec.serialize(object, serializer, txCodecs); - - // Assert: - expect(serializer.buffer()).to.deep.equal(buffer); - }, - - assertDeserialization(codec, size, buffer, object, txCodecs) { - // Arrange: create a parser around the buffer - const parser = new BinaryParser(); - parser.push(buffer); - - // Act: - const model = codec.deserialize(parser, size, txCodecs); - - // Assert: - expect(model).to.deep.equal(object); - }, - - assertRoundtrip(codec, size, object, txCodecs, preprocessedHeaderSize) { - // Arrange: serialize an object - const serializer = new BinarySerializer(size); - codec.serialize(object, serializer, txCodecs); - - // Act: deserialize it (the size passed to deserialize should include the preprocessed header size) - const parser = new BinaryParser(); - parser.push(serializer.buffer()); - const model = codec.deserialize(parser, size + preprocessedHeaderSize, txCodecs); - - // Assert: - expect(model).to.deep.equal(object); - }, - - test: { - addAll(codec, size, dataGenerator, txCodecs, preprocessedHeaderSize = 0) { - const { binary } = binaryTestUtils; - - it('can be serialized', () => { - // Arrange: - const data = dataGenerator(); - - // Assert: - binary.assertSerialization(codec, size - preprocessedHeaderSize, data.object, data.buffer, txCodecs); - }); - - it('can be deserialized', () => { - // Arrange: - const data = dataGenerator(); - - // Assert: - binary.assertDeserialization(codec, size, data.buffer, data.object, txCodecs); - }); - - it('can be roundtripped', () => { - // Arrange: - const data = dataGenerator(); - - // Assert: - binary.assertRoundtrip(codec, size - preprocessedHeaderSize, data.object, txCodecs, preprocessedHeaderSize); - }); - } - } - } -}; - -Object.assign(binaryTestUtils, test); - -module.exports = binaryTestUtils; diff --git a/catapult-sdk/test/crypto/keyPair_spec.js b/catapult-sdk/test/crypto/keyPair_spec.js deleted file mode 100644 index 05a0315e5..000000000 --- a/catapult-sdk/test/crypto/keyPair_spec.js +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { createKeyPairFromPrivateKeyString, sign, verify } = require('../../src/crypto/keyPair'); -const convert = require('../../src/utils/convert'); -const test = require('../testUtils'); -const { expect } = require('chai'); - -describe('key pair', () => { - const Private_Key_Size = 32; - const Signature_Size = 64; - - const Private_Keys = [ - 'ABF4CF55A2B3F742D7543D9CC17F50447B969E6E06F5EA9195D428AB12B7318D', - '6AA6DAD25D3ACB3385D5643293133936CDDDD7F7E11818771DB1FF2F9D3F9215', - '8E32BC030A4C53DE782EC75BA7D5E25E64A2A072A56E5170B77A4924EF3C32A9', - 'C83CE30FCB5B81A51BA58FF827CCBC0142D61C13E2ED39E78E876605DA16D8D7', - '2DA2A0AAE0F37235957B51D15843EDDE348A559692D8FA87B94848459899FC27' - ]; - - describe('construction', () => { - it('can extract from private key test vectors', () => { - // Arrange: - const Expected_Public_Keys = [ - '4DB881D07086498C3626F1F84EF89D7E08E5D8293298400F27CA98C92AB2D271', - 'F7BBE3BB4DBF9698122DA02EB8A6EDE55F1EF90D0C64819E8A792231A2A0B143', - '41C7467803C694DC7CB1D11384AD35BF63873E21EC04454E434FE64934942621', - '4CD65AE31B90557EA0F80BCA0748AE1C91C9A1FB53666E8DCCC176774B94E52A', - '37C877158F0BCCEF264475AF113494A0A385CB01CDA2ABCEC93C76A8EFC537A8' - ]; - - // Sanity: - expect(Private_Keys.length).equal(Expected_Public_Keys.length); - - for (let i = 0; i < Private_Keys.length; ++i) { - // Arrange: - const privateKeyHex = Private_Keys[i]; - const expectedPublicKey = Expected_Public_Keys[i]; - - // Act: - const keyPair = createKeyPairFromPrivateKeyString(privateKeyHex); - - // Assert: - const message = ` from ${privateKeyHex}`; - expect(convert.uint8ToHex(keyPair.publicKey), `public ${message}`).equal(expectedPublicKey); - expect(convert.uint8ToHex(keyPair.privateKey), `private ${message}`).equal(privateKeyHex); - } - }); - - it('cannot extract from invalid private key', () => { - // Arrange: - const invalidPrivateKeys = [ - '', // empty - '53C659B47C176A70EB228DE5C0A0FF391282C96640C2A42CD5BBD0982176AB', // short - '53C659B47C176A70EB228DE5C0A0FF391282C96640C2A42CD5BBD0982176AB1BBB' // long - ]; - - // Act: - invalidPrivateKeys.forEach(privateKey => { - // Assert: - expect(() => { createKeyPairFromPrivateKeyString(privateKey); }, `from ${privateKey}`) - .to.throw('private key has unexpected size'); - }); - }); - }); - - describe('sign', () => { - it('fills the signature', () => { - // Arrange: - const keyPair = test.random.keyPair(); - const payload = test.random.bytes(100); - - // Act: - const signature = sign(keyPair, payload); - - // Assert: - expect(signature).to.not.deep.equal(new Uint8Array(Signature_Size)); - }); - - it('returns same signature for same data signed by same key pairs', () => { - // Arrange: - const privateKey = convert.uint8ToHex(test.random.bytes(Private_Key_Size)); - const keyPair1 = createKeyPairFromPrivateKeyString(privateKey); - const keyPair2 = createKeyPairFromPrivateKeyString(privateKey); - const payload = test.random.bytes(100); - - // Act: - const signature1 = sign(keyPair1, payload); - const signature2 = sign(keyPair2, payload); - - // Assert: - expect(signature2).to.deep.equal(signature1); - }); - - it('returns different signature for same data signed by different key pairs', () => { - // Arrange: - const keyPair1 = test.random.keyPair(); - const keyPair2 = test.random.keyPair(); - const payload = test.random.bytes(100); - - // Act: - const signature1 = sign(keyPair1, payload); - const signature2 = sign(keyPair2, payload); - - // Assert: - expect(signature2).to.not.deep.equal(signature1); - }); - - it('cannot sign unsupported data type', () => { - // Arrange: - const keyPair = createKeyPairFromPrivateKeyString(Private_Keys[0]); - - // Assert: - expect(() => { sign(keyPair, {}); }).to.throw('unexpected type, use Uint8Array'); - }); - }); - - describe('verify', () => { - it('returns true for data signed with same key pair', () => { - // Arrange: - const keyPair = test.random.keyPair(); - const payload = test.random.bytes(100); - const signature = sign(keyPair, payload); - - // Act: - const isVerified = verify(keyPair.publicKey, payload, signature); - - // Assert: - expect(isVerified).to.equal(true); - }); - - it('returns false for data signed with different key pair', () => { - // Arrange: - const keyPair1 = test.random.keyPair(); - const keyPair2 = test.random.keyPair(); - const payload = test.random.bytes(100); - const signature = sign(keyPair1, payload); - - // Act: - const isVerified = verify(keyPair2.publicKey, payload, signature); - - // Assert: - expect(isVerified).to.equal(false); - }); - - it('returns false if signature has been modified', () => { - // Arrange: - const keyPair = test.random.keyPair(); - const payload = test.random.bytes(100); - - for (let i = 0; i < Signature_Size; i += 4) { - const signature = sign(keyPair, payload); - signature[i] ^= 0xFF; - - // Act: - const isVerified = verify(keyPair.publicKey, payload, signature); - - // Assert: - expect(isVerified, `signature modified at ${i}`).to.equal(false); - } - }); - - it('returns false if payload has been modified', () => { - // Arrange: - const keyPair = test.random.keyPair(); - const payload = test.random.bytes(44); - - for (let i = 0; i < payload.length; i += 4) { - const signature = sign(keyPair, payload); - payload[i] ^= 0xFF; - - // Act: - const isVerified = verify(keyPair.publicKey, payload, signature); - - // Assert: - expect(isVerified, `payload modified at ${i}`).to.equal(false); - } - }); - - it('fails if public key is not on curve', () => { - // Arrange: - const keyPair = test.random.keyPair(); - keyPair.publicKey.fill(0); - keyPair.publicKey[keyPair.publicKey.length - 1] = 1; - - const payload = test.random.bytes(100); - const signature = sign(keyPair, payload); - - // Act: - const isVerified = verify(keyPair.publicKey, payload, signature); - - // Assert: - expect(isVerified).to.equal(false); - }); - - it('fails if public key does not correspond to private key', () => { - // Arrange: - const keyPair = test.random.keyPair(); - const payload = test.random.bytes(100); - const signature = sign(keyPair, payload); - - for (let i = 0; i < keyPair.publicKey.length; ++i) - keyPair.publicKey[i] ^= 0xFF; - - // Act: - const isVerified = verify(keyPair.publicKey, payload, signature); - - // Assert: - expect(isVerified).to.equal(false); - }); - - it('rejects zero public key', () => { - // Arrange: - const keyPair = test.random.keyPair(); - keyPair.publicKey.fill(0); - - const payload = test.random.bytes(100); - const signature = sign(keyPair, payload); - - // Act: - const isVerified = verify(keyPair.publicKey, payload, signature); - - // Assert: - expect(isVerified).to.equal(false); - }); - - it('cannot verify non canonical signature', () => { - const scalarAddGroupOrder = scalar => { - // 2^252 + 27742317777372353535851937790883648493, little endian - const Group_Order = [ - 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 - ]; - - let r = 0; - for (let i = 0; i < scalar.length; ++i) { - const t = scalar[i] + Group_Order[i]; - scalar[i] += Group_Order[i] + r; - r = (t >> 8) & 0xFF; - } - }; - - // Arrange: - const keyPair = test.random.keyPair(); - const payload = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); - const canonicalSignature = sign(keyPair, payload); - - // this is signature with group order added to 'encodedS' part of signature - const nonCanonicalSignature = canonicalSignature.slice(); - scalarAddGroupOrder(nonCanonicalSignature.subarray(32)); - - // Act: - const isCanonicalVerified = verify(keyPair.publicKey, payload, canonicalSignature); - const isNonCanonicalVerified = verify(keyPair.privateKey, payload, nonCanonicalSignature); - - // Assert: - expect(isCanonicalVerified).to.equal(true); - expect(isNonCanonicalVerified).to.equal(false); - }); - }); - - describe('test vectors', () => { - const Input_Data = [ - '8ce03cd60514233b86789729102ea09e867fc6d964dea8c2018ef7d0a2e0e24bf7e348e917116690b9', - 'e4a92208a6fc52282b620699191ee6fb9cf04daf48b48fd542c5e43daa9897763a199aaa4b6f10546109f47ac3564fade0', - '13ed795344c4448a3b256f23665336645a853c5c44dbff6db1b9224b5303b6447fbf8240a2249c55', - 'a2704638434e9f7340f22d08019c4c8e3dbee0df8dd4454a1d70844de11694f4c8ca67fdcb08fed0cec9abb2112b5e5f89', - 'd2488e854dbcdfdb2c9d16c8c0b2fdbc0abb6bac991bfe2b14d359a6bc99d66c00fd60d731ae06d0' - ]; - - const Expected_Signatures = [ - /* eslint-disable max-len */ - '31D272F0662915CAC43AB7D721CAF65D8601F52B2E793EA1533E7BC20E04EA97B74859D9209A7B18DFECFD2C4A42D6957628F5357E3FB8B87CF6A888BAB4280E', - 'F21E4BE0A914C0C023F724E1EAB9071A3743887BB8824CB170404475873A827B301464261E93700725E8D4427A3E39D365AFB2C9191F75D33C6BE55896E0CC00', - '939CD8932093571E24B21EA53F1359279BA5CFC32CE99BB020E676CF82B0AA1DD4BC76FCDE41EF784C06D122B3D018135352C057F079C926B3EFFA7E73CF1D06', - '9B4AFBB7B96CAD7726389C2A4F31115940E6EEE3EA29B3293C82EC8C03B9555C183ED1C55CA89A58C17729EFBA76A505C79AA40EC618D83124BC1134B887D305', - '7AF2F0D9B30DE3B6C40605FDD4EBA93ECE39FA7458B300D538EC8D0ABAC1756DEFC0CA84C8A599954313E58CE36EFBA4C24A82FD6BB8127023A58EFC52A8410A' - /* eslint-enable max-len */ - ]; - - it('can sign test vectors as binary', () => { - // Sanity: - expect(Private_Keys.length).equal(Input_Data.length); - expect(Private_Keys.length).equal(Expected_Signatures.length); - - for (let i = 0; i < Private_Keys.length; ++i) { - // Arrange: - const inputData = convert.hexToUint8(Input_Data[i]); - const keyPair = createKeyPairFromPrivateKeyString(Private_Keys[i]); - - // Act: - const signature = sign(keyPair, inputData); - - // Assert: - const message = `signing with ${Private_Keys[i]}`; - expect(convert.uint8ToHex(signature), message).equal(Expected_Signatures[i]); - } - }); - - it('can verify test vectors as binary', () => { - // Sanity: - expect(Private_Keys.length).equal(Input_Data.length); - expect(Private_Keys.length).equal(Expected_Signatures.length); - - for (let i = 0; i < Private_Keys.length; ++i) { - // Arrange: - const inputData = convert.hexToUint8(Input_Data[i]); - const keyPair = createKeyPairFromPrivateKeyString(Private_Keys[i]); - const signature = sign(keyPair, inputData); - - // Act: - const isVerified = verify(keyPair.publicKey, inputData, signature); - - // Assert: - const message = `verifying with ${Private_Keys[i]}`; - expect(isVerified, message).equal(true); - } - }); - }); -}); diff --git a/catapult-sdk/test/crypto/merkleAuditProof_spec.js b/catapult-sdk/test/crypto/merkleAuditProof_spec.js deleted file mode 100644 index 2f1bec75c..000000000 --- a/catapult-sdk/test/crypto/merkleAuditProof_spec.js +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { - indexOfLeafWithHash, buildAuditPath, NodePosition, siblingOf, HashNotFoundError, - InvalidTree, evenify -} = require('../../src/crypto/merkleAuditProof'); -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); - -const hexStringToBuffer = input => Buffer.from(convert.hexToUint8(input), 'hex'); - -const merkleTree = { - count: 4, - nodes: [ - hexStringToBuffer('8D25B2639A7D12FEAAAEF34358B215E97533F9FFDDA5B9FADFD8ECC229695263'), - hexStringToBuffer('8AB2F19A47C5B30CC389AE1580F0472B4D3AFEEA83CDF0F707D03ED76B15A00C'), - hexStringToBuffer('B9840C4EADB6724A2DFCA81D5E90EF3F4EE91BEB63A58FA91A4F05E951F08FCF'), - hexStringToBuffer('B9840C4EADB6724A2DFCA81D5E90EF3F4EE91BEB63A58FA91A4F05E951F08FCF'), - hexStringToBuffer('586B203612B0E5CA695CFF677A5B784E4368B79C1A7B272036105753A915EDC9'), - hexStringToBuffer('AA1DFFF01B3ABA492188195DF4D77AF25FF9D57DF4EA0FD6FE498D572B6E67FD'), - hexStringToBuffer('16D28DD7AF87B86C79273450470E96F22C66F8EF4598064603699B69F10464D0') - ] -}; - -const merkleTreeLong = { - count: 6, - nodes: [ - hexStringToBuffer('A983745F69959AF438C5B59501B7B6FCD4312DE1F5252A6E8B54D09E23266A7C'), - hexStringToBuffer('5A639C5865FFA3331C3315BE2797F490D7D9C12826AF08C3643929DCAC391E21'), - hexStringToBuffer('F95D66CCB9B788A582FB35ABB4328BD705E2DB97D3F2EFAED46C88584A87E202'), - hexStringToBuffer('C11A995692E24FE9A79B657375AA051D97B5261C14A2F08792AE5269F412BD8F'), - hexStringToBuffer('0CDD981B532DDB0789A3B7F96B37FA0973EE6EB1D41FA8AA8E0411BA2FB07851'), - hexStringToBuffer('C7F87E9FC96202ECE5F219EA87A2C02363B763520A1D7B08F0D2037FFF7CC1E0'), - hexStringToBuffer('5EEEF952CE75555C24C4820E7BE36370B0AD9ABFE357D4244AC1DA1E1102229A'), - hexStringToBuffer('EFAE07E3096428E93611072581F769F12758345BEE2779A3B20326F8A1A6C373'), - hexStringToBuffer('DF646700D4CDBA8DF803EE27F0E8DE59A32AD95E74803C342431F1234E9D054C'), - hexStringToBuffer('DF646700D4CDBA8DF803EE27F0E8DE59A32AD95E74803C342431F1234E9D054C'), - hexStringToBuffer('9ED4FE218563EE52D2AE18CAFD9CD12A403EAD9737EFC1B8AADD892A87699AB5'), - hexStringToBuffer('11E903589FAE58D8DDB460F11F33A80A9B2CF09D4B50FCC615C5440337CEBE4F'), - hexStringToBuffer('F1BDD998E8C54C8B71CEC7B9AAC14E3A0B93F2EC93E445542885F29DA5375787') - ] -}; - -describe('evenify', () => { - it('should return the valid even number', () => { - expect(evenify(0)).to.equal(0); - expect(evenify(1)).to.equal(2); - expect(evenify(2)).to.equal(2); - expect(evenify(3)).to.equal(4); - expect(evenify(13)).to.equal(14); - expect(evenify(14)).to.equal(14); - }); -}); - -describe('indexOfLeafWithHash', () => { - it('should return -1 if hash not found in tree', () => { - expect(indexOfLeafWithHash(hexStringToBuffer('9ED4FE218563EE52D2AE18CAFD9CD12A403EAD9737EFC1B8AADD892A00000000'), merkleTree)) - .to.equal(-1); - }); - - it('should return -1 if hash not found in tree leaves', () => { - expect(indexOfLeafWithHash(merkleTree.nodes[4], merkleTree)).to.equal(-1); - }); - - it('should return -1 if hash not found in an empty tree', () => { - expect(indexOfLeafWithHash( - hexStringToBuffer('9ED4FE218563EE52D2AE18CAFD9CD12A403EAD9737EFC1B8AADD892A00000000'), - { nodes: [], count: 0 } - )).to.equal(-1); - }); - - it('should return the transaction found for a single node tree', () => { - const hash = hexStringToBuffer('9ED4FE218563EE52D2AE18CAFD9CD12A403EAD9737EFC1B8AADD892A00000000'); - expect(indexOfLeafWithHash( - hash, - { nodes: [hash], count: 1 } - )).to.equal(0); - }); - - it('should return the index for a found node', () => { - expect(indexOfLeafWithHash(merkleTree.nodes[2], merkleTree)).to.equal(2); - }); - - it('should return the index for a found node in the first leaf', () => { - expect(indexOfLeafWithHash(merkleTree.nodes[0], merkleTree)).to.equal(0); - }); - - it('should return the index for a found duplicated node in the last leaf out of the number of transactions', () => { - // Arrange: - const merkleTree2 = { - count: 3, - nodes: [ - hexStringToBuffer('8D25B2639A7D12FEAAAEF34358B215E97533F9FFDDA5B9FADFD8ECC229695263'), - hexStringToBuffer('8AB2F19A47C5B30CC389AE1580F0472B4D3AFEEA83CDF0F707D03ED76B15A00C'), - hexStringToBuffer('B9840C4EADB6724A2DFCA81D5E90EF3F4EE91BEB63A58FA91A4F05E951F08FCF'), - hexStringToBuffer('B9840C4EADB6724A2DFCA81D5E90EF3F4EE91BEB63A58FA91A4F05E951F08FCF'), - hexStringToBuffer('586B203612B0E5CA695CFF677A5B784E4368B79C1A7B272036105753A915EDC9'), - hexStringToBuffer('AA1DFFF01B3ABA492188195DF4D77AF25FF9D57DF4EA0FD6FE498D572B6E67FD'), - hexStringToBuffer('16D28DD7AF87B86C79273450470E96F22C66F8EF4598064603699B69F10464D0') - ] - }; - - // Assert: - expect(indexOfLeafWithHash(merkleTree2.nodes[2], merkleTree2)).to.equal(2); - }); -}); - -describe('siblingOf', () => { - it('should return valid value if first index', () => { - expect(siblingOf(0).index).to.equal(1); - }); - - it('should return valid values on different tree levels', () => { - expect(siblingOf(1)).to.deep.equal({ position: NodePosition.left, index: 0 }); - expect(siblingOf(2)).to.deep.equal({ position: NodePosition.right, index: 3 }); - expect(siblingOf(13)).to.deep.equal({ position: NodePosition.left, index: 12 }); - expect(siblingOf(14)).to.deep.equal({ position: NodePosition.right, index: 15 }); - }); -}); - -describe('buildAuditPath', () => { - it('should return an empty audit proof trail for a single node tree', () => { - const trail = buildAuditPath(merkleTree.nodes[0], { nodes: [merkleTree.nodes[0]], count: 1 }); - expect(trail.length).to.equal(0); - }); - - it('should throw if hash not in tree', () => { - expect(() => buildAuditPath(hexStringToBuffer('000903589FAE58D8DDB460F11F33A80A9B2CF09D4B50FCC615C5440337CEBE4F'), merkleTree)) - .to.throw(HashNotFoundError); - }); - - it('should throw if tree is empty', () => { - expect(() => buildAuditPath( - hexStringToBuffer('000903589FAE58D8DDB460F11F33A80A9B2CF09D4B50FCC615C5440337CEBE4F'), - { nodes: [], count: 0 } - )).to.throw(InvalidTree); - }); - - it('should throw if hash in tree but not leaf', () => { - expect(() => buildAuditPath( - merkleTree.nodes[4], - merkleTree - )).to.throw(HashNotFoundError); - expect(() => buildAuditPath( - merkleTree.nodes[6], - merkleTree - )).to.throw(HashNotFoundError); - }); - - it('should return correctly if number of transactions is not even', () => { - // Arrange: - const merkleTree2 = { - count: 3, - nodes: [ - hexStringToBuffer('8D25B2639A7D12FEAAAEF34358B215E97533F9FFDDA5B9FADFD8ECC229695263'), - hexStringToBuffer('8AB2F19A47C5B30CC389AE1580F0472B4D3AFEEA83CDF0F707D03ED76B15A00C'), - hexStringToBuffer('B9840C4EADB6724A2DFCA81D5E90EF3F4EE91BEB63A58FA91A4F05E951F08FCF'), - hexStringToBuffer('B9840C4EADB6724A2DFCA81D5E90EF3F4EE91BEB63A58FA91A4F05E951F08FCF'), - hexStringToBuffer('586B203612B0E5CA695CFF677A5B784E4368B79C1A7B272036105753A915EDC9'), - hexStringToBuffer('AA1DFFF01B3ABA492188195DF4D77AF25FF9D57DF4EA0FD6FE498D572B6E67FD'), - hexStringToBuffer('16D28DD7AF87B86C79273450470E96F22C66F8EF4598064603699B69F10464D0') - ] - }; - - // Assert: - const trail0 = buildAuditPath(merkleTree2.nodes[0], merkleTree2); - expect(trail0).to.deep.equal([ - { hash: merkleTree2.nodes[1], position: NodePosition.right }, - { hash: merkleTree2.nodes[5], position: NodePosition.right } - ]); - - const trail1 = buildAuditPath(merkleTree2.nodes[1], merkleTree2); - expect(trail1).to.deep.equal([ - { hash: merkleTree2.nodes[0], position: NodePosition.left }, - { hash: merkleTree2.nodes[5], position: NodePosition.right } - ]); - - const trail2 = buildAuditPath(merkleTree2.nodes[2], merkleTree2); - expect(trail2).to.deep.equal([ - { hash: merkleTree2.nodes[3], position: NodePosition.right }, - { hash: merkleTree2.nodes[4], position: NodePosition.left } - ]); - }); - - it('should return correctly if number of transactions is even', () => { - const trail0 = buildAuditPath(merkleTree.nodes[0], merkleTree); - expect(trail0).to.deep.equal([ - { hash: merkleTree.nodes[1], position: NodePosition.right }, - { hash: merkleTree.nodes[5], position: NodePosition.right } - ]); - - const trail1 = buildAuditPath(merkleTree.nodes[1], merkleTree); - expect(trail1).to.deep.equal([ - { hash: merkleTree.nodes[0], position: NodePosition.left }, - { hash: merkleTree.nodes[5], position: NodePosition.right } - ]); - - const trail2 = buildAuditPath(merkleTree.nodes[2], merkleTree); - expect(trail2).to.deep.equal([ - { hash: merkleTree.nodes[3], position: NodePosition.right }, - { hash: merkleTree.nodes[4], position: NodePosition.left } - ]); - - const trail3 = buildAuditPath(merkleTree.nodes[3], merkleTree); - expect(trail3).to.deep.equal([ - { hash: merkleTree.nodes[2], position: NodePosition.right }, - { hash: merkleTree.nodes[4], position: NodePosition.left } - ]); - }); - - it('should return correctly if number of transactions is even on a four-level tree', () => { - const trail0 = buildAuditPath(merkleTreeLong.nodes[0], merkleTreeLong); - expect(trail0).to.deep.equal([ - { hash: merkleTreeLong.nodes[1], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[7], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[11], position: NodePosition.right } - ]); - - const trail1 = buildAuditPath(merkleTreeLong.nodes[1], merkleTreeLong); - expect(trail1).to.deep.equal([ - { hash: merkleTreeLong.nodes[0], position: NodePosition.left }, - { hash: merkleTreeLong.nodes[7], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[11], position: NodePosition.right } - ]); - - const trail2 = buildAuditPath(merkleTreeLong.nodes[2], merkleTreeLong); - expect(trail2).to.deep.equal([ - { hash: merkleTreeLong.nodes[3], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[6], position: NodePosition.left }, - { hash: merkleTreeLong.nodes[11], position: NodePosition.right } - ]); - - const trail3 = buildAuditPath(merkleTreeLong.nodes[3], merkleTreeLong); - expect(trail3).to.deep.equal([ - { hash: merkleTreeLong.nodes[2], position: NodePosition.left }, - { hash: merkleTreeLong.nodes[6], position: NodePosition.left }, - { hash: merkleTreeLong.nodes[11], position: NodePosition.right } - ]); - - const trail4 = buildAuditPath(merkleTreeLong.nodes[4], merkleTreeLong); - expect(trail4).to.deep.equal([ - { hash: merkleTreeLong.nodes[5], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[9], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[10], position: NodePosition.left } - ]); - - const trail5 = buildAuditPath(merkleTreeLong.nodes[5], merkleTreeLong); - expect(trail5).to.deep.equal([ - { hash: merkleTreeLong.nodes[4], position: NodePosition.left }, - { hash: merkleTreeLong.nodes[9], position: NodePosition.right }, - { hash: merkleTreeLong.nodes[10], position: NodePosition.left } - ]); - }); -}); - -describe('NodePosition', () => { - it('should be 1 for Left value', () => { - expect(NodePosition.left).to.equal('left'); - }); - - it('should be 2 for Right value', () => { - expect(NodePosition.right).to.equal('right'); - }); -}); diff --git a/catapult-sdk/test/crypto/sha3Hasher_spec.js b/catapult-sdk/test/crypto/sha3Hasher_spec.js deleted file mode 100644 index c8148ed4c..000000000 --- a/catapult-sdk/test/crypto/sha3Hasher_spec.js +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const sha3Hasher = require('../../src/crypto/sha3Hasher'); -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); -const jsSha3 = require('js-sha3'); - -describe('hasher', () => { - const inputs = [ - '', - 'CC', - '41FB', - '1F877C', - 'C1ECFDFC', - '9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10' - ]; - - const addSha3Tests = (length, expectedOutputs) => { - describe('func', () => { - it('can hash test vectors', () => { - // Sanity: - expect(expectedOutputs.length).equal(inputs.length); - - for (let i = 0; i < inputs.length; ++i) { - // Arrange: - const inputHex = inputs[i]; - const inputBuffer = convert.hexToUint8(inputHex); - const expectedHash = expectedOutputs[i]; - - // Act: - const hash = new Uint8Array(length); - sha3Hasher.func(hash, inputBuffer, length); - - // Assert: - expect(convert.uint8ToHex(hash), `hashing ${inputHex}`).equal(expectedHash); - } - }); - }); - - describe('getHasher', () => { - it('returns hasher depending on size param', () => { - // Assert: - expect(sha3Hasher.getHasher(32)).to.equal(jsSha3.sha3_256); - expect(sha3Hasher.getHasher(64)).to.equal(jsSha3.sha3_512); - }); - - it('takes a default size param', () => { - // Assert: - expect(sha3Hasher.getHasher()).to.equal(jsSha3.sha3_512); - }); - }); - - describe('object', () => { - it('can hash test vectors', () => { - // Sanity: - expect(expectedOutputs.length).equal(inputs.length); - - for (let i = 0; i < inputs.length; ++i) { - // Arrange: - const inputHex = inputs[i]; - const inputBuffer = convert.hexToUint8(inputHex); - const expectedHash = expectedOutputs[i]; - - const hasher = sha3Hasher.createHasher(length); - hasher.reset(); - - // Act: hash the input in two parts - hasher.update(inputBuffer.subarray(0, inputBuffer.length / 2)); - hasher.update(inputBuffer.subarray(inputBuffer.length / 2)); - - const hash = new Uint8Array(length); - hasher.finalize(hash); - - // Assert: - expect(convert.uint8ToHex(hash), `hashing ${inputHex}`).equal(expectedHash); - } - }); - - it('can hash string', () => { - // Arrange: - const inputHex = inputs[3]; - const expectedHash = expectedOutputs[3]; - - const hasher = sha3Hasher.createHasher(length); - hasher.reset(); - - // Act: - hasher.update(inputHex); - - const hash = new Uint8Array(length); - hasher.finalize(hash); - - // Assert: - expect(convert.uint8ToHex(hash), `hashing ${inputHex}`).equal(expectedHash); - }); - - it('cannot hash unsupported data type', () => { - // Arrange: - const hasher = sha3Hasher.createHasher(length); - hasher.reset(); - - // Act: - expect(() => hasher.update({})).to.throw('unsupported data type'); - }); - - it('can reuse after reset', () => { - // Arrange: - const inputHex = inputs[3]; - const expectedHash = expectedOutputs[3]; - - const hasher = sha3Hasher.createHasher(length); - hasher.reset(); - hasher.update('ABCD'); - - // Act: - hasher.reset(); - hasher.update(inputHex); - - const hash = new Uint8Array(length); - hasher.finalize(hash); - - // Assert: - expect(convert.uint8ToHex(hash), `hashing ${inputHex}`).equal(expectedHash); - }); - }); - }; - - describe('sha3 256', () => { - // https://github.com/gvanas/KeccakCodePackage/blob/master/TestVectors/ShortMsgKAT_SHA3-256.txt - addSha3Tests(32, [ - 'A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A', - '677035391CD3701293D385F037BA32796252BB7CE180B00B582DD9B20AAAD7F0', - '39F31B6E653DFCD9CAED2602FD87F61B6254F581312FB6EEEC4D7148FA2E72AA', - 'BC22345E4BD3F792A341CF18AC0789F1C9C966712A501B19D1B6632CCD408EC5', - 'C5859BE82560CC8789133F7C834A6EE628E351E504E601E8059A0667FF62C124', - '2F1A5F7159E34EA19CDDC70EBF9B81F1A66DB40615D7EAD3CC1F1B954D82A3AF' - ]); - }); - - describe('sha3 512', () => { - // https://github.com/gvanas/KeccakCodePackage/blob/master/TestVectors/ShortMsgKAT_SHA3-512.txt - addSha3Tests(64, [ - /* eslint-disable max-len */ - 'A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A615B2123AF1F5F94C11E3E9402C3AC558F500199D95B6D3E301758586281DCD26', - '3939FCC8B57B63612542DA31A834E5DCC36E2EE0F652AC72E02624FA2E5ADEECC7DD6BB3580224B4D6138706FC6E80597B528051230B00621CC2B22999EAA205', - 'AA092865A40694D91754DBC767B5202C546E226877147A95CB8B4C8F8709FE8CD6905256B089DA37896EA5CA19D2CD9AB94C7192FC39F7CD4D598975A3013C69', - 'CB20DCF54955F8091111688BECCEF48C1A2F0D0608C3A575163751F002DB30F40F2F671834B22D208591CFAF1F5ECFE43C49863A53B3225BDFD7C6591BA7658B', - 'D4B4BDFEF56B821D36F4F70AB0D231B8D0C9134638FD54C46309D14FADA92A2840186EED5415AD7CF3969BDFBF2DAF8CCA76ABFE549BE6578C6F4143617A4F1A', - 'B087C90421AEBF87911647DE9D465CBDA166B672EC47CCD4054A7135A1EF885E7903B52C3F2C3FE722B1C169297A91B82428956A02C631A2240F12162C7BC726' - /* eslint-enable max-len */ - ]); - }); -}); diff --git a/catapult-sdk/test/model/EntityType_spec.js b/catapult-sdk/test/model/EntityType_spec.js deleted file mode 100644 index 070f8585d..000000000 --- a/catapult-sdk/test/model/EntityType_spec.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const { expect } = require('chai'); - -describe('entity type enumeration', () => { - it('exposes expected types', () => { - // Assert: - expect(EntityType).to.deep.equal({ - transfer: 0x4154, - registerNamespace: 0x414E, - aliasAddress: 0x424E, - aliasMosaic: 0x434E, - mosaicDefinition: 0x414D, - mosaicSupplyChange: 0x424D, - mosaicSupplyRevocation: 0x434d, - modifyMultisigAccount: 0x4155, - aggregateComplete: 0x4141, - aggregateBonded: 0x4241, - hashLock: 0x4148, - secretLock: 0x4152, - secretProof: 0x4252, - accountRestrictionAddress: 0x4150, - accountRestrictionMosaic: 0x4250, - accountRestrictionOperation: 0x4350, - mosaicRestrictionAddress: 0x4251, - mosaicRestrictionGlobal: 0x4151, - accountLink: 0x414C, - nodeKeyLink: 0x424C, - votingKeyLink: 0x4143, - vrfKeyLink: 0x4243, - accountMetadata: 0x4144, - mosaicMetadata: 0x4244, - namespaceMetadata: 0x4344 - }); - }); - - it('exposed values are unique', () => { - // Act: - const reverseMapping = Object.keys(EntityType).reduce((state, name) => { - state[EntityType[name]] = name; - return state; - }, {}); - - // Assert: - expect(Object.keys(EntityType).length).to.equal(Object.keys(reverseMapping).length); - }); -}); diff --git a/catapult-sdk/test/model/ModelFormatterBuilder_spec.js b/catapult-sdk/test/model/ModelFormatterBuilder_spec.js deleted file mode 100644 index 9b4ee703b..000000000 --- a/catapult-sdk/test/model/ModelFormatterBuilder_spec.js +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const ModelFormatterBuilder = require('../../src/model/ModelFormatterBuilder'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const ModelType = require('../../src/model/ModelType'); -const { expect } = require('chai'); - -const modelSchema = new ModelSchemaBuilder().build(); -const formattingRules = { - [ModelType.none]: () => 'none', - [ModelType.binary]: () => 'binary', - [ModelType.uint8]: () => 'uint8', - [ModelType.uint16]: () => 'uint16', - [ModelType.uint32]: () => 'uint32', - [ModelType.uint64]: () => 'uint64', - [ModelType.uint64HexIdentifier]: () => 'uint64HexIdentifier', - [ModelType.objectId]: () => 'objectId', - [ModelType.string]: () => 'string', - [ModelType.int]: () => 'int', - [ModelType.encodedAddress]: () => 'encodedAddress' -}; - -describe('model formatter builder', () => { - describe('for built in formatter', () => { - it('can create default formatter', () => { - // Arrange: - const formatter = new ModelFormatterBuilder().build(modelSchema, formattingRules); - - // Act: - const subFormatterTypes = Object.keys(formatter); - - // Assert: - expect(subFormatterTypes).to.deep.equal([ - 'accountWithMetadata', - 'blockHeaderWithMetadata', - 'transactionWithMetadata', - - 'chainInfo', - 'merkleProofInfo', - 'finalizedBlock', - 'finalizationProof', - 'nodeHealth', - 'nodeInfo', - 'nodeTime', - 'serverInfo', - 'stateTree', - 'storageInfo', - 'transactionStatus' - ]); - }); - - it('can format transaction with metadata', () => { - // Arrange: - const formatter = new ModelFormatterBuilder().build(modelSchema, formattingRules); - - // Act: - const result = formatter.transactionWithMetadata.format({ - meta: { - height: 0, - hash: 0, - index: 0 - }, - transaction: { - signature: 0, - signerPublicKey: 0, - version: 0, - network: 0, - type: 0, - - maxFee: 0, - deadline: 0 - } - }); - - // Assert: - expect(result).to.deep.equal({ - meta: { - height: 'uint64', - hash: 'binary', - index: 'int' - }, - transaction: { - signature: 'binary', - signerPublicKey: 'binary', - version: 'uint8', - network: 'uint8', - type: 'int', - - maxFee: 'uint64', - deadline: 'uint64' - } - }); - }); - - it('can format block header with metadata', () => { - // Arrange: - const formatter = new ModelFormatterBuilder().build(modelSchema, formattingRules); - - // Act: - const result = formatter.blockHeaderWithMetadata.format({ - id: 0x5E3CD1498E18164DD5536133, - meta: { - hash: 0, - generationHash: 0, - totalFee: 0, - totalTransactionsCount: 0, - transactionsCount: 0, - statementsCount: 0, - stateHashSubCacheMerkleRoots: [0] - }, - block: { - signature: 0, - signerPublicKey: 0, - version: 0, - network: 0, - type: 0, - - height: 0, - timestamp: 0, - difficulty: 0, - previousBlockHash: 0, - transactionsHash: 0, - receiptsHash: 0, - stateHash: 0, - beneficiaryAddress: 0 - } - }); - - // Assert: - expect(result).to.deep.equal({ - id: 'objectId', - meta: { - hash: 'binary', - generationHash: 'binary', - totalFee: 'uint64', - transactionsCount: 'int', - statementsCount: 'int', - totalTransactionsCount: 'int', - - stateHashSubCacheMerkleRoots: ['binary'] - }, - block: { - signature: 'binary', - signerPublicKey: 'binary', - version: 'uint8', - network: 'uint8', - type: 'int', - - height: 'uint64', - timestamp: 'uint64', - difficulty: 'uint64', - previousBlockHash: 'binary', - transactionsHash: 'binary', - receiptsHash: 'binary', - stateHash: 'binary', - beneficiaryAddress: 'encodedAddress' - } - }); - }); - - it('can format account with metadata', () => { - // Arrange: - const formatter = new ModelFormatterBuilder().build(modelSchema, formattingRules); - - // Act: - const result = formatter.accountWithMetadata.format({ - id: 0, - account: { - address: 0, - addressHeight: 0, - publicKey: 0, - publicKeyHeight: 0, - accountType: 0, - importance: 0, - importanceHeight: 0, - mosaics: [ - { id: 0, amount: 0 }, - { id: 0, amount: 0 } - ] - } - }); - - // Assert: - expect(result).to.deep.equal({ - id: 'objectId', - account: { - address: 'encodedAddress', - addressHeight: 'uint64', - publicKey: 'binary', - publicKeyHeight: 'uint64', - accountType: 'uint8', - importance: 'uint64', - importanceHeight: 'uint64', - mosaics: [ - { id: 'uint64HexIdentifier', amount: 'uint64' }, - { id: 'uint64HexIdentifier', amount: 'uint64' } - ] - } - }); - }); - - it('can format chain info', () => { - // Arrange: - const formatter = new ModelFormatterBuilder().build(modelSchema, formattingRules); - - // Act: - const result = formatter.chainInfo.format({ - height: 0, - scoreLow: 0, - scoreHigh: 0, - latestFinalizedBlock: { - height: 0, - hash: 0, - finalizationEpoch: 0, - finalizationPoint: 0 - } - }); - - // Assert: - expect(result).to.deep.equal({ - height: 'uint64', - scoreLow: 'uint64', - scoreHigh: 'uint64', - latestFinalizedBlock: { - height: 'uint64', - hash: 'binary', - finalizationEpoch: 'uint32', - finalizationPoint: 'uint32' - } - }); - }); - - it('can format storage info', () => { - // Arrange: - const formatter = new ModelFormatterBuilder().build(modelSchema, formattingRules); - - // Act: - const result = formatter.storageInfo.format({ - numBlocks: 0, - numTransactions: 0, - numAccounts: 0 - }); - - // Assert: - expect(result).to.deep.equal({ - numBlocks: 'int', - numTransactions: 'int', - numAccounts: 'int' - }); - }); - }); - - describe('for custom formatter', () => { - it('can add arbitrary formatter', () => { - // Arrange: - const builder = new ModelFormatterBuilder(); - builder.addFormatter('mosaic'); - const formatter = builder.build(modelSchema, formattingRules); - - // Act: - const subFormatterTypes = formatter.mosaic.format({ id: 0, amount: 0 }); - - // Assert: - expect(subFormatterTypes).to.deep.equal({ id: 'uint64HexIdentifier', amount: 'uint64' }); - }); - - it('cannot add arbitrary formatter multiple times', () => { - // Arrange: - const builder = new ModelFormatterBuilder(); - builder.addFormatter('mosaic'); - - // Act + Assert: - expect(() => { builder.addFormatter('mosaic'); }).to.throw('formatter already registered'); - }); - }); -}); diff --git a/catapult-sdk/test/model/ModelSchemaBuilder_spec.js b/catapult-sdk/test/model/ModelSchemaBuilder_spec.js deleted file mode 100644 index fab93e127..000000000 --- a/catapult-sdk/test/model/ModelSchemaBuilder_spec.js +++ /dev/null @@ -1,561 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const ModelType = require('../../src/model/ModelType'); -const { expect } = require('chai'); - -describe('model schema builder', () => { - describe('allowed transaction types', () => { - it('has entityTypes on list of allowed transactions by default', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - - // Act + Assert: - const typeName = builder.typeToName(EntityType.transfer); - expect(typeName).to.equal('transfer'); - }); - - it('can be altered with setAllowedTransactions', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - builder.setAllowedTransactions({}); - - // Act + Assert: - expect(() => builder.typeToName(EntityType.transfer)).to.throw('transactionType is not in the list of allowed transactions'); - }); - - it('can be set to use custom types', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - builder.setAllowedTransactions({ foo: 12345 }); - - // Act: - const typeName = builder.typeToName(12345); - - // Assert: - expect(typeName).to.equal('foo'); - }); - }); - - describe('with no extensions', () => { - it('exposes expected types', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const modelSchema = builder.build(); - - // Act: - const schemaRootProperties = Object.keys(modelSchema); - - // Assert: - expect(schemaRootProperties).to.deep.equal([ - 'verifiableEntity', - - 'blockHeader', - 'blockHeaderMetadata', - 'blockHeaderWithMetadata', - 'merkleProofInfo', - 'merkleProofInfoPathNode', - 'finalizedBlock', - 'finalizationProof', - 'messageGroup', - 'bmTreeSignature', - 'parentPublicKeySignaturePair', - - 'transaction', - 'transactionMetadata', - 'transactionWithMetadata', - - 'transactionStatus', - - 'accountWithMetadata', - 'account', - 'supplementalPublicKey', - 'activityBucket', - 'mosaic', - 'accountLinkPublicKey', - 'accountLinkPublicKey.voting', - 'votingPublicKey', - - 'chainInfo', - 'nodeHealth', - 'nodeHealthStatus', - 'nodeInfo', - 'communicationTimestamps', - 'nodeTime', - 'serverInfo', - 'serverInfoData', - 'deploymentData', - 'stateTree', - 'storageInfo' - ]); - }); - - it('exposes no defined transaction types', () => { - // Act: - const builder = new ModelSchemaBuilder(); - const modelSchema = builder.build(); - - // Assert: - expect(modelSchema).to.not.contain.any.keys(Object.keys(EntityType)); - }); - - const extractPropertiesWithType = (object, matches, propertyType, key = '') => { - const getTypeIfNotBasicType = obj => { - const objKeys = Object.keys(obj); - return 2 === objKeys.length && objKeys.includes('type') && objKeys.includes('schemaName') ? obj.type : undefined; - }; - - Object.keys(object).forEach(property => { - if (ModelType[propertyType] === (getTypeIfNotBasicType(object[property]) || object[property])) - matches.push(`${key}${property}`); - else if ('string' !== typeof object[property]) - extractPropertiesWithType(object[property], matches, propertyType, `${key}${property}.`); - }); - }; - - const extractSchemaPropertiesWithType = propertyType => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const modelSchema = builder.build(); - - // Act: - const matchingProperties = []; - extractPropertiesWithType(modelSchema, matchingProperties, propertyType); - return matchingProperties; - }; - - // region schema types - - it('exposes correct none properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('none'); - - // Assert: - expect(matchingProperties.length).to.equal(0); - }); - - it('exposes correct object properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('object'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeaderWithMetadata.meta', - 'blockHeaderWithMetadata.block', - - 'bmTreeSignature.root', - 'bmTreeSignature.bottom', - - 'transactionWithMetadata.meta', - 'transactionWithMetadata.transaction', - - 'accountWithMetadata.account', - 'account.supplementalPublicKeys', - 'supplementalPublicKey.linked', - 'supplementalPublicKey.node', - 'supplementalPublicKey.vrf', - 'supplementalPublicKey.voting', - - 'chainInfo.latestFinalizedBlock', - - 'nodeHealth.status', - 'nodeTime.communicationTimestamps', - 'serverInfo.serverInfo', - 'serverInfoData.deployment' - ]); - }); - - it('exposes correct array properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('array'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeaderMetadata.stateHashSubCacheMerkleRoots', - 'merkleProofInfo.merklePath', - 'finalizationProof.messageGroups', - 'messageGroup.hashes', - 'messageGroup.signatures', - 'account.activityBuckets', - 'account.mosaics', - 'accountLinkPublicKey.voting.publicKeys', - 'stateTree.tree' - ]); - }); - - // endregion - - // region model types - - it('exposes correct binary properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('binary'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'verifiableEntity.signature', - 'verifiableEntity.signerPublicKey', - - 'blockHeader.proofGamma', - 'blockHeader.proofVerificationHash', - 'blockHeader.proofScalar', - 'blockHeader.previousBlockHash', - 'blockHeader.transactionsHash', - 'blockHeader.receiptsHash', - 'blockHeader.stateHash', - 'blockHeader.previousImportanceBlockHash', - 'blockHeader.signature', - 'blockHeader.signerPublicKey', - 'blockHeaderMetadata.hash', - 'blockHeaderMetadata.generationHash', - 'blockHeaderMetadata.stateHashSubCacheMerkleRoots.schemaName', - 'merkleProofInfoPathNode.hash', - 'finalizedBlock.hash', - 'finalizationProof.hash', - 'messageGroup.hashes.schemaName', - 'parentPublicKeySignaturePair.parentPublicKey', - 'parentPublicKeySignaturePair.signature', - - 'transaction.signature', - 'transaction.signerPublicKey', - 'transactionMetadata.aggregateHash', - 'transactionMetadata.hash', - 'transactionMetadata.merkleComponentHash', - - 'transactionStatus.hash', - - 'account.publicKey', - 'accountLinkPublicKey.publicKey', - 'votingPublicKey.publicKey', - - 'nodeInfo.publicKey', - 'nodeInfo.networkGenerationHashSeed', - 'nodeInfo.nodePublicKey', - 'stateTree.tree.schemaName' - ]); - }); - - it('exposes correct uint64 properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('uint64'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeader.height', - 'blockHeader.timestamp', - 'blockHeader.difficulty', - 'blockHeader.harvestingEligibleAccountsCount', - 'blockHeader.totalVotingBalance', - 'blockHeaderMetadata.totalFee', - - 'finalizedBlock.height', - 'finalizationProof.height', - 'messageGroup.height', - - 'transaction.deadline', - 'transaction.maxFee', - 'transactionMetadata.height', - 'transactionMetadata.timestamp', - - 'transactionStatus.deadline', - 'transactionStatus.height', - - 'account.addressHeight', - 'account.publicKeyHeight', - 'account.importance', - 'account.importanceHeight', - 'activityBucket.startHeight', - 'activityBucket.totalFeesPaid', - 'activityBucket.rawScore', - 'mosaic.amount', - - 'chainInfo.height', - 'chainInfo.scoreLow', - 'chainInfo.scoreHigh', - - 'communicationTimestamps.receiveTimestamp', - 'communicationTimestamps.sendTimestamp' - ]); - }); - - it('exposes correct uint64HexIdentifier properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('uint64HexIdentifier'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'mosaic.id' - ]); - }); - - it('exposes correct object id properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('objectId'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeaderWithMetadata.id', - 'transactionMetadata.aggregateId', - 'transactionWithMetadata.id', - 'accountWithMetadata.id' - ]); - }); - - it('exposes correct string properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('string'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'merkleProofInfoPathNode.position', - 'transactionStatus.group', - 'nodeHealthStatus.apiNode', - 'nodeHealthStatus.db', - 'nodeInfo.friendlyName', - 'nodeInfo.host', - 'serverInfoData.restVersion', - 'serverInfoData.sdkVersion', - 'deploymentData.deploymentTool', - 'deploymentData.deploymentToolVersion', - 'deploymentData.lastUpdatedDate' - - ]); - }); - - it('exposes correct status code properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('statusCode'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'transactionStatus.code' - ]); - }); - - it('exposes correct int properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('int'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeader.size', - 'blockHeader.type', - 'blockHeaderMetadata.totalTransactionsCount', - 'blockHeaderMetadata.transactionsCount', - 'blockHeaderMetadata.statementsCount', - - 'transaction.size', - 'transaction.type', - 'transactionMetadata.index', - - 'nodeInfo.roles', - 'nodeInfo.port', - 'nodeInfo.networkIdentifier', - - 'storageInfo.numBlocks', - 'storageInfo.numTransactions', - 'storageInfo.numAccounts' - ]); - }); - - it('exposes correct uint8 properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('uint8'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeader.version', - 'blockHeader.network', - 'transaction.version', - 'transaction.network', - 'account.accountType', - 'nodeInfo.version' - ]); - }); - - it('exposes correct uint32 properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('uint32'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeader.feeMultiplier', - 'blockHeader.votingEligibleAccountsCount', - 'finalizedBlock.finalizationEpoch', - 'finalizedBlock.finalizationPoint', - 'finalizationProof.version', - 'finalizationProof.finalizationEpoch', - 'finalizationProof.finalizationPoint', - 'messageGroup.stage', - 'transactionMetadata.feeMultiplier', - 'activityBucket.beneficiaryCount', - 'votingPublicKey.startEpoch', - 'votingPublicKey.endEpoch' - ]); - }); - - it('exposes correct encodedAddress properties', () => { - // Act: - const matchingProperties = extractSchemaPropertiesWithType('encodedAddress'); - - // Assert: - expect(matchingProperties).to.deep.equal([ - 'blockHeader.beneficiaryAddress', - 'account.address' - ]); - }); - - // endregion - }); - - const TestEntityType = { foo: 1234, bar: 2345 }; - - describe('with extensions', () => { - it('can add transaction extension', () => { - // Act: - const builder = new ModelSchemaBuilder(); - builder.setAllowedTransactions(TestEntityType); - builder.addTransactionSupport(TestEntityType.foo, { alpha: ModelType.array, beta: ModelType.binary, gamma: ModelType.uint64 }); - const modelSchema = builder.build(); - - // Assert: - expect(modelSchema).to.contain.key('foo'); - expect(modelSchema.foo.alpha).to.equal(ModelType.array); - expect(modelSchema.foo.beta).to.equal(ModelType.binary); - expect(modelSchema.foo.gamma).to.equal(ModelType.uint64); - - // - transaction extensions should inherit transaction types - expect(modelSchema.foo.signature).to.equal(ModelType.binary); - expect(modelSchema.foo.maxFee).to.equal(ModelType.uint64); - }); - - it('can add other extension', () => { - // Act: - const builder = new ModelSchemaBuilder(); - builder.addSchema('foo', { alpha: ModelType.array, beta: ModelType.binary, gamma: ModelType.uint64 }); - const modelSchema = builder.build(); - - // Assert: - expect(modelSchema).to.contain.key('foo'); - expect(modelSchema.foo.alpha).to.equal(ModelType.array); - expect(modelSchema.foo.beta).to.equal(ModelType.binary); - expect(modelSchema.foo.gamma).to.equal(ModelType.uint64); - - // - non-transaction extensions should not inherit transaction types - expect(modelSchema.foo.signature).to.equal(undefined); - expect(modelSchema.foo.maxFee).to.equal(undefined); - }); - - it('can add transaction extension for known entity type', () => { - // Act: - const builder = new ModelSchemaBuilder(); - builder.addTransactionSupport(EntityType.transfer, { alpha: ModelType.array }); - const modelSchema = builder.build(); - - // Assert: - expect(modelSchema).to.contain.key('transfer'); - expect(modelSchema.transfer.alpha).to.equal(ModelType.array); - - // - transaction extensions should inherit transaction types - expect(modelSchema.transfer.signature).to.equal(ModelType.binary); - expect(modelSchema.transfer.maxFee).to.equal(ModelType.uint64); - }); - - it('cannot add transaction extension for unknown entity type', () => { - // Act + Assert: - const builder = new ModelSchemaBuilder(); - expect(() => builder.addTransactionSupport(TestEntityType.foo, { alpha: ModelType.array })).to - .throw(`transactionType is not in the list of allowed transactions '${TestEntityType.foo}'`); - }); - - it('cannot add conflicting extensions', () => { - // Act: - const builder = new ModelSchemaBuilder(); - builder.setAllowedTransactions(TestEntityType); - builder.addTransactionSupport(TestEntityType.foo, { alpha: ModelType.array, beta: ModelType.binary, gamma: ModelType.uint64 }); - builder.addSchema('bar', { alpha: ModelType.array, beta: ModelType.binary, gamma: ModelType.uint64 }); - - // Assert: - ['foo', 'bar'].forEach(key => { - expect(() => builder.addSchema(key, {}), key).to.throw('already registered'); - }); - Object.keys(TestEntityType).forEach(key => { - expect(() => builder.addTransactionSupport(TestEntityType[key], {}), key).to.throw('already registered'); - }); - }); - - it('cannot override default extensions with schema', () => { - // Act: - const builder = new ModelSchemaBuilder(); - - // Assert: - ['blockHeader', 'mosaic'].forEach(key => { - expect(() => builder.addSchema(key, {}), key).to.throw('already registered'); - }); - }); - - it('cannot override default extensions with transactions', () => { - // Act: - const builder = new ModelSchemaBuilder(); - const allowedTransactions = { blockHeader: 123, mosaic: 456 }; - builder.setAllowedTransactions(allowedTransactions); - - // Assert: - Object.keys(allowedTransactions).forEach(key => { - expect(() => builder.addTransactionSupport(allowedTransactions[key], {}), key).to.throw('already registered'); - }); - }); - - it('picks transaction sub schema based on whitelist and availability', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - builder.setAllowedTransactions(Object.assign({}, TestEntityType, EntityType)); - builder.addTransactionSupport(TestEntityType.foo, { alpha: ModelType.array }); - builder.addTransactionSupport(EntityType.registerNamespace, { beta: ModelType.binary }); - const modelSchema = builder.build(); - const schemaLookup = modelSchema.transactionWithMetadata.transaction.schemaName; - - // Act + Assert: - expect(schemaLookup({ type: 0x8888 })).to.equal('transaction'); // not in whitelist - expect(schemaLookup({ type: EntityType.transfer })).to.equal('transaction'); // in whitelist, not available - expect(schemaLookup({ type: EntityType.registerNamespace })).to.equal('registerNamespace'); // in whitelist, available - }); - }); - - describe('transaction schema name supplier', () => { - it('picks transaction sub schema based on whitelist and availability', () => { - // Arrange: notice that schema lookup is created BEFORE additional transactions are registered - const builder = new ModelSchemaBuilder(); - const schemaLookup = builder.transactionSchemaNameSupplier(); - builder.setAllowedTransactions(Object.assign({}, TestEntityType, EntityType)); - builder.addTransactionSupport(TestEntityType.foo, { alpha: ModelType.array }); - builder.addTransactionSupport(EntityType.registerNamespace, { beta: ModelType.binary }); - builder.build(); - - // Act + Assert: - expect(schemaLookup({ type: 0x8888 })).to.equal('transaction'); // not in whitelist - expect(schemaLookup({ type: EntityType.transfer })).to.equal('transaction'); // in whitelist, not available - expect(schemaLookup({ type: EntityType.registerNamespace })).to.equal('registerNamespace'); // in whitelist, available - }); - }); -}); diff --git a/catapult-sdk/test/model/ModelType_spec.js b/catapult-sdk/test/model/ModelType_spec.js deleted file mode 100644 index 52d06004c..000000000 --- a/catapult-sdk/test/model/ModelType_spec.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const ModelType = require('../../src/model/ModelType'); -const { expect } = require('chai'); - -describe('model type enumeration', () => { - it('exposes expected types', () => { - // Assert: - expect(ModelType).to.deep.equal({ - none: 0, - array: 1, - dictionary: 2, - object: 3, - binary: 4, - objectId: 5, - statusCode: 6, - string: 7, - uint8: 8, - uint16: 9, - uint32: 10, - uint64: 11, - uint64HexIdentifier: 12, - int: 13, - boolean: 14, - encodedAddress: 15, - max: 15 - }); - }); -}); diff --git a/catapult-sdk/test/model/address_spec.js b/catapult-sdk/test/model/address_spec.js deleted file mode 100644 index a641e63a1..000000000 --- a/catapult-sdk/test/model/address_spec.js +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const address = require('../../src/model/address'); -const convert = require('../../src/utils/convert'); -const test = require('../testUtils'); -const { expect } = require('chai'); - -const Address_Decoded_Size = 24; -const Network_Mainnet_Identifier = 0x68; -const Network_Testnet_Identifier = 0x98; - -describe('address', () => { - describe('stringToAddress', () => { - const assertCannotCreateAddress = (encoded, message) => { - // Assert: - expect(() => { address.stringToAddress(encoded); }).to.throw(message); - }; - - it('can create address from valid encoded address', () => { - // Arrange: - const encoded = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - const expectedHex = '6823BB7C3C089D996585466380EDBDC19D4959184893E38C'; - - // Act: - const decoded = address.stringToAddress(encoded); - - // Assert: - expect(address.isValidAddress(decoded)).to.equal(true); - expect(convert.uint8ToHex(decoded)).to.equal(expectedHex); - }); - - it('cannot create address from encoded string with wrong length', () => { - // Assert: - assertCannotCreateAddress( - 'NC5J5DI2URIC4H3T3IMXQS25PWQWZIPEV6EV7LASABCDEFG', - 'NC5J5DI2URIC4H3T3IMXQS25PWQWZIPEV6EV7LASABCDEFG does not represent a valid encoded address' - ); - }); - - it('cannot create address from invalid encoded string', () => { - // Assert: - assertCannotCreateAddress('NC5(5DI2URIC4H3T3IMXQS25PWQWZIPEV6EV7LA', 'illegal base32 character ('); - assertCannotCreateAddress('NC5J1DI2URIC4H3T3IMXQS25PWQWZIPEV6EV7LA', 'illegal base32 character 1'); - assertCannotCreateAddress('NC5J5?I2URIC4H3T3IMXQS25PWQWZIPEV6EV7LA', 'illegal base32 character ?'); - }); - }); - - describe('addressToString', () => { - it('can create encoded address from address', () => { - // Arrange: - const decodedHex = '6823BB7C3C089D996585466380EDBDC19D4959184893E38C'; - const expected = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - - // Act: - const encoded = address.addressToString(convert.hexToUint8(decodedHex)); - - // Assert: - expect(encoded).to.equal(expected); - }); - - it('cannot create encoded address from invalid address', () => { - // Arrange: - const decodedHexStrings = [ - '6823BB7C3C089D996585466380EDBDC19D4959184893E3', // too short - '6823BB7C3C089D996585466380EDBDC19D4959184893E38CA6' // too long - ]; - - // Act + Assert: - decodedHexStrings.forEach(decodedHex => { - expect(() => { address.addressToString(convert.hexToUint8(decodedHex)); }, decodedHex) - .to.throw(`${decodedHex} does not represent a valid decoded address`); - }); - }); - }); - - describe('publicKeyToAddress', () => { - it('can create address from public key for well known network', () => { - // Arrange: - const expectedHex = '6823BB7C3C089D996585466380EDBDC19D4959184893E38C'; - const publicKey = convert.hexToUint8('3485D98EFD7EB07ADAFCFD1A157D89DE2796A95E780813C0258AF3F5F84ED8CB'); - - // Act: - const decoded = address.publicKeyToAddress(publicKey, Network_Mainnet_Identifier); - - // Assert: - expect(decoded[0]).to.equal(Network_Mainnet_Identifier); - expect(address.isValidAddress(decoded)).to.equal(true); - expect(convert.uint8ToHex(decoded)).to.equal(expectedHex); - }); - - it('can create address from public key for custom network', () => { - // Arrange: - const expectedHex = '9823BB7C3C089D996585466380EDBDC19D495918484BF7E9'; - const publicKey = convert.hexToUint8('3485D98EFD7EB07ADAFCFD1A157D89DE2796A95E780813C0258AF3F5F84ED8CB'); - - // Act: - const decoded = address.publicKeyToAddress(publicKey, Network_Testnet_Identifier); - - // Assert: - expect(decoded[0]).to.equal(Network_Testnet_Identifier); - expect(address.isValidAddress(decoded)).to.equal(true); - expect(convert.uint8ToHex(decoded)).to.equal(expectedHex); - }); - - it('address calculation is deterministic', () => { - // Arrange: - const publicKey = convert.hexToUint8('3485D98EFD7EB07ADAFCFD1A157D89DE2796A95E780813C0258AF3F5F84ED8CB'); - - // Act: - const decoded1 = address.publicKeyToAddress(publicKey, Network_Mainnet_Identifier); - const decoded2 = address.publicKeyToAddress(publicKey, Network_Mainnet_Identifier); - - // Assert: - expect(address.isValidAddress(decoded1)).to.equal(true); - expect(decoded1).to.deep.equal(decoded2); - }); - - it('different public keys result in different addresses', () => { - // Arrange: - const publicKey1 = test.random.publicKey(); - const publicKey2 = test.random.publicKey(); - - // Act: - const decoded1 = address.publicKeyToAddress(publicKey1, Network_Mainnet_Identifier); - const decoded2 = address.publicKeyToAddress(publicKey2, Network_Mainnet_Identifier); - - // Assert: - expect(address.isValidAddress(decoded1)).to.equal(true); - expect(address.isValidAddress(decoded2)).to.equal(true); - expect(decoded1).to.not.deep.equal(decoded2); - }); - - it('different networks result in different addresses', () => { - // Arrange: - const publicKey = test.random.publicKey(); - - // Act: - const decoded1 = address.publicKeyToAddress(publicKey, Network_Mainnet_Identifier); - const decoded2 = address.publicKeyToAddress(publicKey, Network_Testnet_Identifier); - - // Assert: - expect(address.isValidAddress(decoded1)).to.equal(true); - expect(address.isValidAddress(decoded2)).to.equal(true); - expect(decoded1).to.not.deep.equal(decoded2); - }); - }); - - describe('isValidAddress', () => { - it('returns true for valid address', () => { - // Arrange: - const validHex = '6823BB7C3C089D996585466380EDBDC19D4959184893E38C'; - const decoded = convert.hexToUint8(validHex); - - // Assert: - expect(address.isValidAddress(decoded)).to.equal(true); - }); - - it('returns false for address with invalid checksum', () => { - // Arrange: - const validHex = '6823BB7C3C089D996585466380EDBDC19D4959184893E38C'; - const decoded = convert.hexToUint8(validHex); - decoded[Address_Decoded_Size - 1] ^= 0xff; // ruin checksum - - // Assert: - expect(address.isValidAddress(decoded)).to.equal(false); - }); - - it('returns false for address with invalid hash', () => { - // Arrange: - const validHex = '6823BB7C3C089D996585466380EDBDC19D4959184893E38C'; - const decoded = convert.hexToUint8(validHex); - decoded[5] ^= 0xff; // ruin ripemd160 hash - - // Assert: - expect(address.isValidAddress(decoded)).to.equal(false); - }); - }); - - describe('isValidEncodedAddress', () => { - it('returns true for valid encoded address', () => { - // Arrange: - const encoded = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - - // Assert: - expect(address.isValidEncodedAddress(encoded)).to.equal(true); - }); - - it('returns false for invalid encoded address', () => { - // Arrange: - const encodedAddresses = [ - 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDF', // changed last char - 'NAR3W7B4BCOZSZMFIZRYx3N5YGOUSWIYJCJ6HDA' // non-base32 char ('x') - ]; - - // Assert: - encodedAddresses.forEach(encoded => { - expect(address.isValidEncodedAddress(encoded), encoded).to.equal(false); - }); - }); - - it('returns false for encoded address with wrong length', () => { - // Arrange: added ABC - const encoded = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDFGABC'; - - // Assert: - expect(address.isValidEncodedAddress(encoded)).to.equal(false); - }); - - it('adding leading or trailing white space invalidates encoded address', () => { - // Arrange: - const encoded = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - - // Assert: - expect(address.isValidEncodedAddress(` \t ${encoded}`)).to.equal(false); - expect(address.isValidEncodedAddress(`${encoded} \t `)).to.equal(false); - expect(address.isValidEncodedAddress(` \t ${encoded} \t `)).to.equal(false); - }); - }); -}); diff --git a/catapult-sdk/test/model/idReducer_spec.js b/catapult-sdk/test/model/idReducer_spec.js deleted file mode 100644 index dd3ff1ff1..000000000 --- a/catapult-sdk/test/model/idReducer_spec.js +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const idReducer = require('../../src/model/idReducer'); -const { expect } = require('chai'); - -describe('id reducer', () => { - describe('id to name lookup', () => { - // region basic - - it('can be built around empty tuples', () => { - // Act: - const lookup = idReducer.createIdToNameLookup([]); - const name = lookup.findName([0, 2]); - - // Assert: - expect(lookup.length).to.equal(0); - expect(name).to.equal(undefined); - }); - - it('can be built arround 1-level tuples', () => { - // Act: - const lookup = idReducer.createIdToNameLookup([ - { name: 'alice', namespaceId: [1, 1], parentId: [0, 0] }, - { name: 'bob', namespaceId: [2, 5], parentId: [0, 0] }, - { name: 'carol', namespaceId: [3, 7], parentId: [0, 0] } - ]); - const names = { - alice: lookup.findName([1, 1]), - bob: lookup.findName([2, 5]), - carol: lookup.findName([3, 7]) - }; - - // Assert: - expect(lookup.length).to.equal(3); - expect(names).to.deep.equal({ - alice: 'alice', - bob: 'bob', - carol: 'carol' - }); - }); - - it('can be built arround 2-level tuples', () => { - // Act: - const lookup = idReducer.createIdToNameLookup([ - { name: 'alice', namespaceId: [1, 1], parentId: [0, 0] }, - { name: 'apple', namespaceId: [0, 2], parentId: [1, 1] }, - { name: 'banana', namespaceId: [0, 4], parentId: [1, 1] }, - { name: 'bob', namespaceId: [2, 5], parentId: [0, 0] }, - { name: 'carrot', namespaceId: [0, 6], parentId: [2, 5] } - ]); - const names = { - alice: lookup.findName([1, 1]), - apple: lookup.findName([0, 2]), - banana: lookup.findName([0, 4]), - bob: lookup.findName([2, 5]), - carrot: lookup.findName([0, 6]) - }; - - // Assert: - expect(lookup.length).to.equal(5); - expect(names).to.deep.equal({ - alice: 'alice', - apple: 'alice.apple', - banana: 'alice.banana', - bob: 'bob', - carrot: 'bob.carrot' - }); - }); - - it('can be built arround multilevel tuples', () => { - // Act: - const lookup = idReducer.createIdToNameLookup([ - { name: 'alice', namespaceId: [1, 1], parentId: [0, 0] }, - { name: 'apple', namespaceId: [0, 2], parentId: [1, 1] }, - { name: 'mac', namespaceId: [0, 3], parentId: [0, 2] }, - { name: 'red', namespaceId: [2, 3], parentId: [0, 3] }, - { name: 'banana', namespaceId: [0, 4], parentId: [1, 1] } - ]); - const names = { - alice: lookup.findName([1, 1]), - apple: lookup.findName([0, 2]), - mac: lookup.findName([0, 3]), - red: lookup.findName([2, 3]), - banana: lookup.findName([0, 4]) - }; - - // Assert: - expect(lookup.length).to.equal(5); - expect(names).to.deep.equal({ - alice: 'alice', - apple: 'alice.apple', - mac: 'alice.apple.mac', - red: 'alice.apple.mac.red', - banana: 'alice.banana' - }); - }); - - // endregion - - // region edge cases - - it('returns undefined when id is unknown', () => { - // Arrange: - const lookup = idReducer.createIdToNameLookup([ - { name: 'alice', namespaceId: [1, 1], parentId: [0, 0] } - ]); - - // Act: - const name = lookup.findName([0, 2]); - - // Assert: - expect(name).to.equal(undefined); - }); - - it('gives first conflicting tuple preference', () => { - // Arrange: apple has two conflicting parents - const lookup = idReducer.createIdToNameLookup([ - { name: 'alice', namespaceId: [1, 1], parentId: [0, 0] }, - { name: 'apple', namespaceId: [0, 2], parentId: [1, 1] }, - { name: 'bob', namespaceId: [2, 5], parentId: [0, 0] }, - { name: 'apple', namespaceId: [0, 2], parentId: [2, 5] } - ]); - - // Act: - const name = lookup.findName([0, 2]); - - // Assert: the first definition wins - expect(name).to.equal('alice.apple'); - }); - - it('returns undefined when any parent id is unknown', () => { - // Arrange: - const lookup = idReducer.createIdToNameLookup([ - { name: 'alice', namespaceId: [1, 1], parentId: [2, 0] } - ]); - - // Act: - const name = lookup.findName([1, 1]); - - // Assert: - expect(name).to.equal(undefined); - }); - - // endregion - }); -}); diff --git a/catapult-sdk/test/model/namespace_spec.js b/catapult-sdk/test/model/namespace_spec.js deleted file mode 100644 index 5622cc87f..000000000 --- a/catapult-sdk/test/model/namespace_spec.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const namespace = require('../../src/model/namespace'); -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); - -describe('namespace', () => { - describe('alias type', () => { - it('exposes alias type types', () => { - // Assert: - expect(namespace.aliasType).to.deep.equal({ - mosaic: 1, - address: 2 - }); - }); - - it('exposed values are unique', () => { - // Act: - const reverseMapping = Object.keys(namespace.aliasType).reduce((state, name) => { - state[namespace.aliasType[name]] = name; - return state; - }, {}); - - // Assert: - expect(Object.keys(namespace.aliasType).length).to.equal(Object.keys(reverseMapping).length); - }); - }); - - describe('encodeNamespace', () => { - it('Testnet valid', () => { - // Assert: - const encoded = namespace.encodeNamespace(convert.hexToUint8('C0FB8AA409916260'), 152); - const encodedHex = convert.uint8ToHex(encoded); - const expectedEncodedHex = '9960629109A48AFBC0000000000000000000000000000000'; - expect(encodedHex).to.be.equal(expectedEncodedHex); - expect(encoded).to.be.deep.equal(convert.hexToUint8(expectedEncodedHex)); - }); - }); -}); diff --git a/catapult-sdk/test/model/networkInfo_spec.js b/catapult-sdk/test/model/networkInfo_spec.js deleted file mode 100644 index cb2dc35e0..000000000 --- a/catapult-sdk/test/model/networkInfo_spec.js +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const networkInfo = require('../../src/model/networkInfo'); -const { expect } = require('chai'); - -describe('network info', () => { - describe('networks', () => { - it('defines all known networks', () => { - // Act: - const knownNetworks = Object.keys(networkInfo.networks); - - // Assert: - expect(knownNetworks).to.deep.equal([ - 'mainnet', - 'testnet' - ]); - }); - - it('defines the mainnet network', () => { - // Assert: - expect(networkInfo.networks.mainnet).to.deep.equal({ id: 0x68, bytePrefix: '68', charPrefix: 'N' }); - }); - - it('defines the testnet network', () => { - // Assert: - expect(networkInfo.networks.testnet).to.deep.equal({ id: 0x98, bytePrefix: '98', charPrefix: 'T' }); - }); - }); - - describe('find by id', () => { - it('can find all known networks', () => { - // Arrange: - Object.keys(networkInfo.networks).forEach(networkName => { - // Act: - const network = networkInfo.findById(networkInfo.networks[networkName].id); - - // Assert: - expect(network).to.equal(networkInfo.networks[networkName]); - }); - }); - - it('returns undefined for unknown network', () => { - // Act: - const network = networkInfo.findById(0x25); - - // Assert: - expect(network).to.equal(undefined); - }); - }); - - describe('find by char prefix', () => { - it('can find all known networks', () => { - // Arrange: - Object.keys(networkInfo.networks).forEach(networkName => { - // Act: - const network = networkInfo.findByCharPrefix(networkInfo.networks[networkName].charPrefix); - - // Assert: - expect(network).to.equal(networkInfo.networks[networkName]); - }); - }); - - it('returns undefined for unknown network', () => { - // Act: - const network = networkInfo.findByCharPrefix('J'); - - // Assert: - expect(network).to.equal(undefined); - }); - }); -}); diff --git a/catapult-sdk/test/model/restriction_spec.js b/catapult-sdk/test/model/restriction_spec.js deleted file mode 100644 index 9244c5f2a..000000000 --- a/catapult-sdk/test/model/restriction_spec.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const restriction = require('../../src/model/restriction'); -const { expect } = require('chai'); - -describe('restriction', () => { - describe('mosaic restriction', () => { - describe('mosaic restriction type', () => { - it('exposes mosaic restriction type types', () => { - // Assert: - expect(restriction.mosaicRestriction.restrictionType).to.deep.equal({ - address: 0, - global: 1 - }); - }); - - it('exposed values are unique', () => { - // Act: - const reverseMapping = Object.keys(restriction.mosaicRestriction.restrictionType).reduce((state, name) => { - state[restriction.mosaicRestriction.restrictionType[name]] = name; - return state; - }, {}); - - // Assert: - expect(Object.keys(restriction.mosaicRestriction.restrictionType).length).to.equal(Object.keys(reverseMapping).length); - }); - }); - }); -}); diff --git a/catapult-sdk/test/model/status_spec.js b/catapult-sdk/test/model/status_spec.js deleted file mode 100644 index 6c00fbb50..000000000 --- a/catapult-sdk/test/model/status_spec.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const status = require('../../src/model/status'); -const { expect } = require('chai'); - -describe('status', () => { - describe('toString', () => { - it('can output well-known enum values', () => { - // Assert: - expect(status.toString(0x00000000)).to.equal('Success'); - expect(status.toString(0x40000000)).to.equal('Neutral'); - expect(status.toString(0x80000000)).to.equal('Failure'); - }); - - it('can output known plugin enum values', () => { - // Assert: - expect(status.toString(0x80410003)).to.equal('Failure_Aggregate_Too_Many_Cosignatures'); - expect(status.toString(0x80FF0001)).to.equal('Failure_Chain_Unlinked'); - expect(status.toString(0x80FE0005)).to.equal('Failure_Consumer_Remote_Chain_Duplicate_Transactions'); - expect(status.toString(0x80430005)).to.equal('Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block'); - expect(status.toString(0x80450001)).to.equal('Failure_Extension_Partial_Transaction_Cache_Prune'); - expect(status.toString(0x81490001)).to.equal('Failure_Hash_Already_Exists'); - expect(status.toString(0x80520008)).to.equal('Failure_LockSecret_Invalid_Duration'); - expect(status.toString(0x804D0002)).to.equal('Failure_Mosaic_Invalid_Name'); - expect(status.toString(0x80550003)).to.equal('Failure_Multisig_Redundant_Modification'); - expect(status.toString(0x804E0002)).to.equal('Failure_Namespace_Invalid_Name'); - expect(status.toString(0x80530001)).to.equal('Failure_Signature_Not_Verifiable'); - expect(status.toString(0x80540001)).to.equal('Failure_Transfer_Message_Too_Large'); - }); - - it('can output unknown enum values', () => { - // Assert: - expect(status.toString(0xABCD9812)).to.equal('unknown status 0xABCD9812'); - expect(status.toString(0x00CD9812)).to.equal('unknown status 0x00CD9812'); - }); - }); -}); diff --git a/catapult-sdk/test/modelBinary/ModelCodecBuilder_spec.js b/catapult-sdk/test/modelBinary/ModelCodecBuilder_spec.js deleted file mode 100644 index 8b4d111e8..000000000 --- a/catapult-sdk/test/modelBinary/ModelCodecBuilder_spec.js +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const ModelCodecBuilder = require('../../src/modelBinary/ModelCodecBuilder'); -const BinaryParser = require('../../src/parser/BinaryParser'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -const constants = { - knownTxType: 0x4123, - sizes: { - blockHeader: 372, - importanceBlockHeader: 376, - transactionHeader: 128, - transaction: 128 + 8 + 1 - } -}; - -describe('model codec builder', () => { - const countCodecs = codecs => codecs.reduce((count, value) => count + (undefined === value ? 0 : 1), 0); - - const getCodec = () => { - const builder = new ModelCodecBuilder(); - builder.addTransactionSupport(constants.knownTxType, { - deserialize: (parser, size, txCodecs) => { - const transaction = {}; - transaction.alpha = parser.uint32(); - transaction.beta = parser.uint32(); - - // store deserialize parameter data in the transaction in order to ensure builder is passing down correct data - Object.assign(transaction, { - numSerializeCodecs: parser.uint8(), - numDeserializeCodecs: countCodecs(txCodecs), - size - }); - return transaction; - }, - - serialize: (transaction, serializer, txCodecs) => { - serializer.writeUint32(transaction.alpha); - serializer.writeUint32(transaction.beta); - - // write serialize parameter data in the buffer in order to ensure builder is passing down correct data - // (notice that conditionally writing ensures codecs are passed to size calculator as well - // since numCodecs is expected to be greater than 0) - const numCodecs = countCodecs(txCodecs); - if (0 < numCodecs) - serializer.writeUint8(countCodecs(txCodecs)); - } - }); - - return builder.build(); - }; - - const generateVerifiableEntity = (size, type = 0x451C) => { - const Signature_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signature)); - const Signer_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signerPublicKey)); - - return { - buffer: Buffer.concat([ - test.buffer.fromSize(size), - Buffer.of(0x00, 0x00, 0x00, 0x00), // verifiable entity header reserved 1 4b - Signature_Buffer, - Signer_Buffer, - Buffer.of(0x00, 0x00, 0x00, 0x00), // entity body reserved 1 4b - Buffer.of(0x01), // version 1b - Buffer.of(0x81), // network 1b - Buffer.of(type & 0xFF, (type >> 8) & 0xFF) // type 2b - ]), - object: { - verifiableEntityHeader_Reserved1: 0, - signature: Signature_Buffer, - signerPublicKey: Signer_Buffer, - entityBody_Reserved1: 0, - version: 0x01, - network: 0x81, - type - } - }; - }; - - const generateBlockHeader = () => { - const proofGamma = Buffer.from(test.random.bytes(test.constants.sizes.vrfProof.gamma)); - const proofVerificationHash = Buffer.from(test.random.bytes(test.constants.sizes.vrfProof.verificationHash)); - const proofScalar = Buffer.from(test.random.bytes(test.constants.sizes.vrfProof.scalar)); - const previousBlockHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const transactionsHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const receiptsHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const stateHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const beneficiaryAddress = test.random.bytes(test.constants.sizes.addressDecoded); // 24 - const feeMultiplierBuffer = Buffer.of(0x0A, 0x00, 0x00, 0x00); - - const data = generateVerifiableEntity(constants.sizes.blockHeader, 0x8000); - data.buffer = Buffer.concat([ - data.buffer, - Buffer.of(0x97, 0x87, 0x45, 0x0E, 0xE1, 0x6C, 0xB6, 0x62), // height - Buffer.of(0x30, 0x3A, 0x46, 0x8B, 0x15, 0x2D, 0x60, 0x54), // timestamp - Buffer.of(0x86, 0x02, 0x75, 0x30, 0xE8, 0x50, 0x78, 0xE8), // difficulty - proofGamma, // 32b - proofVerificationHash, // 16b - proofScalar, // 32b - previousBlockHashBuffer, // 32b - transactionsHashBuffer, // 32b - receiptsHashBuffer, // 32b - stateHashBuffer, // 32b - Buffer.from(beneficiaryAddress), // address 24b - feeMultiplierBuffer // 4b - ]); - - Object.assign(data.object, { - height: [0x0E458797, 0x62B66CE1], - timestamp: [0x8B463A30, 0x54602D15], - difficulty: [0x30750286, 0xE87850E8], - proofGamma, - proofVerificationHash, - proofScalar, - previousBlockHash: previousBlockHashBuffer, - transactionsHash: transactionsHashBuffer, - receiptsHash: receiptsHashBuffer, - stateHash: stateHashBuffer, - beneficiaryAddress, - feeMultiplier: 10 - }); - return data; - }; - - const generateTransaction = (type = constants.knownTxType, tag = 0x75) => { - const data = generateVerifiableEntity(constants.sizes.transaction, type); - data.buffer = Buffer.concat([ - data.buffer, - Buffer.of(0x18, 0xA2, 0x46, 0xD0, 0x56, 0xDC, 0x18, 0xB0), // maxFee - Buffer.of(0x4A, 0xE0, 0xDA, 0x7F, 0x93, 0x73, 0x11, 0xC0), // deadline - Buffer.of(0x46, 0x8B, 0x15, 0x2D), // alpha - Buffer.of(tag, 0x30, 0xE8, 0x50), // beta - Buffer.of(0x01) // placeholder - ]); - - Object.assign(data.object, { - maxFee: [0xD046A218, 0xB018DC56], - deadline: [0x7FDAE04A, 0xC0117393], - alpha: 0x2D158B46, - beta: 0x50E83000 | tag - }); - - if (constants.knownTxType === type) { - // add calculated fields in order ensure that the builder passes down correct data to tx codecs - // (this is not advisable in practice outside of this test suite) - Object.assign(data.object, { - numSerializeCodecs: 1, - numDeserializeCodecs: 1, - size: constants.sizes.transaction - }); - } - - return data; - }; - - describe('block', () => { - test.binary.test.addAll(getCodec(), constants.sizes.blockHeader, generateBlockHeader); - }); - - describe('transaction extension', () => { - test.binary.test.addAll(getCodec(), constants.sizes.transaction, generateTransaction); - }); - - describe('basic', () => { - it('block types are supported by default', () => { - // Act: - const builder = new ModelCodecBuilder(); - const codec = builder.build(); - - // Assert: - expect(codec.supports(0x8000)).to.equal(true); - expect(codec.supports(0x8FFF)).to.equal(true); - }); - - it('transaction types are not supported by default', () => { - // Act: - const builder = new ModelCodecBuilder(); - const codec = builder.build(); - - // Assert: - expect(codec.supports(0x4000)).to.equal(false); - expect(codec.supports(0x4123)).to.equal(false); - expect(codec.supports(0x4FFF)).to.equal(false); - }); - - it('transaction types support can be added', () => { - // Act: - const builder = new ModelCodecBuilder(); - builder.addTransactionSupport(0x4123, {}); - const codec = builder.build(); - - // Assert: - expect(codec.supports(0x4000)).to.equal(false); - expect(codec.supports(0x4123)).to.equal(true); - expect(codec.supports(0x4FFF)).to.equal(false); - }); - - it('cannot add conflicting extensions', () => { - // Act: - const builder = new ModelCodecBuilder(); - builder.addTransactionSupport(0x4000, {}); - - // Assert: - expect(() => builder.addTransactionSupport(0x4000, {})).to.throw('already registered'); - }); - - it('cannot override default extensions', () => { - // Act: - const builder = new ModelCodecBuilder(); - - // Assert: - [0x8000, 0x8FFF].forEach(type => { - expect(() => builder.addTransactionSupport(type, {}), type).to.throw('already registered'); - }); - }); - - it('cannot serialize unknown model', () => { - // Arrange: - const codec = getCodec(); - - // Assert: - expect(() => codec.serialize({ type: 0x4143 }, {})).to.throw('no codec registered'); - }); - - it('cannot deserialize unknown model', () => { - // Arrange: - const codec = getCodec(); - const parser = new BinaryParser(); - parser.push(generateTransaction(0x4143).buffer); - - // Assert: - expect(() => codec.deserialize(parser)).to.throw('no codec registered'); - }); - }); -}); diff --git a/catapult-sdk/test/modelBinary/blockHeaderCodec_spec.js b/catapult-sdk/test/modelBinary/blockHeaderCodec_spec.js deleted file mode 100644 index f5c03a884..000000000 --- a/catapult-sdk/test/modelBinary/blockHeaderCodec_spec.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const blockHeaderCodec = require('../../src/modelBinary/blockHeaderCodec'); -const test = require('../binaryTestUtils'); - -describe('block header codec', () => { - const generateBlockHeader = () => { - const proofGamma = Buffer.from(test.random.bytes(test.constants.sizes.vrfProof.gamma)); // 32b - const proofVerificationHash = Buffer.from(test.random.bytes(test.constants.sizes.vrfProof.verificationHash)); // 16b - const proofScalar = Buffer.from(test.random.bytes(test.constants.sizes.vrfProof.scalar)); // 32b - const previousBlockHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const transactionsHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const receiptsHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const stateHashBuffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const beneficiaryAddress = test.random.bytes(test.constants.sizes.addressDecoded); // 24 - const feeMultiplierBuffer = Buffer.of(0x0A, 0x00, 0x00, 0x00); - - return { - buffer: Buffer.concat([ - Buffer.of(0x97, 0x87, 0x45, 0x0E, 0xE1, 0x6C, 0xB6, 0x62), // height 8b - Buffer.of(0x30, 0x3A, 0x46, 0x8B, 0x15, 0x2D, 0x60, 0x54), // timestamp 8b - Buffer.of(0x86, 0x02, 0x75, 0x30, 0xE8, 0x50, 0x78, 0xE8), // difficulty 8b - proofGamma, // 32b - proofVerificationHash, // 16b - proofScalar, // 32b - previousBlockHashBuffer, // 32b - transactionsHashBuffer, // 32b - receiptsHashBuffer, // 32b - stateHashBuffer, // 32b - Buffer.from(beneficiaryAddress), // address 24b - feeMultiplierBuffer, // 4b - Buffer.of(0x00, 0x00, 0x00, 0x00) // block header reserved 1 4b - ]), - object: { - height: [0x0E458797, 0x62B66CE1], - timestamp: [0x8B463A30, 0x54602D15], - difficulty: [0x30750286, 0xE87850E8], - proofGamma, - proofVerificationHash, - proofScalar, - previousBlockHash: previousBlockHashBuffer, - transactionsHash: transactionsHashBuffer, - receiptsHash: receiptsHashBuffer, - stateHash: stateHashBuffer, - beneficiaryAddress, - feeMultiplier: 10 - } - }; - }; - - test.binary.test.addAll(blockHeaderCodec, 264, generateBlockHeader); -}); diff --git a/catapult-sdk/test/modelBinary/embeddedEntityCodec_spec.js b/catapult-sdk/test/modelBinary/embeddedEntityCodec_spec.js deleted file mode 100644 index 8e328e1d6..000000000 --- a/catapult-sdk/test/modelBinary/embeddedEntityCodec_spec.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const embeddedEntityCodec = require('../../src/modelBinary/embeddedEntityCodec'); -const test = require('../binaryTestUtils'); - -describe('embedded entity codec', () => { - const generateEmbeddedEntity = () => { - const SignerPublicKey_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signerPublicKey)); - - return { - buffer: Buffer.concat([ - Buffer.of(0x00, 0x00, 0x00, 0x00), // embedded transaction header reserved 1 4b - SignerPublicKey_Buffer, - Buffer.of(0x00, 0x00, 0x00, 0x00), // entity body reserved 1 4b - Buffer.of(0x2A), // version 1b - Buffer.of(0x55), // network 1b - Buffer.of(0x1C, 0x45) // type 2b - ]), - object: { - embeddedTransactionHeader_Reserved1: 0, - signerPublicKey: SignerPublicKey_Buffer, - entityBody_Reserved1: 0, - version: 0x2A, - network: 0x55, - type: 0x451C - } - }; - }; - - test.binary.test.addAll(embeddedEntityCodec, 44, generateEmbeddedEntity); -}); diff --git a/catapult-sdk/test/modelBinary/importanceBlockHeaderCodec_spec.js b/catapult-sdk/test/modelBinary/importanceBlockHeaderCodec_spec.js deleted file mode 100644 index 16bee10b4..000000000 --- a/catapult-sdk/test/modelBinary/importanceBlockHeaderCodec_spec.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const importanceBlockHeaderCodec = require('../../src/modelBinary/importanceBlockHeaderCodec'); -const test = require('../binaryTestUtils'); - -describe('importance block header codec', () => { - const generateBlockHeader = () => { - const votingEligibleAccountsCount = Buffer.of(0x01, 0x00, 0x00, 0x00);// 4b - const harvestingEligibleAccountsCount = Buffer.of(0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00); // 8b - const totalVotingBalance = Buffer.of(0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00); // 8b - const previousImportanceBlockHash = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - - const buffer = Buffer.concat([ - votingEligibleAccountsCount, - harvestingEligibleAccountsCount, - totalVotingBalance, - previousImportanceBlockHash - ]); - const object = { - votingEligibleAccountsCount: 1, - harvestingEligibleAccountsCount: [ - 2, - 2 - ], - totalVotingBalance: [ - 3, - 3 - ], - previousImportanceBlockHash - }; - return { - buffer, - object - }; - }; - - test.binary.test.addAll(importanceBlockHeaderCodec, 52, generateBlockHeader); -}); diff --git a/catapult-sdk/test/modelBinary/serialize_spec.js b/catapult-sdk/test/modelBinary/serialize_spec.js deleted file mode 100644 index 5521ed015..000000000 --- a/catapult-sdk/test/modelBinary/serialize_spec.js +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const serialize = require('../../src/modelBinary/serialize'); -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); - -describe('serialize', () => { - const getCodec = () => ({ - deserialize: parser => { - const transaction = {}; - transaction.alpha = parser.uint16(); - transaction.beta = parser.uint32(); - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint16(transaction.alpha); - serializer.writeUint32(transaction.beta); - } - }); - - const runTest = actAndAssert => { - // Arrange: - const expectedBuffer = Buffer.concat([ - Buffer.of(0x46, 0x8B), // alpha - Buffer.of(0xFE, 0x30, 0xE8, 0x50) // beta - ]); - - const transaction = { - alpha: 0x8B46, - beta: 0x50E830FE - }; - - // Act + Assert: - actAndAssert(expectedBuffer, transaction); - }; - - it('to buffer returns appropriate buffer', () => { - // Arrange: - runTest((expectedBuffer, transaction) => { - // Act: - const buffer = serialize.toBuffer(getCodec(), transaction); - - // Assert: - expect(buffer).to.deep.equal(expectedBuffer); - }); - }); - - it('to hex returns appropriate hex string', () => { - // Arrange: - runTest((expectedBuffer, transaction) => { - const expectedHex = convert.uint8ToHex(expectedBuffer); - - // Act: - const hex = serialize.toHex(getCodec(), transaction); - - // Assert: - expect(hex).to.equal(expectedHex); - }); - }); -}); diff --git a/catapult-sdk/test/modelBinary/transactionCodec_spec.js b/catapult-sdk/test/modelBinary/transactionCodec_spec.js deleted file mode 100644 index b2712a2d1..000000000 --- a/catapult-sdk/test/modelBinary/transactionCodec_spec.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const transactionCodec = require('../../src/modelBinary/transactionCodec'); -const test = require('../binaryTestUtils'); - -describe('transaction codec', () => { - const generateTransaction = () => ({ - buffer: Buffer.concat([ - Buffer.of(0x18, 0xA2, 0x46, 0xD0, 0x56, 0xDC, 0x18, 0xB0), // maxFee - Buffer.of(0x4A, 0xE0, 0xDA, 0x7F, 0x93, 0x73, 0x11, 0xC0) // deadline - ]), - object: { - maxFee: [0xD046A218, 0xB018DC56], - deadline: [0x7FDAE04A, 0xC0117393] - } - }); - - test.binary.test.addAll(transactionCodec, 16, generateTransaction); -}); diff --git a/catapult-sdk/test/modelBinary/transactionExtensions_spec.js b/catapult-sdk/test/modelBinary/transactionExtensions_spec.js deleted file mode 100644 index cd2f4f74c..000000000 --- a/catapult-sdk/test/modelBinary/transactionExtensions_spec.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const sizes = require('../../src/modelBinary/sizes'); -const transactionExtensions = require('../../src/modelBinary/transactionExtensions'); -const test = require('../testUtils'); -const { expect } = require('chai'); - -describe('transaction extensions', () => { - const createMockTransaction = (alpha, beta) => ({ - verifiableEntityHeader_Reserved1: 0, - signerPublicKey: test.random.bytes(sizes.signerPublicKey), - signature: test.random.bytes(sizes.signature), - entityBody_Reserved1: 0, - alpha, - beta - }); - - const codec = { - serialize: (transaction, serializer) => { - // write header (will be ignored) - serializer.writeUint32(sizes.transactionHeader + 2 + 4); - serializer.writeUint32(transaction.verifiableEntityHeader_Reserved1); - serializer.writeBuffer(transaction.signature); - serializer.writeBuffer(transaction.signerPublicKey); - serializer.writeUint32(transaction.entityBody_Reserved1); - - // write data - serializer.writeUint16(transaction.alpha); - serializer.writeUint32(transaction.beta); - } - }; - - describe('hash', () => { - it('changes if r part of signature changes', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const hash = transactionExtensions.hash(codec, transaction); - - // Act: - transaction.signature[0] ^= 0xFF; - const modifiedHash = transactionExtensions.hash(codec, transaction); - - // Assert: - expect(modifiedHash).to.not.deep.equal(hash); - }); - - it('does not change if s part of signature changes', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const hash = transactionExtensions.hash(codec, transaction); - - // Act: - transaction.signature[sizes.signature / 2] ^= 0xFF; - const modifiedHash = transactionExtensions.hash(codec, transaction); - - // Assert: - expect(modifiedHash).to.deep.equal(hash); - }); - - it('changes if signer public key changes', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const hash = transactionExtensions.hash(codec, transaction); - - // Act: - transaction.signerPublicKey[sizes.signerPublicKey / 2] ^= 0xFF; - const modifiedHash = transactionExtensions.hash(codec, transaction); - - // Assert: - expect(modifiedHash).to.not.deep.equal(hash); - }); - - it('changes if entity data changes', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const hash = transactionExtensions.hash(codec, transaction); - - // Act: - ++transaction.alpha; - const modifiedHash = transactionExtensions.hash(codec, transaction); - - // Assert: - expect(modifiedHash).to.not.deep.equal(hash); - }); - }); - - describe('sign and verify', () => { - it('cannot validate unsigned transaction', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - - // Act: - const isVerified = transactionExtensions.verify(codec, transaction); - - // Assert: - expect(isVerified).is.equal(false); - }); - - it('can validate signed transaction', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const signerKeyPair = test.random.keyPair(); - transaction.signerPublicKey = signerKeyPair.publicKey; - transactionExtensions.sign(codec, signerKeyPair, transaction); - - // Act: - const isVerified = transactionExtensions.verify(codec, transaction); - - // Assert: - expect(isVerified).is.equal(true); - }); - - it('cannot validate altered signed transaction', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const signerKeyPair = test.random.keyPair(); - transaction.signerPublicKey = signerKeyPair.publicKey; - transactionExtensions.sign(codec, signerKeyPair, transaction); - - ++transaction.alpha; - - // Act: - const isVerified = transactionExtensions.verify(codec, transaction); - - // Assert: - expect(isVerified).is.equal(false); - }); - - it('cannot validate signed transaction with altered signature', () => { - // Arrange: - const transaction = createMockTransaction(12, 56); - const signerKeyPair = test.random.keyPair(); - transaction.signerPublicKey = signerKeyPair.publicKey; - transactionExtensions.sign(codec, signerKeyPair, transaction); - - transaction.signature[0] ^= 0xFF; - - // Act: - const isVerified = transactionExtensions.verify(codec, transaction); - - // Assert: - expect(isVerified).is.equal(false); - }); - }); -}); diff --git a/catapult-sdk/test/modelBinary/verifiableEntityCodec_spec.js b/catapult-sdk/test/modelBinary/verifiableEntityCodec_spec.js deleted file mode 100644 index 2ac1f45b4..000000000 --- a/catapult-sdk/test/modelBinary/verifiableEntityCodec_spec.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const verifiableEntityCodec = require('../../src/modelBinary/verifiableEntityCodec'); -const test = require('../binaryTestUtils'); - -describe('verifiable entity codec', () => { - const generateVerifiableEntity = () => { - const Signature_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signature)); - const SignerPublicKey_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signerPublicKey)); - - return { - buffer: Buffer.concat([ - Buffer.of(0x00, 0x00, 0x00, 0x00), // verifiable entity header reserved 1 4b - Signature_Buffer, - SignerPublicKey_Buffer, - Buffer.of(0x00, 0x00, 0x00, 0x00), // entity body reserved 1 4b - Buffer.of(0xBA), // version 1b - Buffer.of(0x55), // network 1b - Buffer.of(0x1C, 0x45) // type 2b - ]), - object: { - verifiableEntityHeader_Reserved1: 0, - signature: Signature_Buffer, - signerPublicKey: SignerPublicKey_Buffer, - entityBody_Reserved1: 0, - version: 0xBA, - network: 0x55, - type: 0x451C - } - }; - }; - - test.binary.test.addAll(verifiableEntityCodec, 108, generateVerifiableEntity); -}); diff --git a/catapult-sdk/test/packet/header_spec.js b/catapult-sdk/test/packet/header_spec.js deleted file mode 100644 index 713451dee..000000000 --- a/catapult-sdk/test/packet/header_spec.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const packetHeader = require('../../src/packet/header'); -const { expect } = require('chai'); - -describe('packet header', () => { - describe('constants', () => { - it('has correct size', () => { - // Act: - const { size } = packetHeader; - - // Assert: - expect(size).to.equal(8); - }); - }); - - describe('create buffer', () => { - it('can create header buffer', () => { - // Act: - const buffer = packetHeader.createBuffer(0x1234, 0x987); - - // Assert: - expect(buffer).to.deep.equal(Buffer.of(0x87, 0x09, 0x00, 0x00, 0x34, 0x12, 0x00, 0x00)); - }); - }); -}); diff --git a/catapult-sdk/test/parser/BinaryParser_spec.js b/catapult-sdk/test/parser/BinaryParser_spec.js deleted file mode 100644 index 3185c68bd..000000000 --- a/catapult-sdk/test/parser/BinaryParser_spec.js +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const BinaryParser = require('../../src/parser/BinaryParser'); -const { expect } = require('chai'); - -describe('BinaryParser', () => { - // region push - - it('cannot push non buffer', () => { - // Arrange: - const parser = new BinaryParser(); - - // Act: - const errorMessageText = 'NodeJS Buffer object'; - expect(() => { parser.push([0, 1, 2, 3]); }, 'array').to.throw(errorMessageText); - expect(() => { parser.push({}); }, 'object').to.throw(errorMessageText); - expect(() => { parser.push(7); }, 'numeric').to.throw(errorMessageText); - - // Assert: - expect(parser.numUnprocessedBytes()).to.equal(0); - }); - - it('can push single buffer to parser', () => { - // Arrange: - const parser = new BinaryParser(); - - // Act: - parser.push(Buffer.alloc(3)); - - // Assert: - expect(parser.numUnprocessedBytes()).to.equal(3); - }); - - it('can push mutiple buffers to parser', () => { - // Arrange: - const parser = new BinaryParser(); - - // Act: - const numBuffers = 5; - for (let i = 0; i < numBuffers; ++i) - parser.push(Buffer.alloc(i + 1)); - - // Assert: - expect(parser.numUnprocessedBytes()).to.equal(15); - }); - - // endregion - - // region uint8 / uint16 / uint32 / uint64 / buffer - - const addTypeParserTests = (name, validData, expected) => { - it(`cannot extract ${name} with insufficient data`, () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.alloc(validData.length - 1, 1)); - - // Act: - expect(() => { parser[name](validData.length); }).to.throw('insufficient unprocessed data'); - - // Assert: - expect(parser.numUnprocessedBytes()).to.equal(validData.length - 1); - }); - - it(`can extract ${name} with sufficient data`, () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.from(validData)); - - // Act: - const result = parser[name](validData.length); - - // Assert: - expect(result).to.deep.equal(expected); - expect(parser.numUnprocessedBytes()).to.equal(0); - }); - - it(`can extract ${name} with more than sufficient data`, () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.from(validData)); - parser.push(Buffer.from([0xAA, 0xBB])); - - // Act: - const result = parser[name](validData.length); - - // Assert: - expect(result).to.deep.equal(expected); - expect(parser.numUnprocessedBytes()).to.equal(2); - }); - - it(`can extract ${name} with sufficient data spanning buffers`, () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.from([])); - parser.push(Buffer.from(validData.slice(0, validData.length / 2))); - parser.push(Buffer.from([])); - parser.push(Buffer.from(validData.slice(validData.length / 2))); - - // Act: - const result = parser[name](validData.length); - - // Assert: - expect(result).to.deep.equal(expected); - expect(parser.numUnprocessedBytes()).to.equal(0); - }); - }; - - addTypeParserTests('uint8', [0xFC], 0xFC); - addTypeParserTests('uint16', [0x11, 0xC2], 0xC211); - addTypeParserTests('uint32', [0x11, 0x22, 0x33, 0xAA], 0xAA332211); - addTypeParserTests('uint64', [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], [0x44332211, 0x88776655]); - addTypeParserTests('buffer', [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77], Buffer.from([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77])); - - // endregion - - it('can extract subset of buffer as buffer', () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.from([0x66, 0x22, 0x88, 0x99, 0xAA, 0xFF])); - - // Act: - const result1 = parser.buffer(2); - const result2 = parser.buffer(3); - - // Assert: - expect(result1).to.deep.equal(Buffer.from([0x66, 0x22])); - expect(result2).to.deep.equal(Buffer.from([0x88, 0x99, 0xAA])); - expect(parser.numUnprocessedBytes()).to.equal(1); - }); - - it('can extract empty buffer as buffer', () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.from([0x66, 0x22, 0x88, 0x99, 0xAA, 0xFF])); - - // Act: - const result1 = parser.buffer(2); - const result2 = parser.buffer(0); - - // Assert: - expect(result1).to.deep.equal(Buffer.from([0x66, 0x22])); - expect(result2).to.deep.equal(Buffer.from([])); - expect(parser.numUnprocessedBytes()).to.equal(4); - }); - - it('can extract multiple properties from parser', () => { - // Arrange: - const parser = new BinaryParser(); - parser.push(Buffer.from([0x11, 0x77, 0x33])); - parser.push(Buffer.from([0x44])); - parser.push(Buffer.from([0x55])); - parser.push(Buffer.from([0x66, 0x22, 0x88, 0x99, 0xAA])); - parser.push(Buffer.from([0xBB])); - - // Act: - const result1 = parser.uint8(); - const result2 = parser.uint32(); - const result3 = parser.buffer(3); - const result4 = parser.uint16(); - - // Assert: - expect(result1).to.equal(0x11); - expect(result2).to.equal(0x55443377); - expect(result3).to.deep.equal(Buffer.from([0x66, 0x22, 0x88])); - expect(result4).to.equal(0xAA99); - expect(parser.numUnprocessedBytes()).to.equal(1); - }); -}); diff --git a/catapult-sdk/test/parser/PacketParser_spec.js b/catapult-sdk/test/parser/PacketParser_spec.js deleted file mode 100644 index 4ad028e41..000000000 --- a/catapult-sdk/test/parser/PacketParser_spec.js +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const PacketParser = require('../../src/parser/PacketParser'); -const { expect } = require('chai'); - -describe('PacketParser', () => { - const Test_Buffer_64 = Buffer.of( - 0xAA, 0xAA, 0xBB, 0xBB, 0xCC, 0xCC, 0xDD, 0xDD, - 0xEE, 0xEE, 0xFF, 0xFF, 0xAA, 0xAA, 0xBB, 0xBB, - 0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, - 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, - 0xAA, 0xAA, 0xBB, 0xBB, 0xCC, 0xCC, 0xDD, 0xDD, - 0xEE, 0xEE, 0xFF, 0xFF, 0xAA, 0xAA, 0xBB, 0xBB, - 0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, - 0x12, 0x34, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33 - ); - - describe('basic', () => { - const createPacketParser = packets => { - const parser = new PacketParser(); - parser.onPacket(packet => packets.push(packet)); - return parser; - }; - - it('fails if packet sizes are invalid', () => { - // Arrange: - const packets = []; - const parser = createPacketParser(packets); - - // Act: - const errorMessageText = 'cannot be less than packet header size'; - expect(() => { parser.push(Buffer.from('0000000004000000', 'hex')); }, '0').to.throw(errorMessageText); - expect(() => { parser.push(Buffer.from('0700000004000000', 'hex')); }, '7').to.throw(errorMessageText); - - // Assert: - expect(packets.length).to.equal(0); - }); - - it('succeeds if packet has min size', () => { - // Arrange: - const packets = []; - const parser = createPacketParser(packets); - - // Act: - parser.push(Buffer.from('0800000009000000', 'hex')); - - // Assert: - expect(packets.length).to.equal(1); - expect(packets[0]).to.deep.equal({ type: 0x0009, size: 0x0008, payload: Buffer.from([]) }); - }); - - it('succeeds if packet has nonzero payload size', () => { - // Arrange: - const packets = []; - const parser = createPacketParser(packets); - - // Act: - parser.push(Buffer.from('1600000004000000AAAABBBBCCCCDDDDEEEEFFFFAAAA', 'hex')); - - // Assert: - expect(packets.length).to.equal(1); - expect(packets[0]).to.deep.equal({ - type: 0x0004, - size: 0x0016, - payload: Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAA', 'hex') - }); - }); - - it('can parse packet spanning buffers', () => { - // Arrange: - const packets = []; - const parser = createPacketParser(packets); - - // Act: - parser.push(Buffer.from([0x48, 0x00, 0x00, 0x00])); - parser.push(Buffer.from([0x01, 0x00, 0x00, 0x00])); - parser.push(Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFF0000111122223333', 'hex')); - parser.push(Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFF1234111122223333', 'hex')); - - // Assert: - expect(packets.length).to.equal(1); - expect(packets[0]).to.deep.equal({ type: 0x0001, size: 0x0048, payload: Test_Buffer_64 }); - }); - - it('can parse multiple packets', () => { - // Arrange: - const packets = []; - const parser = createPacketParser(packets); - - // Act: - parser.push(Buffer.from('1600000004000000AAAABBBBCCCCDDDDEEEEFFFFAAAA4800000001000000', 'hex')); - parser.push(Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFF0000111122223333', 'hex')); - parser.push(Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFF1234111122223333', 'hex')); - parser.push(Buffer.from('1000000008000000FEDCBA9876543210', 'hex')); - - // Assert: - expect(packets.length).to.equal(3); - expect(packets[0]).to.deep.equal({ type: 0x0004, size: 0x0016, payload: Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAA', 'hex') }); - expect(packets[1]).to.deep.equal({ type: 0x0001, size: 0x0048, payload: Test_Buffer_64 }); - expect(packets[2]).to.deep.equal({ type: 0x0008, size: 0x0010, payload: Buffer.from('FEDCBA9876543210', 'hex') }); - }); - - it('can parse multiple packets in single buffer', () => { - // Arrange: - const packets = []; - const parser = createPacketParser(packets); - - // Act: - const hex = '1600000004000000AAAABBBBCCCCDDDDEEEEFFFFAAAA4800000001000000' - + 'AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFF0000111122223333' - + 'AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFF1234111122223333' - + '1000000008000000FEDCBA9876543210'; - parser.push(Buffer.from(hex, 'hex')); - - // Assert: - expect(packets.length).to.equal(3); - expect(packets[0]).to.deep.equal({ type: 0x0004, size: 0x0016, payload: Buffer.from('AAAABBBBCCCCDDDDEEEEFFFFAAAA', 'hex') }); - expect(packets[1]).to.deep.equal({ type: 0x0001, size: 0x0048, payload: Test_Buffer_64 }); - expect(packets[2]).to.deep.equal({ type: 0x0008, size: 0x0010, payload: Buffer.from('FEDCBA9876543210', 'hex') }); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/accountLink_spec.js b/catapult-sdk/test/plugins/accountLink_spec.js deleted file mode 100644 index 7be82e4a3..000000000 --- a/catapult-sdk/test/plugins/accountLink_spec.js +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const accountLinkPlugin = require('../../src/plugins/accountLink'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -describe('account link plugin', () => { - describe('register schema', () => { - it('adds account link system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - accountLinkPlugin.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 4); - expect(modelSchema).to.contain.all.keys(['accountLink', 'nodeKeyLink', 'votingKeyLink', 'vrfKeyLink']); - - // - accountLink - expect(Object.keys(modelSchema.accountLink).length).to.equal(Object.keys(modelSchema.transaction).length + 2); - expect(modelSchema.accountLink).to.contain.all.keys(['linkedPublicKey', 'linkAction']); - - // - nodeKeyLink - expect(Object.keys(modelSchema.nodeKeyLink).length).to.equal(Object.keys(modelSchema.transaction).length + 2); - expect(modelSchema.nodeKeyLink).to.contain.all.keys(['linkedPublicKey', 'linkAction']); - - // - votingKeyLink - expect(Object.keys(modelSchema.votingKeyLink).length).to.equal(Object.keys(modelSchema.transaction).length + 4); - expect(modelSchema.votingKeyLink).to.contain.all.keys(['linkedPublicKey', 'startEpoch', 'endEpoch', 'linkAction']); - - // - vrfKeyLink - expect(Object.keys(modelSchema.vrfKeyLink).length).to.equal(Object.keys(modelSchema.transaction).length + 2); - expect(modelSchema.vrfKeyLink).to.contain.all.keys(['linkedPublicKey', 'linkAction']); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - accountLinkPlugin.registerCodecs({ - addTransactionSupport: (type, codec) => { - codecs[type] = codec; - } - }); - - return codecs; - }; - - it('adds account link codec', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codec was registered - expect(Object.keys(codecs).length).to.equal(4); - expect(codecs).to.contain.all.keys([EntityType.accountLink.toString()]); - expect(codecs).to.contain.all.keys([EntityType.nodeKeyLink.toString()]); - expect(codecs).to.contain.all.keys([EntityType.votingKeyLink.toString()]); - expect(codecs).to.contain.all.keys([EntityType.vrfKeyLink.toString()]); - }); - - describe('supports account link transaction', () => { - const linkedPublicKey = Buffer.of( - 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, 0xC9, - 0x47, 0x0D, 0xB8, 0xFD, 0x2D, 0x81, 0x47, 0x6A, 0xC5, 0x61, 0xA4, 0xCE, 0xE1, 0x81, 0x40, 0x83 - ); - test.binary.test.addAll(getCodecs()[EntityType.accountLink], 32 + 1, () => ({ - buffer: Buffer.concat([ - linkedPublicKey, - Buffer.of(0x01) - ]), - object: { - linkedPublicKey, - linkAction: 0x01 - } - })); - }); - - describe('supports node key link transaction', () => { - const linkedPublicKey = Buffer.of( - 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, 0xC9, - 0x47, 0x0D, 0xB8, 0xFD, 0x2D, 0x81, 0x47, 0x6A, 0xC5, 0x61, 0xA4, 0xCE, 0xE1, 0x81, 0x40, 0x83 - ); - test.binary.test.addAll(getCodecs()[EntityType.nodeKeyLink], 32 + 1, () => ({ - buffer: Buffer.concat([ - linkedPublicKey, - Buffer.of(0x01) - ]), - object: { - linkedPublicKey, - linkAction: 0x01 - } - })); - }); - - describe('supports voting key link transaction', () => { - const linkedPublicKey = Buffer.of( - 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, 0xC9, - 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, 0xC9 - ); - const startEpoch = Buffer.of(0x47, 0x12, 0xC3, 0x00); - const endEpoch = Buffer.of(0x73, 0xBE, 0xD2, 0x11); - - test.binary.test.addAll(getCodecs()[EntityType.votingKeyLink], 32 + 4 + 4 + 1, () => ({ - buffer: Buffer.concat([ - linkedPublicKey, // 32 - startEpoch, // 4b - endEpoch, // 4b - Buffer.of(0x01) // 1b - ]), - object: { - linkedPublicKey, - startEpoch: 0x00C31247, - endEpoch: 0x11D2BE73, - linkAction: 0x01 - } - })); - }); - - describe('supports vrf key link transaction', () => { - const linkedPublicKey = Buffer.of( - 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, 0xC9, - 0x47, 0x0D, 0xB8, 0xFD, 0x2D, 0x81, 0x47, 0x6A, 0xC5, 0x61, 0xA4, 0xCE, 0xE1, 0x81, 0x40, 0x83 - ); - test.binary.test.addAll(getCodecs()[EntityType.vrfKeyLink], 32 + 1, () => ({ - buffer: Buffer.concat([ - linkedPublicKey, - Buffer.of(0x01) - ]), - object: { - linkedPublicKey, - linkAction: 0x01 - } - })); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/aggregate_spec.js b/catapult-sdk/test/plugins/aggregate_spec.js deleted file mode 100644 index 5d3e8dac8..000000000 --- a/catapult-sdk/test/plugins/aggregate_spec.js +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const ModelType = require('../../src/model/ModelType'); -const BinaryParser = require('../../src/parser/BinaryParser'); -const aggregate = require('../../src/plugins/aggregate'); -const BinarySerializer = require('../../src/serializer/BinarySerializer'); -const uint64 = require('../../src/utils/uint64'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -const constants = { - knownTxType: 0x0022, - sizes: { - aggregate: 128 + 32 + 4 + 4, // transaction header + transactionshash + payload size + aggregateTransactionHeader_Reserved1 - transaction: 128, - embedded: 48 + 8, - cosignature: 8 + 32 + 64, // version + signer public key + signature - transactionsHash: 32 - } -}; - -describe('aggregate plugin', () => { - describe('register schema', () => { - const assertAddsSchema = schemaName => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - aggregate.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 3); - expect(modelSchema).to.contain.all.keys(['aggregateComplete', 'aggregateBonded', 'aggregate.cosignature']); - - // - aggregate - expect(Object.keys(modelSchema[schemaName]).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema[schemaName]).to.contain.all.keys(['transactionsHash', 'transactions', 'cosignatures']); - - // - cosignature - expect(modelSchema['aggregate.cosignature']).to.deep.equal({ - version: ModelType.uint64, - signerPublicKey: ModelType.binary, - signature: ModelType.binary, - parentHash: ModelType.binary - }); - }; - - it('adds aggregateComplete system schema', () => assertAddsSchema('aggregateComplete')); - it('adds aggregateBonded system schema', () => assertAddsSchema('aggregateBonded')); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - aggregate.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds aggregate codec', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codec was registered - expect(Object.keys(codecs).length).to.equal(2); - expect(codecs).to.contain.all.keys([EntityType.aggregateComplete.toString(), EntityType.aggregateBonded.toString()]); - }); - - const getSubTxCodecs = () => { - const txCodecs = []; - // notice that this codec (unlike the one in ModelCodecBuilder_spec assumes that it is embedded) - txCodecs[constants.knownTxType] = { - deserialize: parser => { - const transaction = {}; - transaction.alpha = parser.uint32(); - transaction.beta = parser.uint32(); - - // use of extraSize allows tests with variably sized transactions - const extraSize = transaction.beta & 0xFF; - if (0 < extraSize) - parser.buffer(extraSize); - - return transaction; - }, - - serialize: (transaction, serializer) => { - serializer.writeUint32(transaction.alpha); - serializer.writeUint32(transaction.beta); - - const extraSize = transaction.beta & 0xFF; - serializer.writeBuffer(Buffer.alloc(extraSize)); - } - }; - - return txCodecs; - }; - - const generateAggregate = () => { - const transactionsHash = Buffer.concat([ - Buffer.of(0x02, 0x04, 0x80, 0xDE, 0xA4, 0x33, 0xC0, 0x3C), - Buffer.of(0x53, 0x33, 0x98, 0x67, 0x55, 0x40, 0x33, 0x22), - Buffer.of(0x05, 0x23, 0xF4, 0x5C, 0xD2, 0xE3, 0xE2, 0xEE), - Buffer.of(0x09, 0xFF, 0xFF, 0x0F, 0xF0, 0x10, 0xA0, 0x02) - ]); - - return { - buffer: Buffer.concat([ - transactionsHash, // transactionsHash 32 bytes - Buffer.of(0x00, 0x00, 0x00, 0x00), // payload size 4b - Buffer.of(0x00, 0x00, 0x00, 0x00) // aggregate transaction header reserved 1 4b - ]), - - // notice that payloadSize, like size, should not be in returned object - object: { - transactionsHash, - aggregateTransactionHeader_Reserved1: 0 - } - }; - }; - - const innerAggregateTxPaddingSize = innerTransactionSize => { - const alignment = 8; - return 0 === innerTransactionSize % alignment ? 0 : alignment - (innerTransactionSize % alignment); - }; - - const generateTransaction = options => { - const type = (options || {}).type || constants.knownTxType; - const extraSize = (options || {}).extraSize || 0; - - const SignerPublicKey_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signerPublicKey)); - return { - buffer: Buffer.concat([ - test.buffer.fromSize(constants.sizes.embedded + extraSize), - Buffer.of(0x00, 0x00, 0x00, 0x00), // embedded transaction header reserved 1 4b - SignerPublicKey_Buffer, - Buffer.of(0x00, 0x00, 0x00, 0x00), // entity body reserved 1 - Buffer.of(0x2A), // version 1b - Buffer.of(0x55), // network 1b - Buffer.of(type & 0xFF, (type >> 8) & 0xFF), // type 2b - Buffer.of(0x46, 0x8B, 0x15, 0x2D), // alpha - Buffer.of(extraSize, 0x30, 0xE8, 0x50), // beta - Buffer.alloc(extraSize) - ]), - object: { - embeddedTransactionHeader_Reserved1: 0, - signerPublicKey: SignerPublicKey_Buffer, - entityBody_Reserved1: 0, - version: 0x2A, - network: 0x55, - type, - alpha: 0x2D158B46, - beta: 0x50E83000 | extraSize - } - }; - }; - - const addTransaction = (generator, options) => () => { - const data = generator(); - const txData = generateTransaction(options); - const txPadding = innerAggregateTxPaddingSize(txData.buffer.length); - data.buffer = Buffer.concat([ - data.buffer, - txData.buffer - ]); - - if (txPadding) - data.buffer = Buffer.concat([data.buffer, Buffer.alloc(txPadding)]); - - const payloadSize = data.buffer.readUInt32LE(constants.sizes.transactionsHash) + txData.buffer.length + txPadding; - data.buffer.writeUInt32LE(payloadSize, constants.sizes.transactionsHash); - - if (!data.object.transactions) - data.object.transactions = []; - - data.object.transactions.push({ transaction: txData.object }); - return data; - }; - - const addCosignature = generator => { - const Version_Buffer = Buffer.of(0x46, 0x8B, 0x15, 0x2D, 0x30, 0xE8, 0x50, 0x54); - const Signer_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signerPublicKey)); - const Signature_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.signature)); - - return () => { - const data = generator(); - data.buffer = Buffer.concat([ - data.buffer, - Version_Buffer, - Signer_Buffer, - Signature_Buffer - ]); - - if (!data.object.cosignatures) - data.object.cosignatures = []; - - data.object.cosignatures.push({ - version: uint64.fromBytes(Version_Buffer), - signerPublicKey: Signer_Buffer, - signature: Signature_Buffer - }); - return data; - }; - }; - - const addAggregateTests = (aggregateName, getCodec) => { - describe(`supports ${aggregateName} aggregate`, () => { - const addAll = (size, dataGenerator) => { - // notice that the transaction header is preprocessed before deserialize is called on the codec - test.binary.test.addAll(getCodec(), size, dataGenerator, getSubTxCodecs(), constants.sizes.transaction); - }; - - describe('with neither transactions nor cosignatures', () => { - addAll(constants.sizes.aggregate, generateAggregate); - }); - - describe('with single transaction', () => { - addAll( - constants.sizes.aggregate + constants.sizes.embedded, - addTransaction(generateAggregate) - ); - }); - - describe('with multiple transactions', () => { - // use extraSize to emulate transactions of varying sizes within a single aggregate - const extraSize1 = 1; - const extraSize2 = 4; - const extraSize3 = 2; - - addAll( - constants.sizes.aggregate + (3 * constants.sizes.embedded) + (extraSize1 + extraSize2 + extraSize3) - + (innerAggregateTxPaddingSize(constants.sizes.aggregate + extraSize1) - + innerAggregateTxPaddingSize(constants.sizes.aggregate + extraSize2) - + innerAggregateTxPaddingSize(constants.sizes.aggregate + extraSize3)), - addTransaction( - addTransaction( - addTransaction(generateAggregate, { extraSize: extraSize1 }), - { extraSize: extraSize2 } - ), - { extraSize: extraSize3 } - ) - ); - }); - - describe('with cosignatures', () => { - addAll( - constants.sizes.aggregate + (2 * constants.sizes.cosignature), - addCosignature(addCosignature(generateAggregate)) - ); - }); - - describe('with multiple transactions and cosignatures', () => { - addAll( - constants.sizes.aggregate + (3 * constants.sizes.embedded) + (2 * constants.sizes.cosignature), - addCosignature(addCosignature(addTransaction(addTransaction(addTransaction(generateAggregate))))) - ); - }); - }); - - describe(`rejects ${aggregateName} aggregate`, () => { - describe('during deserialization if it', () => { - it('is embedded', () => { - // Arrange: - const codec = getCodec(); - const parser = new BinaryParser(); - parser.push(generateAggregate().buffer); - - // Act: calling deserialize without tx codecs emulates an embedded call - expect(() => { codec.deserialize(parser); }).to.throw('aggregate transaction is not embeddable'); - }); - - const assertDeserializationError = (buffer, size, errorText, message) => { - // Arrange: - const codec = getCodec(); - const parser = new BinaryParser(); - parser.push(buffer); - - // Act: - expect(() => { codec.deserialize(parser, size, getSubTxCodecs()); }, message).to.throw(errorText); - }; - - it('has sub transaction of unknown type', () => { - // Assert: - assertDeserializationError( - addTransaction(generateAggregate, { type: 0x0001 })().buffer, - constants.sizes.aggregate + constants.sizes.embedded, - 'error unsupported transaction type (1) in aggregate' - ); - }); - - it('has partial cosignatures', () => { - // Arrange: - [-1, 1].forEach(delta => { - // Assert: - assertDeserializationError( - addCosignature(addTransaction(generateAggregate))().buffer, - constants.sizes.aggregate + constants.sizes.embedded + constants.sizes.cosignature + delta, - 'aggregate cannot have partial cosignatures', - `delta ${delta}` - ); - }); - }); - - it('fails if payload size is too large', () => { - // Arrange: - [1, constants.sizes.aggregate, constants.sizes.aggregate + 1, constants.sizes.embedded].forEach(delta => { - // - increase reported payload size - const data = addTransaction(addTransaction(addTransaction(generateAggregate)))(); - data.buffer.writeUInt32LE( - data.buffer.readUInt32LE(constants.sizes.transactionsHash) + delta, constants.sizes.transactionsHash - ); - - // Assert: - assertDeserializationError( - data.buffer, - constants.sizes.aggregate + (3 * constants.sizes.embedded), - 'aggregate must contain complete payload', - `delta ${delta}` - ); - }); - }); - - it('fails if aggregate size is too small', () => { - // Arrange: - [0, 1, constants.sizes.aggregate - 1].forEach(size => { - // Assert: - assertDeserializationError( - addCosignature(addTransaction(generateAggregate))().buffer, - size, - 'aggregate must contain complete aggregate header', - `size ${size}` - ); - }); - }); - - it('fails if sub transaction size is too small', () => { - // Arrange: - [0, 1, constants.sizes.embedded - 8 - 1].forEach(size => { - // - modify second transaction size (notice that data.buffer does not include aggregate transaction header) - const data = addTransaction(addTransaction(addTransaction(generateAggregate)))(); - const offset = constants.sizes.aggregate - constants.sizes.transaction + constants.sizes.embedded; - data.buffer.writeUInt32LE(size, offset); - - // Assert: - assertDeserializationError( - data.buffer, - constants.sizes.aggregate + (3 * constants.sizes.embedded), - 'sub transaction must contain complete transaction header', - `size ${size}` - ); - }); - }); - }); - - describe('during serialization if it', () => { - it('is embedded', () => { - // Arrange: - const codec = getCodec(); - const { object } = generateAggregate(); - const serializer = new BinarySerializer(constants.sizes.aggregate); - - // Act: calling serialize without tx codecs emulates an embedded call - expect(() => { codec.serialize(object, serializer); }).to.throw('aggregate transaction is not embeddable'); - }); - - it('has sub transaction of unknown type', () => { - // Arrange: - const codec = getCodec(); - const { object } = addTransaction(generateAggregate, { type: 0x0001 })(); - const serializer = new BinarySerializer(constants.sizes.aggregate); - - // Act: - expect(() => { codec.serialize(object, serializer, getSubTxCodecs()); }) - .to.throw('error unsupported transaction type (1) in aggregate'); - }); - }); - }); - }; - - addAggregateTests('complete', () => getCodecs()[EntityType.aggregateComplete]); - addAggregateTests('bonded', () => getCodecs()[EntityType.aggregateBonded]); - }); -}); diff --git a/catapult-sdk/test/plugins/catapultModelSystem_spec.js b/catapult-sdk/test/plugins/catapultModelSystem_spec.js deleted file mode 100644 index 93ecdaa6d..000000000 --- a/catapult-sdk/test/plugins/catapultModelSystem_spec.js +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelType = require('../../src/model/ModelType'); -const catapultModelSystem = require('../../src/plugins/catapultModelSystem'); -const { expect } = require('chai'); - -const formattingRules = { - [ModelType.none]: () => 'none', - [ModelType.binary]: () => 'binary', - [ModelType.uint64]: () => 'uint64', - [ModelType.uint64HexIdentifier]: () => 'uint64HexIdentifier', - [ModelType.objectId]: () => 'objectId', - [ModelType.string]: () => 'string' -}; - -describe('catapult model system', () => { - describe('basic', () => { - it('cannot register unknown extension', () => { - // Act: - expect(() => catapultModelSystem.configure(['transfer', 'foo', 'namespace'])).to.throw('plugin \'foo\' not supported'); - }); - - it('has support for all plugins', () => { - // Act: - const supportedPluginNames = catapultModelSystem.supportedPluginNames(); - - // Assert: - expect(supportedPluginNames).to.deep.equal([ - 'accountLink', - 'aggregate', - 'lockHash', - 'lockSecret', - 'metadata', - 'mosaic', - 'multisig', - 'namespace', - 'receipts', - 'restrictions', - 'transfer' - ]); - }); - }); - - describe('model schema', () => { - it('can create default schema', () => { - // Act: - const system = catapultModelSystem.configure([], {}); - - // Assert: - expect(system.schema).to.contain.key('blockHeader'); - expect(system.schema).to.not.contain.key('transfer'); - expect(system.schema).to.not.contain.key('registerNamespace'); - }); - - it('can register single extension', () => { - // Act: - const system = catapultModelSystem.configure(['transfer'], {}); - - // Assert: - expect(system.schema).to.contain.key('blockHeader'); - expect(system.schema).to.contain.key('transfer'); - expect(system.schema).to.not.contain.key('registerNamespace'); - }); - - it('can register multiple extensions', () => { - // Act: - const system = catapultModelSystem.configure(['transfer', 'namespace', 'aggregate'], {}); - - // Assert: - expect(system.schema).to.contain.key('blockHeader'); - expect(system.schema).to.contain.key('transfer'); - expect(system.schema).to.contain.key('registerNamespace'); - expect(system.schema).to.contain.key('aggregateComplete'); - }); - }); - - describe('codec', () => { - it('can create default codec', () => { - // Act: - const system = catapultModelSystem.configure([], {}); - - // Assert: - expect(system.codec.supports(0x8000)).to.equal(true); - expect(system.codec.supports(EntityType.transfer)).to.equal(false); - expect(system.codec.supports(EntityType.registerNamespace)).to.equal(false); - }); - - it('can register single extension', () => { - // Act: - const system = catapultModelSystem.configure(['transfer'], {}); - - // Assert: - expect(system.codec.supports(0x8000)).to.equal(true); - expect(system.codec.supports(EntityType.transfer)).to.equal(true); - expect(system.codec.supports(EntityType.registerNamespace)).to.equal(false); - }); - - it('can register multiple extensions', () => { - // Act: - const system = catapultModelSystem.configure(['transfer', 'namespace'], {}); - - // Assert: - expect(system.codec.supports(0x8000)).to.equal(true); - expect(system.codec.supports(EntityType.transfer)).to.equal(true); - expect(system.codec.supports(EntityType.registerNamespace)).to.equal(true); - }); - }); - - describe('model formatter', () => { - it('can create default formatter without extensions', () => { - // Act: - const system = catapultModelSystem.configure([], { default: formattingRules }); - - // Assert: - expect(Object.keys(system.formatters)).to.deep.equal(['default']); - - const formatter = system.formatters.default; - expect(formatter).to.contain.key('blockHeaderWithMetadata'); - expect(formatter).to.not.contain.key('transfer'); - expect(formatter).to.not.contain.key('registerNamespace'); - }); - - it('can register single extension', () => { - // Act: - const system = catapultModelSystem.configure(['transfer'], { default: formattingRules }); - - // Assert: - expect(Object.keys(system.formatters)).to.deep.equal(['default']); - - const formatter = system.formatters.default; - expect(formatter).to.contain.key('blockHeaderWithMetadata'); - expect(formatter).to.contain.key('transfer'); - expect(formatter).to.not.contain.key('registerNamespace'); - }); - - it('can register multiple extensions', () => { - // Act: - const system = catapultModelSystem.configure(['transfer', 'namespace'], { default: formattingRules }); - - // Assert: - expect(Object.keys(system.formatters)).to.deep.equal(['default']); - - const formatter = system.formatters.default; - expect(formatter).to.contain.key('blockHeaderWithMetadata'); - expect(formatter).to.contain.key('transfer'); - expect(formatter).to.contain.key('registerNamespace'); - }); - - it('cannot create formatter when no rules are specified', () => { - // Act: - const system = catapultModelSystem.configure(['transfer'], {}); - - // Assert: - expect(Object.keys(system.formatters)).to.deep.equal([]); - }); - - it('can create multiple formatters when multiple sets of formatting rules are specfied', () => { - // Act: - const system = catapultModelSystem.configure(['transfer'], { - default: formattingRules, - custom: { [ModelType.uint64]: value => value[0] } - }); - - // Assert: - expect(Object.keys(system.formatters)).to.deep.equal(['default', 'custom']); - - // - plugins are respected - ['default', 'custom'].forEach(key => { - const formatter = system.formatters[key]; - const message = `formatter ${key}`; - expect(formatter, message).to.contain.key('blockHeaderWithMetadata'); - expect(formatter, message).to.contain.key('transfer'); - expect(formatter, message).to.not.contain.key('registerNamespace'); - }); - - // - formatting rules are dependent on formatter - const chainInfo = { height: [123, 456] }; - expect(system.formatters.default.chainInfo.format(chainInfo)).to.deep.equal({ height: 'uint64' }); - expect(system.formatters.custom.chainInfo.format(chainInfo)).to.deep.equal({ height: 123 }); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/lockHash_spec.js b/catapult-sdk/test/plugins/lockHash_spec.js deleted file mode 100644 index e93dd70e2..000000000 --- a/catapult-sdk/test/plugins/lockHash_spec.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const lockHash = require('../../src/plugins/lockHash'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -describe('lock hash plugin', () => { - describe('register schema', () => { - it('adds lock hash system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - lockHash.registerSchema(builder); - const modelSchema = builder.build(); - const assertSchema = (schema, expectedSchemaSize, ...expectedKeys) => { - expect(Object.keys(schema).length).to.equal(expectedSchemaSize); - expect(schema).to.contain.all.keys(...expectedKeys); - }; - - // Assert: - assertSchema(modelSchema, numDefaultKeys + 3, [ - 'hashLockInfo', - 'hashLockInfo.lock', - 'hashLock' - ]); - - // - hash lock infos - assertSchema(modelSchema.hashLockInfo, 2, 'id', 'lock'); - assertSchema(modelSchema['hashLockInfo.lock'], 7, - 'version', 'ownerAddress', 'mosaicId', 'amount', 'endHeight', 'status', 'hash'); - - // - hash lock transaction - const transactionSchemaSize = Object.keys(modelSchema.transaction).length; - assertSchema(modelSchema.hashLock, transactionSchemaSize + 4, 'duration', 'hash', 'mosaicId', 'amount'); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - lockHash.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds lock hash codecs', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codecs were registered - expect(Object.keys(codecs).length).to.equal(1); - expect(codecs).to.contain.all.keys([EntityType.hashLock.toString()]); - }); - - const getCodec = entityType => getCodecs()[entityType]; - - describe('supports hash lock', () => { - const hash = test.random.bytes(test.constants.sizes.hash256); - - test.binary.test.addAll(getCodec(EntityType.hashLock), 56, () => ({ - buffer: Buffer.concat([ - Buffer.of(0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF), // mosaicId - Buffer.of(0xCA, 0xD0, 0x8E, 0x6E, 0xFF, 0x21, 0x2F, 0x49), // amount - Buffer.of(0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF), // duration - Buffer.from(hash) // hash 32b - ]), - object: { - mosaicId: [0x78563412, 0xEFCDAB90], - amount: [0x6E8ED0CA, 0x492F21FF], - duration: [0xBBAA0099, 0xFFEEDDCC], - hash - } - })); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/lockSecret_spec.js b/catapult-sdk/test/plugins/lockSecret_spec.js deleted file mode 100644 index 85e7bc15b..000000000 --- a/catapult-sdk/test/plugins/lockSecret_spec.js +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const lockSecret = require('../../src/plugins/lockSecret'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -describe('lock secret plugin', () => { - describe('register schema', () => { - it('adds lock secret system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - lockSecret.registerSchema(builder); - const modelSchema = builder.build(); - const assertSchema = (schema, expectedSchemaSize, ...expectedKeys) => { - expect(Object.keys(schema).length).to.equal(expectedSchemaSize); - expect(schema).to.contain.all.keys(...expectedKeys); - }; - - // Assert: - assertSchema(modelSchema, numDefaultKeys + 4, [ - 'secretLockInfo', - 'secretLockInfo.lock', - 'secretLock', - 'secretProof' - ]); - - // - secret lock - assertSchema(modelSchema.secretLockInfo, 2, 'id', 'lock'); - - // - secret lock infos - assertSchema(modelSchema['secretLockInfo.lock'], 10, - 'version', 'ownerAddress', 'mosaicId', 'amount', 'endHeight', 'secret', - 'status', 'hashAlgorithm', 'recipientAddress', 'compositeHash'); - - // - secret lock transactions - const transactionSchemaSize = Object.keys(modelSchema.transaction).length; - assertSchema(modelSchema.secretLock, transactionSchemaSize + 6, - 'secret', 'mosaicId', 'amount', 'duration', 'recipientAddress', 'hashAlgorithm'); - assertSchema(modelSchema.secretProof, transactionSchemaSize + 4, 'secret', 'recipientAddress', 'proof', 'hashAlgorithm'); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - lockSecret.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds lock secret codecs', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codecs were registered - expect(Object.keys(codecs).length).to.equal(2); - expect(codecs).to.contain.all.keys([ - EntityType.secretLock.toString(), - EntityType.secretProof.toString() - ]); - }); - - const getCodec = entityType => getCodecs()[entityType]; - - describe('supports secret lock', () => { - const recipientAddressBuffer = test.random.bytes(test.constants.sizes.addressDecoded); - const secretBuffer = test.random.bytes(test.constants.sizes.hash256); - - test.binary.test.addAll(getCodec(EntityType.secretLock), 81, () => ({ - buffer: Buffer.concat([ - Buffer.from(recipientAddressBuffer), // recipientAddress 24b - Buffer.from(secretBuffer), // secret 32b - Buffer.of(0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF), // mosaic - Buffer.of(0xCA, 0xD0, 0x8E, 0x6E, 0xFF, 0x21, 0x2F, 0x49), // amount - Buffer.of(0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF), // duration - Buffer.of(0xFF) // hash algorithm - ]), - - object: { - recipientAddress: recipientAddressBuffer, - secret: secretBuffer, - mosaicId: [0x78563412, 0xEFCDAB90], - amount: [0x6E8ED0CA, 0x492F21FF], - duration: [0xBBAA0099, 0xFFEEDDCC], - hashAlgorithm: 0xFF - } - })); - }); - - describe('supports secret proof', () => { - const RecipientAddress_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.addressDecoded)); - const Secret_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.hash256)); - const proofBufferSize = 300; - const Proof_Buffer = Buffer.from(test.random.bytes(proofBufferSize)); - - const generateTransaction = () => { - const data = { - buffer: Buffer.concat([ - RecipientAddress_Buffer, // recipient 24b - Secret_Buffer, // secret 32b - Buffer.of(0x00, 0x00), // proof size 2b - Buffer.of(0xFF), // hash algorithm - Proof_Buffer // proofBufferSize - ]), - - object: { - recipientAddress: RecipientAddress_Buffer, - secret: Secret_Buffer, - hashAlgorithm: 0xFF, - proof: Proof_Buffer - } - }; - data.buffer.writeUInt16LE(Proof_Buffer.length, 24 + 32); - return data; - }; - - const size = test.constants.sizes.hash256 + 2 + 1 + test.constants.sizes.addressDecoded + proofBufferSize; - test.binary.test.addAll(getCodec(EntityType.secretProof), size, generateTransaction); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/metadata_spec.js b/catapult-sdk/test/plugins/metadata_spec.js deleted file mode 100644 index 8cf238f7f..000000000 --- a/catapult-sdk/test/plugins/metadata_spec.js +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const metadataPlugin = require('../../src/plugins/metadata'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -describe('metadata plugin', () => { - describe('register schema', () => { - it('adds metadata system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - metadataPlugin.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 5); - expect(modelSchema).to.contain.all.keys([ - 'accountMetadata', - 'mosaicMetadata', - 'namespaceMetadata', - 'metadata', - 'metadataEntry' - ]); - - // - accountMetadata - expect(Object.keys(modelSchema.accountMetadata).length).to.equal(Object.keys(modelSchema.transaction).length + 5); - expect(modelSchema.accountMetadata).to.contain.all.keys([ - 'targetAddress', 'scopedMetadataKey', 'valueSizeDelta', 'valueSize', 'value' - ]); - - // - mosaicMetadata - expect(Object.keys(modelSchema.mosaicMetadata).length).to.equal(Object.keys(modelSchema.transaction).length + 6); - expect(modelSchema.mosaicMetadata).to.contain.all.keys([ - 'targetAddress', 'scopedMetadataKey', 'targetMosaicId', 'valueSizeDelta', 'valueSize', 'value' - ]); - - // - namespaceMetadata - expect(Object.keys(modelSchema.namespaceMetadata).length).to.equal(Object.keys(modelSchema.transaction).length + 6); - expect(modelSchema.namespaceMetadata).to.contain.all.keys([ - 'targetAddress', - 'scopedMetadataKey', - 'targetNamespaceId', - 'valueSizeDelta', - 'valueSize', - 'value' - ]); - - // - metadata - expect(Object.keys(modelSchema.metadata).length).to.equal(2); - expect(modelSchema.metadata).to.contain.all.keys(['metadataEntry', 'id']); - - // - metadataEntry - expect(Object.keys(modelSchema.metadataEntry).length).to.equal(9); - expect(modelSchema.metadataEntry).to.contain.all.keys([ - 'version', - 'compositeHash', - 'sourceAddress', - 'targetAddress', - 'scopedMetadataKey', - 'targetId', - 'metadataType', - 'valueSize', - 'value' - ]); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - metadataPlugin.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds metadata codecs', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codecs were registered - expect(Object.keys(codecs).length).to.equal(3); - expect(codecs).to.contain.all.keys([ - EntityType.accountMetadata.toString(), - EntityType.mosaicMetadata.toString(), - EntityType.namespaceMetadata.toString() - ]); - }); - - const getCodec = entityType => getCodecs()[entityType]; - - describe('supports account metadata', () => { - const targetAddress = test.random.bytes(test.constants.sizes.addressDecoded); - const valueBuffer = Buffer.of(0x6d, 0x65, 0x74, 0x61, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e); - - test.binary.test.addAll(getCodec(EntityType.accountMetadata), 52, () => ({ - buffer: Buffer.concat([ - Buffer.from(targetAddress), // address 24b - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // scopedMetadataKey 8b - Buffer.of(0x03, 0x00), // valueSizeDelta - Buffer.of(0x10, 0x00), // valueSize - valueBuffer // value 16b - ]), - - object: { - targetAddress, - scopedMetadataKey: [0x066C26F2, 0x92B28340], - valueSizeDelta: 3, - value: valueBuffer - } - })); - }); - - describe('supports mosaic metadata', () => { - const targetAddress = test.random.bytes(test.constants.sizes.addressDecoded); - const valueBuffer = Buffer.of(0x6d, 0x65, 0x74, 0x61, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e); - - test.binary.test.addAll(getCodec(EntityType.mosaicMetadata), 60, () => ({ - buffer: Buffer.concat([ - Buffer.from(targetAddress), // address 24b - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // scopedMetadataKey 8b - Buffer.of(0x93, 0x53, 0xBB, 0x24, 0x12, 0xB1, 0xFF, 0x36), // targetMosaicId 8b - Buffer.of(0x05, 0x00), // valueSizeDelta - Buffer.of(0x10, 0x00), // valueSize - valueBuffer // value 16b - ]), - - object: { - targetAddress, - scopedMetadataKey: [0x066C26F2, 0x92B28340], - targetMosaicId: [0x24BB5393, 0x36FFB112], - valueSizeDelta: 5, - value: valueBuffer - } - })); - }); - - describe('supports namespace metadata', () => { - const targetAddress = test.random.bytes(test.constants.sizes.addressDecoded); - const valueBuffer = Buffer.of(0x6d, 0x65, 0x74, 0x61, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e); - - test.binary.test.addAll(getCodec(EntityType.namespaceMetadata), 60, () => ({ - buffer: Buffer.concat([ - Buffer.from(targetAddress), // address 24b - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // scopedMetadataKey 8b - Buffer.of(0xAA, 0x22, 0xC2, 0x32, 0x99, 0xBC, 0xDE, 0x63), // targetNamespaceId 8b - Buffer.of(0x12, 0x00), // valueSizeDelta - Buffer.of(0x10, 0x00), // valueSize - valueBuffer // value 16b - ]), - - object: { - targetAddress, - scopedMetadataKey: [0x066C26F2, 0x92B28340], - targetNamespaceId: [0x32C222AA, 0x63DEBC99], - valueSizeDelta: 18, - value: valueBuffer - } - })); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/mosaic_spec.js b/catapult-sdk/test/plugins/mosaic_spec.js deleted file mode 100644 index d605fc6bd..000000000 --- a/catapult-sdk/test/plugins/mosaic_spec.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const mosaic = require('../../src/plugins/mosaic'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -const constants = { - sizes: { - mosaicDefinition: 22, - mosaicSupplyChange: 17, - mosaicSupplyRevocation: 40 - } -}; - -describe('mosaic plugin', () => { - describe('register schema', () => { - it('adds mosaic system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - mosaic.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 5); - expect(modelSchema).to.contain.all.keys( - 'mosaicDefinition', - 'mosaicSupplyChange', - 'mosaicSupplyRevocation', - 'mosaicDescriptor', - 'mosaicDescriptor.mosaic' - ); - - // - mosaic definition - expect(Object.keys(modelSchema.mosaicDefinition).length).to.equal(Object.keys(modelSchema.transaction).length + 5); - expect(modelSchema.mosaicDefinition).to.contain.all.keys( - ['id', 'duration', 'nonce', 'flags', 'divisibility'] - ); - - // - mosaic supply change - expect(Object.keys(modelSchema.mosaicSupplyChange).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.mosaicSupplyChange).to.contain.all.keys(['mosaicId', 'delta', 'action']); - - // - mosaic descriptor - expect(Object.keys(modelSchema.mosaicDescriptor).length).to.equal(2); - expect(modelSchema.mosaicDescriptor).to.contain.all.keys(['id', 'mosaic']); - - // - mosaic descriptor mosaic - expect(Object.keys(modelSchema['mosaicDescriptor.mosaic']).length).to.equal(9); - expect(modelSchema['mosaicDescriptor.mosaic']).to.contain.all.keys([ - 'version', 'id', 'supply', 'startHeight', 'ownerAddress', 'revision', 'flags', 'divisibility', 'duration' - ]); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - mosaic.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds mosaic codecs', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codecs were registered - expect(Object.keys(codecs).length).to.equal(3); - expect(codecs).to.contain.all.keys([ - EntityType.mosaicDefinition.toString(), - EntityType.mosaicSupplyChange.toString(), - EntityType.mosaicSupplyRevocation.toString() - ]); - }); - - const getCodec = entityType => getCodecs()[entityType]; - - describe('supports mosaic definition', () => { - const generateTransaction = () => ({ - buffer: Buffer.concat([ - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // mosaic id - Buffer.of(0xFA, 0x62, 0xCC, 0x56, 0x42, 0x37, 0xBB, 0xD2), // duration - Buffer.of(0x06, 0xFF, 0xCA, 0xB8), // mosaic nonce - Buffer.of(0x11), // flags - Buffer.of(0x66) // divisibility - ]), - - object: { - id: [0x066C26F2, 0x92B28340], - duration: [0x56CC62FA, 0xD2BB3742], - nonce: 3100311302, - flags: 0x11, - divisibility: 0x66 - } - }); - - test.binary.test.addAll(getCodec(EntityType.mosaicDefinition), constants.sizes.mosaicDefinition, generateTransaction); - }); - - describe('supports mosaic supply change', () => { - const generateTransaction = () => ({ - buffer: Buffer.concat([ - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // mosaic id - Buffer.of(0xCA, 0xD0, 0x8E, 0x6E, 0xFF, 0x21, 0x2F, 0x49), // delta - Buffer.of(0x01) // action - ]), - - object: { - mosaicId: [0x066C26F2, 0x92B28340], - delta: [0x6E8ED0CA, 0x492F21FF], - action: 0x01 - } - }); - - test.binary.test.addAll(getCodec(EntityType.mosaicSupplyChange), constants.sizes.mosaicSupplyChange, generateTransaction); - }); - - describe('supports mosaic supply revokation', () => { - const sourceAddressBuffer = test.random.bytes(test.constants.sizes.addressDecoded); - const generateTransaction = () => ({ - buffer: Buffer.concat([ - sourceAddressBuffer, // source address - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // mosaic id - Buffer.of(0xCA, 0xD0, 0x8E, 0x6E, 0xFF, 0x21, 0x2F, 0x49) // amount - ]), - - object: { - sourceAddress: sourceAddressBuffer, - mosaicId: [0x066C26F2, 0x92B28340], - amount: [0x6E8ED0CA, 0x492F21FF] - } - }); - - test.binary.test.addAll(getCodec(EntityType.mosaicSupplyRevocation), - constants.sizes.mosaicSupplyRevocation, generateTransaction); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/multisig_spec.js b/catapult-sdk/test/plugins/multisig_spec.js deleted file mode 100644 index 1233056db..000000000 --- a/catapult-sdk/test/plugins/multisig_spec.js +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const multisig = require('../../src/plugins/multisig'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -const constants = { - sizes: { - addressDecoded: 24, - modifyMultisigAccount: 8 - } -}; - -describe('multisig plugin', () => { - describe('register schema', () => { - it('adds multisig system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - multisig.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 4); - expect(modelSchema).to.contain.all.keys([ - 'modifyMultisigAccount', - 'multisigEntry', - 'multisigEntry.multisig', - 'multisigGraph' - ]); - - // - modify multisig account - expect(Object.keys(modelSchema.modifyMultisigAccount).length).to.equal(Object.keys(modelSchema.transaction).length + 4); - expect(modelSchema.modifyMultisigAccount).to.contain.all.keys( - ['minRemovalDelta', 'minApprovalDelta', 'addressAdditions', 'addressDeletions'] - ); - - // - multisig entry - expect(Object.keys(modelSchema.multisigEntry).length).to.equal(1); - expect(modelSchema.multisigEntry).to.contain.all.keys(['multisig']); - - expect(Object.keys(modelSchema['multisigEntry.multisig']).length).to.equal(6); - expect(modelSchema['multisigEntry.multisig']) - .to.contain.all.keys(['version', 'accountAddress', 'minApproval', - 'minRemoval', 'multisigAddresses', 'cosignatoryAddresses']); - - // - multisig graph - expect(Object.keys(modelSchema.multisigGraph).length).to.equal(2); - expect(modelSchema.multisigGraph).to.contain.all.keys(['level', 'multisigEntries']); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - multisig.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds multisig codec', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codec was registered - expect(Object.keys(codecs).length).to.equal(1); - expect(codecs).to.contain.all.keys([EntityType.modifyMultisigAccount.toString()]); - }); - - const generateTransaction = () => ({ - buffer: Buffer.concat([ - Buffer.of(0x2B), // minRemovalDelta 1b - Buffer.of(0x4D), // minApprovalDelta 1b - Buffer.of(0x00), // addressAdditionsCount 1b - Buffer.of(0x00), // addressDeletionsCount 1b - Buffer.of(0x00, 0x00, 0x00, 0x00) // multisig account modification transaction body reserved 1 4b - ]), - object: { - minRemovalDelta: 0x2B, - minApprovalDelta: 0x4D, - multisigAccountModificationTransactionBody_Reserved1: 0, - addressAdditions: [], - addressDeletions: [] - } - }); - - const addModifications = generator => { - const addressAddition1 = Buffer.of( - 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, 0xC9, - 0x47, 0x0D, 0xB8, 0xFD, 0x2D, 0x81, 0x47, 0x6A - ); - const addressAddition2 = Buffer.of( - 0x3E, 0xCA, 0x9E, 0x17, 0x1A, 0x02, 0xFB, 0xD4, 0x9C, 0x73, 0x75, 0x5D, 0x82, 0xEE, 0xCE, 0x6F, - 0x63, 0x90, 0x5A, 0x44, 0xA2, 0x7C, 0xF1, 0x3A - ); - const addressDeletion1 = Buffer.of( - 0x99, 0xF2, 0x26, 0x6C, 0x06, 0xBE, 0xE0, 0xE1, 0xC7, 0x39, 0x57, 0xFE, 0x0F, 0x39, 0x7E, 0x7A, - 0xE3, 0x15, 0xEA, 0x51, 0x6B, 0xA7, 0x12, 0xEF - ); - - return () => { - const data = generator(); - data.buffer = Buffer.concat([data.buffer, addressAddition1, addressAddition2, addressDeletion1]); - - data.buffer.writeUInt8(2, 2); // addressAdditionsCount, two additions at 2 bytes offset - data.buffer.writeUInt8(1, 3); // addressDeletionsCount, one deletion at 3 bytes offset - - data.object.addressAdditions = [addressAddition1, addressAddition2]; - data.object.addressDeletions = [addressDeletion1]; - - return data; - }; - }; - - const getCodec = () => getCodecs()[EntityType.modifyMultisigAccount]; - - describe('supports modify multisig account', () => { - describe('with no additions or deletions', () => { - test.binary.test.addAll(getCodec(), constants.sizes.modifyMultisigAccount, generateTransaction); - }); - - describe('with no additions or deletions and negative deltas', () => { - test.binary.test.addAll(getCodec(), constants.sizes.modifyMultisigAccount, () => ({ - buffer: Buffer.concat([ - Buffer.of(0xA2), // minRemovalDelta 1b - Buffer.of(0xC9), // minApprovalDelta 1b - Buffer.of(0x00), // addressAdditionsCount 1b - Buffer.of(0x00), // addressDeletionsCount 1b - Buffer.of(0x00, 0x00, 0x00, 0x00) // multisig account modification transaction body reserved 1 4b - ]), - object: { - minRemovalDelta: -94, - minApprovalDelta: -55, - addressAdditions: [], - addressDeletions: [], - multisigAccountModificationTransactionBody_Reserved1: 0 - } - })); - }); - - describe('with additions and deletions', () => { - test.binary.test.addAll( - getCodec(), - constants.sizes.modifyMultisigAccount + (3 * constants.sizes.addressDecoded), - addModifications(generateTransaction) - ); - }); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/namespace_spec.js b/catapult-sdk/test/plugins/namespace_spec.js deleted file mode 100644 index 23e851082..000000000 --- a/catapult-sdk/test/plugins/namespace_spec.js +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const ModelType = require('../../src/model/ModelType'); -const namespace = require('../../src/plugins/namespace'); -const schemaFormatter = require('../../src/utils/schemaFormatter'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -const constants = { - sizes: { - aliasAddress: 33, - aliasMosaic: 17, - namespaceName: 6, - registerNamespace: 18 - } -}; - -describe('namespace plugin', () => { - describe('register schema', () => { - it('adds namespace system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - namespace.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 15); - expect(modelSchema).to.contain.all.keys( - 'aliasAddress', - 'aliasMosaic', - 'namespaces', - 'namespaceDescriptor', - 'namespaceDescriptor.meta', - 'namespaceDescriptor.namespace', - 'namespaceDescriptor.alias.mosaic', - 'namespaceDescriptor.alias.address', - 'namespaceDescriptor.alias.empty', - 'namespaceNameTuple', - 'registerNamespace', - 'mosaicNames', - 'mosaicNamesTuple', - 'accountNames', - 'accountNamesTuple' - ); - - // - alias address - expect(Object.keys(modelSchema.aliasAddress).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.aliasAddress).to.contain.all.keys(['namespaceId', 'address', 'aliasAction']); - - // - alias mosaic - expect(Object.keys(modelSchema.aliasMosaic).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.aliasMosaic).to.contain.all.keys(['namespaceId', 'mosaicId', 'aliasAction']); - - // - namespaces - expect(Object.keys(modelSchema.namespaces).length).to.equal(1); - expect(modelSchema.namespaces).to.contain.all.keys(['namespaces']); - - // - namespaceDescriptor - expect(Object.keys(modelSchema.namespaceDescriptor).length).to.equal(3); - expect(modelSchema.namespaceDescriptor).to.contain.all.keys(['id', 'meta', 'namespace']); - - // - namespaceDescriptor.meta - expect(Object.keys(modelSchema['namespaceDescriptor.meta']).length).to.equal(2); - expect(modelSchema['namespaceDescriptor.meta']).to.contain.all.keys(['active', 'index']); - - // - namespaceDescriptor.namespace - expect(Object.keys(modelSchema['namespaceDescriptor.namespace']).length).to.equal(11); - expect(modelSchema['namespaceDescriptor.namespace']).to.contain.all.keys([ - 'version', 'registrationType', 'depth', 'level0', 'level1', 'level2', - 'alias', 'parentId', 'ownerAddress', 'startHeight', 'endHeight' - ]); - - // - namespaceDescriptor.alias.mosaic - expect(Object.keys(modelSchema['namespaceDescriptor.alias.mosaic']).length).to.equal(2); - expect(modelSchema['namespaceDescriptor.alias.mosaic']).to.contain.all.keys(['type', 'mosaicId']); - - // - namespaceDescriptor.alias.address - expect(Object.keys(modelSchema['namespaceDescriptor.alias.address']).length).to.equal(2); - expect(modelSchema['namespaceDescriptor.alias.address']).to.contain.all.keys(['type', 'address']); - - // - namespaceDescriptor.alias.empty - expect(Object.keys(modelSchema['namespaceDescriptor.alias.empty']).length).to.equal(1); - expect(modelSchema['namespaceDescriptor.alias.empty']).to.contain.all.keys(['type']); - - // - namespaceNameTuple - expect(Object.keys(modelSchema.namespaceNameTuple).length).to.equal(3); - expect(modelSchema.namespaceNameTuple).to.contain.all.keys(['id', 'name', 'parentId']); - - // - register namespace - expect(Object.keys(modelSchema.registerNamespace).length).to.equal(Object.keys(modelSchema.transaction).length + 5); - expect(modelSchema.registerNamespace).to.contain.all.keys(['id', 'registrationType', 'parentId', 'duration', 'name']); - - // - mosaic names - expect(Object.keys(modelSchema.mosaicNames).length).to.equal(1); - expect(modelSchema.mosaicNames).to.contain.all.keys(['mosaicNames']); - - // - mosaic names tuple - expect(Object.keys(modelSchema.mosaicNamesTuple).length).to.equal(2); - expect(modelSchema.mosaicNamesTuple).to.contain.all.keys(['mosaicId', 'names']); - - // - account names - expect(Object.keys(modelSchema.accountNames).length).to.equal(1); - expect(modelSchema.accountNames).to.contain.all.keys(['accountNames']); - - // - account names tuple - expect(Object.keys(modelSchema.accountNamesTuple).length).to.equal(2); - expect(modelSchema.accountNamesTuple).to.contain.all.keys(['address', 'names']); - }); - }); - - describe('conditional schema', () => { - describe('uses the correct conditional schema depending on alias type', () => { - const formatAlias = alias => { - // Arrange: - const formattingRules = { - [ModelType.none]: () => 'none', - [ModelType.binary]: () => 'binary', - [ModelType.uint8]: () => 'uint8', - [ModelType.uint16]: () => 'uint16', - [ModelType.uint32]: () => 'uint32', - [ModelType.uint64]: () => 'uint64', - [ModelType.uint64HexIdentifier]: () => 'uint64HexIdentifier', - [ModelType.objectId]: () => 'objectId', - [ModelType.string]: () => 'string', - [ModelType.int]: () => 'int', - [ModelType.encodedAddress]: () => 'encodedAddress' - }; - const namespaceDescriptorNamespace = { - registrationType: null, - depth: null, - level0: null, - level1: null, - level2: null, - alias, - parentId: null, - ownerAddress: null, - startHeight: null, - endHeight: null - }; - const builder = new ModelSchemaBuilder(); - - // Act: - namespace.registerSchema(builder); - const modelSchema = builder.build(); - const formattedEntity = schemaFormatter.format( - namespaceDescriptorNamespace, - modelSchema['namespaceDescriptor.namespace'], - modelSchema, - formattingRules - ); - - // Assert - expect(Object.keys(formattedEntity).length).to.equal(10); - expect(formattedEntity).to.contain.all.keys([ - 'registrationType', 'depth', 'level0', 'level1', 'level2', 'alias', - 'parentId', 'ownerAddress', 'startHeight', 'endHeight' - ]); - return formattedEntity.alias; - }; - - it('formats alias mosaic type', () => { - // Arrange: - const aliasMosaic = { - type: 1, - mosaicId: null - }; - - // Act: - const formattedAlias = formatAlias(aliasMosaic); - - // Assert: - expect(formattedAlias).to.contain.all.keys(['type', 'mosaicId']); - expect(formattedAlias).deep.equal({ - type: 'uint8', - mosaicId: 'uint64HexIdentifier' - }); - }); - - it('formats alias address type', () => { - // Arrange: - const aliasAddress = { - type: 2, - address: null - }; - - // Act: - const formattedAlias = formatAlias(aliasAddress); - - // Assert: - expect(formattedAlias).to.contain.all.keys(['type', 'address']); - expect(formattedAlias).deep.equal({ - type: 'uint8', - address: 'encodedAddress' - }); - }); - - it('formats alias empty type', () => { - // Arrange: - const aliasAddress = { - type: null - }; - - // Act: - const formattedAlias = formatAlias(aliasAddress); - - // Assert: - expect(formattedAlias).to.contain.all.keys(['type']); - expect(formattedAlias).deep.equal({ - type: 'uint8' - }); - }); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - namespace.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds namespace codecs', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codecs were registered - expect(Object.keys(codecs).length).to.equal(3); - expect(codecs).to.contain.all.keys([ - EntityType.aliasAddress.toString(), - EntityType.aliasMosaic.toString(), - EntityType.registerNamespace.toString() - ]); - }); - - const getCodec = entityType => getCodecs()[entityType]; - - describe('supports alias address', () => { - const address = test.random.bytes(test.constants.sizes.addressDecoded); - - test.binary.test.addAll(getCodec(EntityType.aliasAddress), constants.sizes.aliasAddress, () => ({ - buffer: Buffer.concat([ - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // namespace id - Buffer.from(address), // address - Buffer.of(0xCA) // alias action - ]), - - object: { - namespaceId: [0x066C26F2, 0x92B28340], - address, - aliasAction: 0xCA - } - })); - }); - - describe('supports alias mosaic', () => { - test.binary.test.addAll(getCodec(EntityType.aliasMosaic), constants.sizes.aliasMosaic, () => ({ - buffer: Buffer.concat([ - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // namespace id - Buffer.of(0xCA, 0xD0, 0x8E, 0x6E, 0xFF, 0x21, 0x2F, 0x49), // mosaic id - Buffer.of(0xCA) // alias action - ]), - - object: { - namespaceId: [0x066C26F2, 0x92B28340], - mosaicId: [0x6E8ED0CA, 0x492F21FF], - aliasAction: 0xCA - } - })); - }); - - describe('supports register namespace', () => { - const generateTransaction = registrationType => ({ - buffer: Buffer.concat([ - Buffer.of(0xCA, 0xD0, 0x8E, 0x6E, 0xFF, 0x21, 0x2F, 0x49), // duration or parent id - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), // namespace id - Buffer.of(registrationType), // namespace type - Buffer.of(0x06), // namespace name size - Buffer.of(0x6A, 0x61, 0x62, 0x6F, 0x33, 0x38) // namespace name - ]), - - object: { - [registrationType ? 'parentId' : 'duration']: [0x6E8ED0CA, 0x492F21FF], - id: [0x066C26F2, 0x92B28340], - registrationType, - name: 'jabo38' - } - }); - - const addAll = registrationType => { - const size = constants.sizes.registerNamespace + constants.sizes.namespaceName; - test.binary.test.addAll(getCodec(EntityType.registerNamespace), size, () => generateTransaction(registrationType)); - }; - - describe('with root type', () => { - addAll(0x00); - }); - - describe('with child type', () => { - addAll(0x01); - }); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/receipts_spec.js b/catapult-sdk/test/plugins/receipts_spec.js deleted file mode 100644 index 6b034e138..000000000 --- a/catapult-sdk/test/plugins/receipts_spec.js +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const ModelType = require('../../src/model/ModelType'); -const receiptsPlugin = require('../../src/plugins/receipts'); -const schemaFormatter = require('../../src/utils/schemaFormatter'); -const { expect } = require('chai'); - -describe('receipts plugin', () => { - describe('register schema', () => { - it('adds receipts system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - receiptsPlugin.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 15); - expect(modelSchema).to.contain.all.keys([ - 'addressResolutionStatement', - 'addressResolutionStatement.statement', - 'mosaicResolutionStatement', - 'mosaicResolutionStatement.statement', - 'transactionStatement', - 'transactionStatement.statement', - 'statement.meta', - 'receipts.balanceChange', - 'receipts.balanceTransfer', - 'receipts.artifactExpiry', - 'receipts.inflation', - 'receipts.entry.address', - 'receipts.entry.mosaic', - 'receipts.unknown', - 'receipts.source' - ]); - - // - addressResolutionStatement - // - mosaicResolutionStatement - // - transactionStatement - ['addressResolution', 'mosaicResolution', 'transaction'].forEach(statementType => { - expect(Object.keys(modelSchema[`${statementType}Statement`])).deep.equal(['id', 'meta', 'statement']); - expect(modelSchema[`${statementType}Statement`]).to.contain.all.keys(['statement']); - }); - - // - addressResolutionStatement.statement - expect(Object.keys(modelSchema['addressResolutionStatement.statement']).length).to.equal(3); - expect(modelSchema['addressResolutionStatement.statement']).to.contain.all.keys([ - 'height', - 'unresolved', - 'resolutionEntries' - ]); - - // - mosaicResolutionStatement - expect(Object.keys(modelSchema['mosaicResolutionStatement.statement']).length).to.equal(3); - expect(modelSchema['mosaicResolutionStatement.statement']).to.contain.all.keys([ - 'height', - 'unresolved', - 'resolutionEntries' - ]); - - // - transactionStatement - expect(Object.keys(modelSchema['transactionStatement.statement']).length).to.equal(3); - expect(modelSchema['transactionStatement.statement']).to.contain.all.keys([ - 'height', 'source', 'receipts' - ]); - - // - receipts.entry.address - expect(Object.keys(modelSchema['receipts.entry.address']).length).to.equal(2); - expect(modelSchema['receipts.entry.address']).to.contain.all.keys([ - 'source', 'resolved' - ]); - - expect(modelSchema['statement.meta']).to.contain.all.keys([ - 'timestamp' - ]); - - // - receipts.entry.mosaic - expect(Object.keys(modelSchema['receipts.entry.mosaic']).length).to.equal(2); - expect(modelSchema['receipts.entry.mosaic']).to.contain.all.keys([ - 'source', 'resolved' - ]); - - // - receipts.balanceChange - expect(Object.keys(modelSchema['receipts.balanceChange']).length).to.equal(5); - expect(modelSchema['receipts.balanceChange']).to.contain.all.keys([ - 'version', 'type', 'targetAddress', 'mosaicId', 'amount' - ]); - - // - receipts.balanceTransfer - expect(Object.keys(modelSchema['receipts.balanceTransfer']).length).to.equal(6); - expect(modelSchema['receipts.balanceTransfer']).to.contain.all.keys([ - 'version', 'type', 'senderAddress', 'recipientAddress', 'mosaicId', 'amount' - ]); - - // - receipts.artifactExpiry - expect(Object.keys(modelSchema['receipts.artifactExpiry']).length).to.equal(3); - expect(modelSchema['receipts.artifactExpiry']).to.contain.all.keys([ - 'version', 'type', 'artifactId' - ]); - - // - receipts.inflation - expect(Object.keys(modelSchema['receipts.inflation']).length).to.equal(4); - expect(modelSchema['receipts.inflation']).to.contain.all.keys([ - 'version', 'type', 'mosaicId', 'amount' - ]); - - // - receipts.unknown - expect(Object.keys(modelSchema['receipts.unknown']).length).to.equal(2); - expect(modelSchema['receipts.unknown']).to.contain.all.keys([ - 'version', 'type' - ]); - - // - receipts.source - expect(Object.keys(modelSchema['receipts.source']).length).to.equal(2); - expect(modelSchema['receipts.source']).to.contain.all.keys([ - 'primaryId', 'secondaryId' - ]); - }); - }); - - describe('conditional schema', () => { - describe('uses the correct conditional schema depending on receipt type', () => { - const formatReceipt = receipt => { - // Arrange: - const formattingRules = { - [ModelType.none]: () => 'none', - [ModelType.binary]: () => 'binary', - [ModelType.uint64]: () => 'uint64', - [ModelType.uint64HexIdentifier]: () => 'uint64HexIdentifier', - [ModelType.objectId]: () => 'objectId', - [ModelType.string]: () => 'string', - [ModelType.int]: () => 'int', - [ModelType.encodedAddress]: () => 'encodedAddress' - }; - const transactionStatement = { - statement: { - height: null, - source: { primaryId: null, secondaryId: null }, - receipts: [receipt] - } - }; - const builder = new ModelSchemaBuilder(); - - // Act: - receiptsPlugin.registerSchema(builder); - const modelSchema = builder.build(); - const unwrappedFormattedEntity = schemaFormatter.format( - transactionStatement, - modelSchema.transactionStatement, - modelSchema, - formattingRules - ).statement; - - // Assert - expect(Object.keys(unwrappedFormattedEntity).length).to.equal(3); - expect(unwrappedFormattedEntity).to.contain.all.keys(['height', 'source', 'receipts']); - expect(unwrappedFormattedEntity.receipts.length).to.equal(1); - return unwrappedFormattedEntity.receipts[0]; - }; - - it('formats balance transfer receipt type', () => { - // Arrange: - const balanceTransferReceipt = { - version: 1, - type: 0x1000, - senderAddress: null, - recipientAddress: null, - mosaicId: null, - amount: null - }; - - // Act: - const formattedReceipt = formatReceipt(balanceTransferReceipt); - - // Assert: - expect(formattedReceipt).to.contain.all.keys([ - 'version', - 'type', - 'senderAddress', - 'recipientAddress', - 'mosaicId', - 'amount' - ]); - }); - - it('formats balance change receipt type', () => { - // Arrange: - const balanceChangeReceipt = { - version: 1, - type: 0x2000, - targetAddress: null, - mosaicId: null, - amount: null - }; - - // Act: - const formattedReceipt = formatReceipt(balanceChangeReceipt); - - // Assert: - expect(formattedReceipt).to.contain.all.keys([ - 'version', - 'type', - 'targetAddress', - 'mosaicId', - 'amount' - ]); - }); - - it('formats artifact expiry receipt type', () => { - // Arrange: - const artifactExpiryReceipt = { - version: 1, - type: 0x4000, - artifactId: null - }; - - // Act: - const formattedReceipt = formatReceipt(artifactExpiryReceipt); - - // Assert: - expect(formattedReceipt).to.contain.all.keys([ - 'version', - 'type', - 'artifactId' - ]); - }); - - it('formats inflation receipt type', () => { - // Arrange: - const inflationReceipt = { - version: 1, - type: 0x5000, - mosaicId: null, - amount: null - }; - - // Act: - const formattedReceipt = formatReceipt(inflationReceipt); - - // Assert: - expect(formattedReceipt).to.contain.all.keys([ - 'version', - 'type', - 'mosaicId', - 'amount' - ]); - }); - - it('formats unknown receipt type', () => { - // Arrange: - const unknownReceipt = { - version: null, - type: 82356235, - unknownProperty1: null, - unknownProperty2: null - }; - - // Act: - const formattedReceipt = formatReceipt(unknownReceipt); - - // Assert: - expect(formattedReceipt).to.contain.all.keys([ - 'version', - 'type' - ]); - }); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/restrictions_spec.js b/catapult-sdk/test/plugins/restrictions_spec.js deleted file mode 100644 index a947be7ad..000000000 --- a/catapult-sdk/test/plugins/restrictions_spec.js +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const restrictionsPlugin = require('../../src/plugins/restrictions'); -const { AccountRestrictionType } = require('../../src/plugins/restrictions'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -describe('restrictions plugin', () => { - describe('account restriction types enumeration', () => { - it('contains valid values', () => { - const accountRestrictionTypeBlockOffset = 0x8000; - - // Assert: - expect(AccountRestrictionType.addressAllow).to.equal(0x0001); - expect(AccountRestrictionType.addressBlock).to.equal(0x0001 + accountRestrictionTypeBlockOffset); - expect(AccountRestrictionType.mosaicAllow).to.equal(0x0002); - expect(AccountRestrictionType.mosaicBlock).to.equal(0x0002 + accountRestrictionTypeBlockOffset); - expect(AccountRestrictionType.operationAllow).to.equal(0x0004); - expect(AccountRestrictionType.operationBlock).to.equal(0x0004 + accountRestrictionTypeBlockOffset); - }); - }); - - describe('register schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - const accountRestrictionSchemas = [ - 'accountRestriction.addressAccountRestriction', - 'accountRestriction.mosaicAccountRestriction', - 'accountRestriction.operationAccountRestriction' - ]; - - // Act: - restrictionsPlugin.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - it('adds restrictions system schema', () => { - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 15); - expect(modelSchema).to.contain.all.keys([ - 'accountRestrictionAddress', - 'accountRestrictionMosaic', - 'accountRestrictionOperation', - 'accountRestrictions', - 'accountRestriction.restrictions', - 'accountRestriction.fallback', - 'mosaicRestrictions', - 'mosaicRestrictions.entry', - 'mosaicRestrictions.entry.restrictions', - 'mosaicRestrictions.entry.restrictions.restriction' - ].concat(accountRestrictionSchemas)); - }); - - it('adds account restrictions schemas', () => { - // - accountRestrictionAddress - expect(Object.keys(modelSchema.accountRestrictionAddress).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.accountRestrictionAddress).to.contain.all.keys([ - 'version', 'restrictionFlags', 'restrictionAdditions', 'restrictionDeletions' - ]); - - // - accountRestrictionMosaic - expect(Object.keys(modelSchema.accountRestrictionMosaic).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.accountRestrictionMosaic).to.contain.all.keys([ - 'restrictionFlags', 'restrictionAdditions', 'restrictionDeletions' - ]); - - // - accountRestrictionOperation - expect(Object.keys(modelSchema.accountRestrictionOperation).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.accountRestrictionOperation).to.contain.all.keys([ - 'restrictionFlags', 'restrictionAdditions', 'restrictionDeletions' - ]); - - // - accountRestrictions - expect(Object.keys(modelSchema.accountRestrictions).length).to.equal(1); - expect(modelSchema.accountRestrictions).to.contain.all.keys(['accountRestrictions']); - - // - accountRestriction.restrictions - expect(Object.keys(modelSchema['accountRestriction.restrictions']).length).to.equal(3); - expect(modelSchema['accountRestriction.restrictions']).to.contain.all.keys(['version', 'address', 'restrictions']); - - // - accountRestriction address, mosaic, and operation restrictions - accountRestrictionSchemas.forEach(schema => { - expect(Object.keys(modelSchema[schema]).length).to.equal(2); - expect(modelSchema[schema]).to.contain.all.keys(['restrictionFlags', 'values']); - }); - }); - - it('uses the correct conditional account schema depending on restriction type', () => { - // Arrange: - const accountRestrictionSchema = modelSchema['accountRestriction.restrictions'].restrictions.schemaName; - - // Assert: - expect(accountRestrictionSchema({ restrictionFlags: AccountRestrictionType.addressAllow })) - .to.equal('accountRestriction.addressAccountRestriction'); - expect(accountRestrictionSchema({ restrictionFlags: AccountRestrictionType.addressBlock })) - .to.equal('accountRestriction.addressAccountRestriction'); - expect(accountRestrictionSchema({ restrictionFlags: AccountRestrictionType.mosaicAllow })) - .to.equal('accountRestriction.mosaicAccountRestriction'); - expect(accountRestrictionSchema({ restrictionFlags: AccountRestrictionType.mosaicBlock })) - .to.equal('accountRestriction.mosaicAccountRestriction'); - expect(accountRestrictionSchema({ restrictionFlags: AccountRestrictionType.operationAllow })) - .to.equal('accountRestriction.operationAccountRestriction'); - expect(accountRestrictionSchema({ restrictionFlags: AccountRestrictionType.operationBlock })) - .to.equal('accountRestriction.operationAccountRestriction'); - expect(accountRestrictionSchema({ restrictionFlags: 99 })) - .to.equal('accountRestriction.fallback'); - }); - - it('adds mosaic restrictions system schemas', () => { - // - mosaic restriction address transaction - expect(Object.keys(modelSchema.mosaicRestrictionAddress).length).to.equal(Object.keys(modelSchema.transaction).length + 5); - expect(modelSchema.mosaicRestrictionAddress).to.contain.all.keys([ - 'mosaicId', - 'restrictionKey', - 'targetAddress', - 'previousRestrictionValue', - 'newRestrictionValue' - ]); - - // - mosaic restriction global transaction - expect(Object.keys(modelSchema.mosaicRestrictionGlobal).length).to.equal(Object.keys(modelSchema.transaction).length + 7); - expect(modelSchema.mosaicRestrictionGlobal).to.contain.all.keys([ - 'mosaicId', - 'referenceMosaicId', - 'restrictionKey', - 'previousRestrictionValue', - 'newRestrictionValue', - 'previousRestrictionType', - 'newRestrictionType' - ]); - - // - mosaic restrictions - expect(Object.keys(modelSchema.mosaicRestrictions).length).to.equal(2); - expect(modelSchema.mosaicRestrictions).to.contain.all.keys(['id', 'mosaicRestrictionEntry']); - - // - mosaicRestriction.entry - expect(Object.keys(modelSchema['mosaicRestrictions.entry']).length).to.equal(6); - expect(modelSchema['mosaicRestrictions.entry']).to.contain.all.keys([ - 'version', 'compositeHash', 'entryType', 'mosaicId', 'targetAddress', 'restrictions' - ]); - - // - mosaicRestrictions.entry.restrictions - expect(Object.keys(modelSchema['mosaicRestrictions.entry.restrictions']).length).to.equal(3); - expect(modelSchema['mosaicRestrictions.entry.restrictions']).to.contain.all.keys([ - 'key', 'value', 'restriction' - ]); - - // - mosaicRestrictions.entry.restrictions.restriction - expect(Object.keys(modelSchema['mosaicRestrictions.entry.restrictions.restriction']).length).to.equal(3); - expect(modelSchema['mosaicRestrictions.entry.restrictions.restriction']).to.contain.all.keys([ - 'referenceMosaicId', 'restrictionValue', 'restrictionType' - ]); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - restrictionsPlugin.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds restriction codecs (account and mosaic)', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codecs were registered - expect(Object.keys(codecs).length).to.equal(5); - expect(codecs).to.contain.all.keys([ - EntityType.accountRestrictionAddress.toString(), - EntityType.accountRestrictionMosaic.toString(), - EntityType.accountRestrictionOperation.toString(), - EntityType.mosaicRestrictionAddress.toString(), - EntityType.mosaicRestrictionGlobal.toString() - ]); - }); - - describe('account restrictions codecs', () => { - const addressCodec = getCodecs()[EntityType.accountRestrictionAddress]; - const mosaicCodec = getCodecs()[EntityType.accountRestrictionMosaic]; - const operationCodec = getCodecs()[EntityType.accountRestrictionOperation]; - - const generateTransaction = restrictionFlags => { - const data = { - buffer: Buffer.concat([ - Buffer.of(0x00, 0x00), // account restriction type 2b - Buffer.of(0x00), // restrictionAdditions count 1b - Buffer.of(0x00), // restrictionDeletions count 1b - Buffer.of(0x00, 0x00, 0x00, 0x00) // account restriction transaction body reserved 1 4b - ]), - object: { - restrictionFlags, - accountRestrictionTransactionBody_Reserved1: 0, - restrictionAdditions: [], - restrictionDeletions: [] - } - }; - data.buffer.writeUInt32LE(restrictionFlags); - - return data; - }; - - const addNoModificationTests = (restrictionFlags, codec) => { - test.binary.test.addAll(codec, 8, () => generateTransaction(restrictionFlags)); - }; - - const addModificationTests = (restrictionType, codec, additionsBuffer, additionsValues, deletionsBuffer, deletionsValues) => { - const data = generateTransaction(restrictionType); - - data.buffer = Buffer.concat([data.buffer, additionsBuffer, deletionsBuffer]); - - data.buffer.writeUInt8(additionsValues.length, 2); // restrictionAdditionsCount, additions at 2 bytes offset - data.buffer.writeUInt8(deletionsValues.length, 3); // restrictionDeletionsCount, deletions at 3 bytes offset - - data.object.restrictionAdditions = additionsValues; - data.object.restrictionDeletions = deletionsValues; - - const bufferSize = 8 + additionsBuffer.length + deletionsBuffer.length; - - test.binary.test.addAll(codec, bufferSize, () => (data)); - }; - - describe('supports account address restriction with no additions or deletions', () => { - addNoModificationTests(AccountRestrictionType.addressAllow, addressCodec); - }); - - describe('supports account mosaic restriction with no additions or deletions', () => { - addNoModificationTests(AccountRestrictionType.mosaicAllow, mosaicCodec); - }); - - describe('supports account operation restriction with no additions or deletions', () => { - addNoModificationTests(AccountRestrictionType.operationAllow, operationCodec); - }); - - describe('supports account address restriction with one addition and deletion', () => { - const additionTestAddress = test.random.bytes(test.constants.sizes.addressDecoded); - const deletionTestAddress = test.random.bytes(test.constants.sizes.addressDecoded); - - addModificationTests( - AccountRestrictionType.addressAllow, - addressCodec, - Buffer.from(additionTestAddress), - [additionTestAddress], - Buffer.from(deletionTestAddress), - [deletionTestAddress] - ); - }); - - describe('supports account mosaic restriction with one addition and deletion', () => { - addModificationTests( - AccountRestrictionType.mosaicAllow, - mosaicCodec, - Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x92), - [[0x066C26F2, 0x92B28340]], - Buffer.of(0xE3, 0x12, 0x4B, 0x33, 0x25, 0x38, 0x00, 0x12), - [[0x334B12E3, 0x12003825]] - ); - }); - - describe('supports account operation restriction with one addition and deletion', () => { - addModificationTests( - AccountRestrictionType.operationAllow, - operationCodec, - Buffer.of(0xF2, 0x83), - [0x83F2], - Buffer.of(0x03, 0x44), - [0x4403] - ); - }); - - describe('supports account address restriction with several additions and deletions', () => { - const testAddress1 = test.random.bytes(test.constants.sizes.addressDecoded); - const testAddress2 = test.random.bytes(test.constants.sizes.addressDecoded); - const testAddress3 = test.random.bytes(test.constants.sizes.addressDecoded); - const testAddress4 = test.random.bytes(test.constants.sizes.addressDecoded); - const testAddress5 = test.random.bytes(test.constants.sizes.addressDecoded); - - addModificationTests( - AccountRestrictionType.addressAllow, - addressCodec, - Buffer.concat([Buffer.from(testAddress1), Buffer.from(testAddress2), Buffer.from(testAddress3)]), - [testAddress1, testAddress2, testAddress3], - Buffer.concat([Buffer.from(testAddress4), Buffer.from(testAddress5)]), - [testAddress4, testAddress5] - ); - }); - - describe('supports account mosaic restriction with several additions and deletions', () => { - const mosaic1 = Buffer.of(0xF2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x10); - const mosaic2 = Buffer.of(0xB2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x11); - const mosaic3 = Buffer.of(0xD2, 0x26, 0x6C, 0x06, 0x40, 0x83, 0xB2, 0x12); - - const mosaic4 = Buffer.of(0xAA, 0x00, 0x4B, 0x33, 0x25, 0x38, 0x00, 0x13); - const mosaic5 = Buffer.of(0xBB, 0x00, 0x4B, 0x33, 0x25, 0x38, 0x00, 0x14); - - addModificationTests( - AccountRestrictionType.mosaicAllow, - mosaicCodec, - Buffer.concat([mosaic1, mosaic2, mosaic3]), - [[0x066C26F2, 0x10B28340], [0x066C26B2, 0x11B28340], [0x066C26D2, 0x12B28340]], - Buffer.concat([mosaic4, mosaic5]), - [[0x334B00AA, 0x13003825], [0x334B00BB, 0x14003825]] - ); - }); - - describe('supports account operation restriction with several additions and deletions', () => { - addModificationTests( - AccountRestrictionType.operationAllow, - operationCodec, - Buffer.concat([Buffer.of(0xF2, 0x83), Buffer.of(0xAA, 0xBB), Buffer.of(0x01, 0x10)]), - [0x83F2, 0xBBAA, 0x1001], - Buffer.concat([Buffer.of(0x03, 0x44), Buffer.of(0x12, 0x34)]), - [0x4403, 0x3412] - ); - }); - }); - - describe('mosaic restrictions codecs', () => { - const getCodec = entityType => getCodecs()[entityType]; - - describe('supports mosaic restriction address', () => { - const targetAddress = test.random.bytes(test.constants.sizes.addressDecoded); // 24 - - test.binary.test.addAll(getCodec(EntityType.mosaicRestrictionAddress), 56, () => ({ - buffer: Buffer.concat([ - Buffer.of(0xA4, 0x78, 0xB2, 0x05, 0x04, 0x40, 0x38, 0x36), // mosaicId - Buffer.of(0xFF, 0x12, 0x77, 0x31, 0x82, 0x33, 0x32, 0x29), // restrictionKey - Buffer.of(0xD3, 0xA1, 0x3E, 0x35, 0x02, 0x22, 0xC5, 0xC4), // previousRestrictionValue - Buffer.of(0xCC, 0x33, 0xC2, 0x2A, 0x23, 0x32, 0x67, 0xAC), // newRestrictionValue - Buffer.from(targetAddress) // targetAddress 24b - ]), - - object: { - mosaicId: [0x05B278A4, 0x36384004], - restrictionKey: [0x317712FF, 0x29323382], - previousRestrictionValue: [0x353EA1D3, 0xC4C52202], - newRestrictionValue: [0x2AC233CC, 0xAC673223], - targetAddress - } - })); - }); - - describe('supports mosaic restriction global', () => { - test.binary.test.addAll(getCodec(EntityType.mosaicRestrictionGlobal), 42, () => ({ - buffer: Buffer.concat([ - Buffer.of(0x03, 0xC1, 0xC2, 0x33, 0xB2, 0xFF, 0x23, 0xAC), // mosaicId - Buffer.of(0x45, 0x32, 0x27, 0xAA, 0x23, 0xC2, 0x2B, 0xEE), // referenceMosaicId - Buffer.of(0xC4, 0x56, 0x12, 0xB5, 0xF3, 0x3A, 0xA3, 0x01), // restrictionKey - Buffer.of(0xDD, 0x2E, 0x3C, 0x56, 0x77, 0x7F, 0xF7, 0x7F), // previousRestrictionValue - Buffer.of(0x34, 0x03, 0x0F, 0x0C, 0x0C, 0x00, 0x11, 0xB2), // newRestrictionValue - Buffer.of(0x01), // previousRestrictionType - Buffer.of(0x02) // newRestrictionType - ]), - - object: { - mosaicId: [0x33C2C103, 0xAC23FFB2], - referenceMosaicId: [0xAA273245, 0xEE2BC223], - restrictionKey: [0xB51256C4, 0x01A33AF3], - previousRestrictionValue: [0x563C2EDD, 0x7FF77F77], - newRestrictionValue: [0x0C0F0334, 0xB211000C], - previousRestrictionType: 0x01, - newRestrictionType: 0x02 - } - })); - }); - }); - }); -}); diff --git a/catapult-sdk/test/plugins/transfer_spec.js b/catapult-sdk/test/plugins/transfer_spec.js deleted file mode 100644 index 0ca2aa51e..000000000 --- a/catapult-sdk/test/plugins/transfer_spec.js +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EntityType = require('../../src/model/EntityType'); -const ModelSchemaBuilder = require('../../src/model/ModelSchemaBuilder'); -const transfer = require('../../src/plugins/transfer'); -const test = require('../binaryTestUtils'); -const { expect } = require('chai'); - -const constants = { - sizes: { - transfer: 32, - message: 0x6F, - mosaics: 0x50 - }, - offsets: { - messageSize: 2 + 1 + 4 + 1, // messageSize + mosaicsCount + reserved1 + reserved2 - mosaicsCount: 1 + 4 + 1 // mosaicsCount + reserved1 + reserved2 - } -}; - -describe('transfer plugin', () => { - describe('register schema', () => { - it('adds transfer system schema', () => { - // Arrange: - const builder = new ModelSchemaBuilder(); - const numDefaultKeys = Object.keys(builder.build()).length; - - // Act: - transfer.registerSchema(builder); - const modelSchema = builder.build(); - - // Assert: - expect(Object.keys(modelSchema).length).to.equal(numDefaultKeys + 1); - expect(modelSchema).to.contain.all.keys(['transfer']); - - // - transfer - expect(Object.keys(modelSchema.transfer).length).to.equal(Object.keys(modelSchema.transaction).length + 3); - expect(modelSchema.transfer).to.contain.all.keys(['recipientAddress', 'message', 'mosaics']); - }); - }); - - describe('register codecs', () => { - const getCodecs = () => { - const codecs = {}; - transfer.registerCodecs({ - addTransactionSupport: (type, codec) => { codecs[type] = codec; } - }); - - return codecs; - }; - - it('adds transfer codec', () => { - // Act: - const codecs = getCodecs(); - - // Assert: codec was registered - expect(Object.keys(codecs).length).to.equal(1); - expect(codecs).to.contain.all.keys([EntityType.transfer.toString()]); - }); - - const generateTransaction = () => { - const RecipientAddress_Buffer = Buffer.from(test.random.bytes(test.constants.sizes.addressDecoded)); - - return { - buffer: Buffer.concat([ - RecipientAddress_Buffer, - Buffer.of(0x00, 0x00), // message size 2b - Buffer.of(0x00), // num mosaics 1b - Buffer.of(0x00, 0x00, 0x00, 0x00), // transfer transaction body reserved 1 4b - Buffer.of(0x00) // transfer transaction body reserved 2 1b - ]), - - object: { - recipientAddress: RecipientAddress_Buffer, - transferTransactionBody_Reserved1: 0, - transferTransactionBody_Reserved2: 0 - } - }; - }; - - const addMessage = generator => { - const Message_Buffer = Buffer.from([ - 0x99, 0xF2, 0x26, 0x6C, 0x06, 0xBE, 0xE0, 0xE1, 0xC7, 0x39, 0x57, 0xFE, 0x0F, 0x39, 0x7E, 0x7A, - 0xE3, 0x15, 0xEA, 0x51, 0x6B, 0xA7, 0x12, 0xEF, 0x82, 0x7C, 0xE6, 0x2B, 0xD9, 0x5E, 0x01, 0xEC, - 0x31, 0x77, 0xBE, 0xE1, 0xCA, 0xD0, 0x8E, 0x6E, 0x48, 0x95, 0xE8, 0x18, 0xB2, 0x7B, 0xD8, 0xFA, - 0x47, 0x0D, 0xB8, 0xFD, 0x2D, 0x81, 0x47, 0x6A, 0xC5, 0x61, 0xA4, 0xCE, 0xE1, 0x81, 0x40, 0x83, - 0x20, 0x3E, 0xCA, 0x9E, 0x17, 0x1A, 0x02, 0xFB, 0xD4, 0x9C, 0x73, 0x75, 0x5D, 0x82, 0xEE, 0xCE, - 0x63, 0x90, 0x5A, 0x44, 0xA2, 0x7C, 0xF1, 0x3A, 0x7B, 0x77, 0xA9, 0xB3, 0x8A, 0xD1, 0xB2, 0x92, - 0x86, 0xFF, 0x21, 0x2F, 0x49, 0x7A, 0x34, 0x14, 0xC9, 0x88, 0xE7, 0x79, 0x6A, 0x6F, 0xC9 - ]); - - return () => { - const data = generator(); - data.buffer = Buffer.concat([ - data.buffer, - Message_Buffer - ]); - data.buffer.writeUInt16LE(constants.sizes.message, constants.sizes.transfer - constants.offsets.messageSize); - - data.object.message = Buffer.from(Message_Buffer); - return data; - }; - }; - - const addMosaics = generator => { - const Mosaics_Buffer = Buffer.from([ - 0xED, 0x3E, 0x8A, 0xAD, 0xEC, 0xAD, 0xDA, 0x3F, 0x33, 0x05, 0x49, 0x3C, 0x6C, 0x97, 0xAE, 0x94, - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8, - 0x60, 0xD7, 0xFE, 0xCD, 0xC6, 0x44, 0xD7, 0x1A, 0x6B, 0xAD, 0x02, 0xA4, 0x55, 0x96, 0x0C, 0x00, - 0x12, 0xE0, 0x2D, 0x82, 0x8E, 0x54, 0x86, 0xF3, 0x03, 0x81, 0x70, 0xA9, 0xFE, 0x33, 0x12, 0x2F - ]); - - return () => { - const data = generator(); - data.buffer = Buffer.concat([ - data.buffer, - Mosaics_Buffer - ]); - data.buffer.writeUInt8(5, constants.sizes.transfer - constants.offsets.mosaicsCount); - - data.object.mosaics = [ - { id: [0xAD8A3EED, 0x3FDAADEC], amount: [0x3C490533, 0x94AE976C] }, - { id: [0xFEEA00A3, 0xFA5CBDDA], amount: [0x1D944B0D, 0xB151BB15] }, - { id: [0x427264B4, 0x0011FFF1], amount: [0x8F9AD09F, 0xF887353D] }, - { id: [0xCDFED760, 0x1AD744C6], amount: [0xA402AD6B, 0x000C9655] }, - { id: [0x822DE012, 0xF386548E], amount: [0xA9708103, 0x2F1233FE] } - ]; - return data; - }; - }; - - const getCodec = () => getCodecs()[EntityType.transfer]; - - describe('supports transfer', () => { - describe('with neither message nor mosaics', () => { - test.binary.test.addAll(getCodec(), constants.sizes.transfer, generateTransaction); - }); - - describe('with message', () => { - test.binary.test.addAll(getCodec(), constants.sizes.transfer + constants.sizes.message, addMessage(generateTransaction)); - }); - - describe('with mosaics', () => { - test.binary.test.addAll(getCodec(), constants.sizes.transfer + constants.sizes.mosaics, addMosaics(generateTransaction)); - }); - - describe('with message and mosaics', () => { - test.binary.test.addAll( - getCodec(), - constants.sizes.transfer + constants.sizes.message + constants.sizes.mosaics, - addMessage(addMosaics(generateTransaction)) - ); - }); - }); - }); -}); diff --git a/catapult-sdk/test/serializer/BinarySerializer_spec.js b/catapult-sdk/test/serializer/BinarySerializer_spec.js deleted file mode 100644 index 0e89e834e..000000000 --- a/catapult-sdk/test/serializer/BinarySerializer_spec.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const BinarySerializer = require('../../src/serializer/BinarySerializer'); -const { expect } = require('chai'); - -describe('BinarySerializer', () => { - // region constructor - - it('cannot construct binary serializer with non-positive integer size', () => { - // Arrange: - const message = 'BinarySerializer constructor needs integer size > 0'; - const createSerializer = param => new BinarySerializer(param); - - // Assert: - expect(() => { createSerializer(0); }, 'zero size').to.throw(message); - expect(() => { createSerializer(-1); }, 'negative size').to.throw(message); - expect(() => { createSerializer(7.35); }, 'not an integer number').to.throw(message); - expect(() => { createSerializer('foo'); }, 'not a number').to.throw(message); - }); - - it('can construct binary serializer from positive integer', () => { - // Act: - const serializer = new BinarySerializer(123); - - // Assert: - expect(serializer.bufferSize()).to.equal(123); - }); - - // endregion - - // region writeUint8 / writeUint16 / writeUint32 / writeUint64 / writeBuffer - - const addTypeSerializerTests = (name, validData, dataLength, expected) => { - it(`cannot serialize ${name} with insufficient bytes left in buffer`, () => { - // Arrange: consume 1 byte to cause the insufficient buffer size problem - const serializer = new BinarySerializer(dataLength); - serializer.writeUint8(0); - - // Assert: - const message = `insufficient buffer space left (${dataLength} bytes required, ${dataLength - 1} bytes available)`; - expect(() => { serializer[name](validData); }).to.throw(message); - expect(serializer.bufferSize()).to.equal(dataLength); - }); - - it(`can serialize ${name} with sufficient bytes left in buffer`, () => { - // Arrange: - const serializer = new BinarySerializer(dataLength); - - // Act: - serializer[name](validData); - - // Assert: - expect(serializer.bufferSize()).to.equal(dataLength); - expect(serializer.buffer()).to.deep.equal(expected); - }); - - it(`can serialize ${name} with more than sufficient bytes left in buffer`, () => { - // Arrange: - const serializer = new BinarySerializer(dataLength + 2); - - // Act: - serializer[name](validData); - - // Assert: - const expectedBuffer = Buffer.concat([expected, Buffer.from([0x00, 0x00])], dataLength + 2); - expect(serializer.bufferSize()).to.equal(dataLength + 2); - expect(serializer.buffer()).to.deep.equal(expectedBuffer); - }); - }; - - addTypeSerializerTests('writeUint8', 0xDE, 1, Buffer.from([0xDE])); - addTypeSerializerTests('writeUint16', 0xF393, 2, Buffer.from([0x93, 0xF3])); - addTypeSerializerTests('writeUint32', 0x28D6A5F1, 4, Buffer.from([0xF1, 0xA5, 0xD6, 0x28])); - addTypeSerializerTests('writeUint64', [0x38B0FE34, 0x7A01DB67], 8, Buffer.from([0x34, 0xFE, 0xB0, 0x38, 0x67, 0xDB, 0x01, 0x7A])); - addTypeSerializerTests('writeBuffer', Buffer.from([0x1F, 0xEE, 0xC2, 0x34, 0x9D]), 5, Buffer.from([0x1F, 0xEE, 0xC2, 0x34, 0x9D])); - - // endregion - - // region multiple - - it('can serialize empty buffer', () => { - // Arrange: - const serializer = new BinarySerializer(5); - - // Act: - serializer.writeUint8(0xF3); - serializer.writeBuffer(Buffer.from([])); - serializer.writeUint32(0xD18490FB); - - // Assert: - expect(serializer.bufferSize()).to.equal(5); - expect(serializer.buffer()).to.deep.equal(Buffer.from([0xF3, 0xFB, 0x90, 0x84, 0xD1])); - }); - - it('can serialize multiple entities', () => { - // Arrange: - const serializer = new BinarySerializer(10); - - // Act: - serializer.writeUint8(0xF3); - serializer.writeUint32(0xD18490FB); - serializer.writeBuffer(Buffer.from([0xC8, 0x23, 0x6E, 0x5D, 0xA8])); - - // Assert: - expect(serializer.bufferSize()).to.equal(10); - expect(serializer.buffer()).to.deep.equal(Buffer.from([0xF3, 0xFB, 0x90, 0x84, 0xD1, 0xC8, 0x23, 0x6E, 0x5D, 0xA8])); - }); - - // endregion -}); diff --git a/catapult-sdk/test/serializer/SerializedSizeCalculator_spec.js b/catapult-sdk/test/serializer/SerializedSizeCalculator_spec.js deleted file mode 100644 index 33a4f9037..000000000 --- a/catapult-sdk/test/serializer/SerializedSizeCalculator_spec.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const SerializedSizeCalculator = require('../../src/serializer/SerializedSizeCalculator'); -const { expect } = require('chai'); - -describe('EntitySizeCalculator', () => { - const addTypeSerializerTests = (name, validData, expectedSize) => { - it(`can serialize ${name}`, () => { - // Arrange: - const serializer = new SerializedSizeCalculator(); - - // Act: - serializer[name](validData); - - // Assert: - expect(serializer.size()).to.equal(expectedSize); - }); - }; - - addTypeSerializerTests('writeUint8', 0xDE, 1); - addTypeSerializerTests('writeUint16', 0xF393, 2); - addTypeSerializerTests('writeUint32', 0x28D6A5F1, 4); - addTypeSerializerTests('writeUint64', [0x38B0FE34, 0x7A01DB67], 8); - addTypeSerializerTests('writeBuffer', Buffer.from([0x1F, 0xEE, 0xC2, 0x34, 0x9D]), 5); - - it('can serialize multiple entities', () => { - // Act: - const serializer = new SerializedSizeCalculator(); - - // Act: - serializer.writeUint8(0xF3); - serializer.writeUint16(0x45D3); - serializer.writeUint32(0xD18490FB); - serializer.writeUint64([0xA34B06CE, 0xF974A0BC]); - serializer.writeBuffer(Buffer.from([0xC8, 0x23, 0x6E, 0x5D, 0xA8])); - - // Assert: - expect(serializer.size()).to.equal(1 + 2 + 4 + 8 + 5); - }); -}); diff --git a/catapult-sdk/test/testUtils.js b/catapult-sdk/test/testUtils.js deleted file mode 100644 index fcb2a9301..000000000 --- a/catapult-sdk/test/testUtils.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { createKeyPairFromPrivateKeyString } = require('../src/crypto/keyPair'); -const sizes = require('../src/modelBinary/sizes'); -const convert = require('../src/utils/convert'); -const crypto = require('crypto'); - -module.exports = { - constants: { sizes }, - - random: { - bytes: size => crypto.randomBytes(size), - publicKey: () => crypto.randomBytes(sizes.signerPublicKey), - keyPair: () => createKeyPairFromPrivateKeyString(convert.uint8ToHex(crypto.randomBytes(sizes.signerPublicKey))) - }, - - buffer: { - fromSize: size => { - const buffer = Buffer.allocUnsafe(4); - buffer.writeUInt32LE(size); - return buffer; - } - } -}; diff --git a/catapult-sdk/test/utils/SchemaType_spec.js b/catapult-sdk/test/utils/SchemaType_spec.js deleted file mode 100644 index 8500316a7..000000000 --- a/catapult-sdk/test/utils/SchemaType_spec.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const SchemaType = require('../../src/utils/SchemaType'); -const { expect } = require('chai'); - -describe('schema type enumeration', () => { - it('exposes expected types', () => { - // Assert: - expect(SchemaType).to.deep.equal({ - none: 0, - array: 1, - dictionary: 2, - object: 3, - max: 3 - }); - }); -}); diff --git a/catapult-sdk/test/utils/arrayUtils_spec.js b/catapult-sdk/test/utils/arrayUtils_spec.js deleted file mode 100644 index 7ab4f2b1b..000000000 --- a/catapult-sdk/test/utils/arrayUtils_spec.js +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const arrayUtils = require('../../src/utils/arrayUtils'); -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); - -describe('array', () => { - describe('uint8View', () => { - it('can get uint8 view of array buffer', () => { - // Arrange: - const src = convert.hexToUint8('0A12B5675069'); - - // Act: - const view = arrayUtils.uint8View(src.buffer); - - // Assert: - expect(convert.uint8ToHex(view)).to.equal('0A12B5675069'); - }); - - it('can get uint8 view of uint8 typed array', () => { - // Arrange: - const src = convert.hexToUint8('0A12B5675069'); - - // Act: - const view = arrayUtils.uint8View(src); - - // Assert: - expect(convert.uint8ToHex(view)).to.equal('0A12B5675069'); - }); - - it('cannot get uint8 view of arbitrary typed array', () => { - // Arrange: - const src = new Uint16Array(10); - - // Act: - expect(() => arrayUtils.uint8View(src)).to.throw('unsupported type passed to uint8View'); - }); - }); - - describe('copy', () => { - it('can copy full typed array', () => { - // Arrange: - const src = convert.hexToUint8('0A12B5675069'); - const dest = new Uint8Array(src.length); - - // Act: - arrayUtils.copy(dest, src); - - // Assert: - expect(convert.uint8ToHex(dest)).to.equal('0A12B5675069'); - }); - - it('can copy partial typed array when dest is same size as src', () => { - // Arrange: - const src = convert.hexToUint8('0A12B5675069'); - const dest = new Uint8Array(src.length); - - // Act: - arrayUtils.copy(dest, src, 3); - - // Assert: - expect(convert.uint8ToHex(dest)).to.equal('0A12B5000000'); - }); - - it('can copy partial typed array when dest is smaller than src', () => { - // Arrange: - const src = convert.hexToUint8('0A12B5675069'); - const dest = new Uint8Array(4); - - // Act: - arrayUtils.copy(dest, src); - - // Assert: - expect(convert.uint8ToHex(dest)).to.equal('0A12B567'); - }); - - it('can copy partial typed array with custom offsets', () => { - // Arrange: - const src = convert.hexToUint8('0A12B5675069'); - const dest = new Uint8Array(src.length); - - // Act: - arrayUtils.copy(dest, src, 3, 2, 1); - - // Assert: - expect(convert.uint8ToHex(dest)).to.equal('000012B56700'); - }); - }); - - describe('isZero', () => { - it('returns true if typed array is zero', () => { - // Act: - const isZero = arrayUtils.isZero(new Uint16Array(10)); - - // Assert: - expect(isZero).to.equal(true); - }); - - const assertIsNonZero = (length, nonZeroOffset) => { - // Arrange: - const src = new Uint16Array(length); - src[nonZeroOffset] = 2; - - // Act - const isZero = arrayUtils.isZero(src); - - // Assert: - expect(isZero, `nonzero offset ${nonZeroOffset}`).to.equal(false); - }; - - it('returns false if typed array is non zero', () => { - // Assert: - assertIsNonZero(10, 0); - assertIsNonZero(10, 5); - assertIsNonZero(10, 9); - }); - }); - - describe('deepEqual', () => { - it('returns true if typed arrays are equal', () => { - // Arrange: - const lhs = convert.hexToUint8('0A12B5675069'); - const rhs = convert.hexToUint8('0A12B5675069'); - - // Act: - const isEqual = arrayUtils.deepEqual(lhs, rhs); - - // Assert: - expect(isEqual).to.equal(true); - }); - - it('returns false if typed arrays have different sizes', () => { - // Arrange: - const shorter = convert.hexToUint8('0A12B5675069'); - const longer = convert.hexToUint8('0A12B567506983'); - - // Act: - const isEqual1 = arrayUtils.deepEqual(shorter, longer); - const isEqual2 = arrayUtils.deepEqual(longer, shorter); - - // Assert: - expect(isEqual1).to.equal(false); - expect(isEqual2).to.equal(false); - }); - - const assertNotEqual = (lhs, unequalOffset) => { - // Arrange: - const rhs = new Uint8Array(lhs.length); - arrayUtils.copy(rhs, lhs); - rhs[unequalOffset] ^= 0xFF; - - // Act - const isEqual = arrayUtils.deepEqual(lhs, rhs); - - // Assert: - expect(isEqual, `unequal offset ${unequalOffset}`).to.equal(false); - }; - - it('returns false if typed arrays are not equal', () => { - // Arrange: - const lhs = convert.hexToUint8('0A12B5675069'); - - // Assert: - assertNotEqual(lhs, 0); - assertNotEqual(lhs, 3); - assertNotEqual(lhs, 5); - }); - - it('returns true if subset of typed arrays are equal', () => { - // Arrange: different at 2 - const lhs = convert.hexToUint8('0A12B5675069'); - const rhs = convert.hexToUint8('0A12C5675069'); - - // Act: - const isEqualSubset = arrayUtils.deepEqual(lhs, rhs, 2); - const isEqualAll = arrayUtils.deepEqual(lhs, rhs); - - // Assert: - expect(isEqualSubset).to.equal(true); - expect(isEqualAll).to.equal(false); - }); - - it('returns true if subset of typed arrays of different lengths are equal', () => { - // Arrange: - const shorter = convert.hexToUint8('0A12B5'); - const longer = convert.hexToUint8('0A12B567506983'); - - // Act: - const isEqual1 = arrayUtils.deepEqual(shorter, longer, 3); - const isEqual2 = arrayUtils.deepEqual(longer, shorter, 3); - - // Assert: - expect(isEqual1).to.equal(true); - expect(isEqual2).to.equal(true); - }); - - it('returns false if either typed array has fewer elements than requested for comparison', () => { - // Arrange: - const shorter = convert.hexToUint8('0A12B5'); - const longer = convert.hexToUint8('0A12B567506983'); - - // Act: - const isEqual1 = arrayUtils.deepEqual(shorter, longer, 4); - const isEqual2 = arrayUtils.deepEqual(longer, shorter, 4); - - // Assert: - expect(isEqual1).to.equal(false); - expect(isEqual2).to.equal(false); - }); - }); -}); diff --git a/catapult-sdk/test/utils/base32_spec.js b/catapult-sdk/test/utils/base32_spec.js deleted file mode 100644 index c44cffc89..000000000 --- a/catapult-sdk/test/utils/base32_spec.js +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const base32 = require('../../src/utils/base32'); -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); - -describe('base32', () => { - const Test_Vectors = [ - { decoded: '68BA9E8D1AA4502E1F73DA19784B5D7DA16CA1E4AF895FAC12', encoded: 'NC5J5DI2URIC4H3T3IMXQS25PWQWZIPEV6EV7LAS' }, - { decoded: '684C2605E5B366BB94BC30755EC9F50D74E80FC9283D20E283', encoded: 'NBGCMBPFWNTLXFF4GB2V5SPVBV2OQD6JFA6SBYUD' }, - { decoded: '68D7B09A14BEA7CE060E71C0FA9AC9B4226DE167013DE10B3D', encoded: 'NDL3BGQUX2T44BQOOHAPVGWJWQRG3YLHAE66CCZ5' }, - { decoded: '686C44C024F1089669F53C45AC6D62CC17A0D9CBA67A6205E6', encoded: 'NBWEJQBE6EEJM2PVHRC2Y3LCZQL2BWOLUZ5GEBPG' }, - { decoded: '98A0FE84BBFC5EEE7CADC2B12F790DAA4A7A9505096E674FAB', encoded: 'TCQP5BF37RPO47FNYKYS66INVJFHVFIFBFXGOT5L' } - ]; - - describe('encode', () => { - it('can convert empty input', () => { - // Act: - const encoded = base32.encode([]); - - // Assert: - expect(encoded).to.equal(''); - }); - - it('can convert test vectors', () => { - // Arrange: - Test_Vectors.forEach(sample => { - const input = convert.hexToUint8(sample.decoded); - - // Act: - const encoded = base32.encode(input); - - // Assert: - expect(encoded, `input ${sample.decoded}`).to.equal(sample.encoded); - }); - }); - - it('accepts all byte values', () => { - // Arrange: - const data = []; - for (let i = 0; 260 > i; ++i) - data.push(i & 0xFF); - - // Act: - const encoded = base32.encode(data); - - // Assert: - const expected = '' - + 'AAAQEAYEAUDAOCAJBIFQYDIOB4IBCEQTCQKRMFYY' - + 'DENBWHA5DYPSAIJCEMSCKJRHFAUSUKZMFUXC6MBR' - + 'GIZTINJWG44DSOR3HQ6T4P2AIFBEGRCFIZDUQSKK' - + 'JNGE2TSPKBIVEU2UKVLFOWCZLJNVYXK6L5QGCYTD' - + 'MRSWMZ3INFVGW3DNNZXXA4LSON2HK5TXPB4XU634' - + 'PV7H7AEBQKBYJBMGQ6EITCULRSGY5D4QSGJJHFEV' - + 'S2LZRGM2TOOJ3HU7UCQ2FI5EUWTKPKFJVKV2ZLNO' - + 'V6YLDMVTWS23NN5YXG5LXPF5X274BQOCYPCMLRWH' - + 'ZDE4VS6MZXHM7UGR2LJ5JVOW27MNTWW33TO55X7A' - + '4HROHZHF43T6R2PK5PWO33XP6DY7F47U6X3PP6HZ' - + '7L57Z7P674AACAQD'; - expect(encoded).to.equal(expected); - }); - - it('throws if input size is not a multiple of block size', () => { - // Arrange: - for (let i = 2; 10 > i; i += 2) { - const input = new Array(i); - - // Act + Assert: - expect(() => { base32.encode(input); }, `input at ${i}`).to.throw('decoded size must be multiple of 5'); - } - }); - }); - - describe('decode', () => { - it('can convert empty input', () => { - // Act: - const decoded = base32.decode(''); - - // Assert: - expect(convert.uint8ToHex(decoded)).to.equal(''); - }); - - it('can convert test vectors', () => { - // Arrange: - Test_Vectors.forEach(sample => { - // Act: - const decoded = base32.decode(sample.encoded); - - // Assert: - expect(convert.uint8ToHex(decoded), `input ${sample.encoded}`).to.equal(sample.decoded); - }); - }); - - it('accepts all valid characters', () => { - // Act: - const decoded = base32.decode('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'); - - // Assert: - expect(convert.uint8ToHex(decoded)).to.equal('00443214C74254B635CF84653A56D7C675BE77DF'); - }); - - it('throws if input size is not a multiple of block size', () => { - // Arrange: - for (let i = 1; 8 > i; ++i) { - const input = 'A'.repeat(i); - - // Act + Assert: - expect(() => { base32.decode(input); }, `input at ${i}`).to.throw('encoded size must be multiple of 8'); - } - }); - - it('throws if input contains an invalid character', () => { - // Arrange: - const illegalInputs = [ - 'NC5J5DI2URIC4H3T3IMXQS21PWQWZIPEV6EV7LAS', // contains char '1' - 'NBGCMBPFWNTLXFF4GB2V5SPV!V2OQD6JFA6SBYUD', // contains char '!' - 'NDL3BGQUX2T44BQOOHAPVGWJWQRG3YLHAE)6CCZ5' // contains char ')' - ]; - - // Act + Assert: - illegalInputs.forEach(input => { - expect(() => { base32.decode(input); }, `input ${input}`).to.throw('illegal base32 character'); - }); - }); - }); - - describe('roundtrip', () => { - it('decode -> encode', () => { - // Arrange: inputs - const inputs = ['BDS73DQ5NC33MKYI3K6GXLJ53C2HJ35A', '46FNYP7T4DD3SWAO6C4NX62FJI5CBA26']; - inputs.forEach(input => { - // Act: - const decoded = base32.decode(input); - const result = base32.encode(decoded); - - // Assert: - expect(result, `input ${input}`).to.equal(input); - }); - }); - - it('encode -> decode', () => { - // Arrange: inputs - const inputs = ['8A4E7DF5B61CC0F97ED572A95F6ACA', '2D96E4ABB65F0AD3C29FEA48C132CE']; - inputs.forEach(input => { - // Act: - const encoded = base32.encode(convert.hexToUint8(input)); - const result = base32.decode(encoded); - - // Assert: - expect(convert.uint8ToHex(result), `input ${input}`).to.equal(input); - }); - }); - }); -}); diff --git a/catapult-sdk/test/utils/charMapping_spec.js b/catapult-sdk/test/utils/charMapping_spec.js deleted file mode 100644 index baffd3f4c..000000000 --- a/catapult-sdk/test/utils/charMapping_spec.js +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const charMapping = require('../../src/utils/charMapping'); -const { expect } = require('chai'); - -describe('char mapping', () => { - describe('builder', () => { - it('initially has empty map', () => { - // Arrange: - const builder = charMapping.createBuilder(); - - // Act: - const { map } = builder; - - // Assert: - expect(map).to.deep.equal({}); - }); - - it('can add single arbitrary range with zero base', () => { - // Arrange: - const builder = charMapping.createBuilder(); - - // Act: - builder.addRange('d', 'f', 0); - const { map } = builder; - - // Assert: - expect(map).to.deep.equal({ - d: 0, - e: 1, - f: 2 - }); - }); - - it('can add single arbitrary range with nonzero base', () => { - // Arrange: - const builder = charMapping.createBuilder(); - - // Act: - builder.addRange('d', 'f', 17); - const { map } = builder; - - // Assert: - expect(map).to.deep.equal({ - d: 17, - e: 18, - f: 19 - }); - }); - - it('can add multiple arbitrary ranges', () => { - // Arrange: - const builder = charMapping.createBuilder(); - - // Act: - builder.addRange('b', 'b', 8); - builder.addRange('d', 'f', 17); - builder.addRange('y', 'z', 0); - const { map } = builder; - - // Assert: - expect(map).to.deep.equal({ - b: 8, - d: 17, - e: 18, - f: 19, - y: 0, - z: 1 - }); - }); - - it('can add multiple arbitrary overlapping ranges', () => { - // Arrange: - const builder = charMapping.createBuilder(); - - // Act: - builder.addRange('b', 'b', 18); - builder.addRange('d', 'f', 17); - builder.addRange('y', 'z', 19); - const { map } = builder; - - // Assert: - expect(map).to.deep.equal({ - b: 18, - d: 17, - e: 18, - f: 19, - y: 19, - z: 20 - }); - }); - }); -}); diff --git a/catapult-sdk/test/utils/convert_spec.js b/catapult-sdk/test/utils/convert_spec.js deleted file mode 100644 index 211a9140d..000000000 --- a/catapult-sdk/test/utils/convert_spec.js +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const convert = require('../../src/utils/convert'); -const { expect } = require('chai'); - -describe('convert', () => { - describe('toByte', () => { - it('can convert all valid hex char combinations to byte', () => { - // Arrange: - const charToValueMappings = []; - for (let code = '0'.charCodeAt(0); code <= '9'.charCodeAt(0); ++code) - charToValueMappings.push([String.fromCharCode(code), code - '0'.charCodeAt(0)]); - for (let code = 'a'.charCodeAt(0); code <= 'f'.charCodeAt(0); ++code) - charToValueMappings.push([String.fromCharCode(code), code - 'a'.charCodeAt(0) + 10]); - for (let code = 'A'.charCodeAt(0); code <= 'F'.charCodeAt(0); ++code) - charToValueMappings.push([String.fromCharCode(code), code - 'A'.charCodeAt(0) + 10]); - - // Act: - let numTests = 0; - charToValueMappings.forEach(pair1 => { - charToValueMappings.forEach(pair2 => { - // Act: - const byte = convert.toByte(pair1[0], pair2[0]); - - // Assert: - const expected = (pair1[1] * 16) + pair2[1]; - expect(byte, `input: ${pair1[0]}${pair2[0]}`).to.equal(expected); - ++numTests; - }); - }); - - // Sanity: - expect(numTests).to.equal(22 * 22); - }); - - it('cannot convert invalid hex chars to byte', () => { - // Arrange: - const pairs = [['G', '6'], ['7', 'g'], ['*', '8'], ['9', '!']]; - - // Act: - pairs.forEach(pair => { - // Assert: - const message = `input: ${pair[0]}${pair[0]}`; - expect(() => { convert.toByte(pair[0], pair[1]); }, message).to.throw('unrecognized hex char'); - }); - }); - }); - - describe('isHexString', () => { - it('returns true for valid hex strings', () => { - // Arrange: - const inputs = [ - '', - '026ee415fc15', - 'abcdef0123456789ABCDEF' - ]; - - // Act: - inputs.forEach(input => { - const isHexString = convert.isHexString(input); - - // Assert: - expect(isHexString, `input ${input}`).to.equal(true); - }); - }); - - it('returns false for invalid hex strings', () => { - // Arrange: - const inputs = [ - 'abcdef012345G789ABCDEF', // invalid ('G') char - 'abcdef0123456789ABCDE' // invalid (odd) length - ]; - - // Act: - inputs.forEach(input => { - const isHexString = convert.isHexString(input); - - // Assert: - expect(isHexString, `input ${input}`).to.equal(false); - }); - }); - }); - - describe('hexToUint8', () => { - it('can parse empty hex string into array', () => { - // Act: - const actual = convert.hexToUint8(''); - - // Assert: - const expected = Uint8Array.of(); - expect(actual).to.deep.equal(expected); - }); - - it('can parse valid hex string into array', () => { - // Act: - const actual = convert.hexToUint8('026ee415fc15'); - - // Assert: - const expected = Uint8Array.of(0x02, 0x6E, 0xE4, 0x15, 0xFC, 0x15); - expect(actual).to.deep.equal(expected); - }); - - it('can parse valid hex string containing all valid hex characters into array', () => { - // Act: - const actual = convert.hexToUint8('abcdef0123456789ABCDEF'); - - // Assert: - const expected = Uint8Array.of(0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF); - expect(actual).to.deep.equal(expected); - }); - - it('cannot parse hex string with invalid characters into array', () => { - // Assert: - expect(() => { convert.hexToUint8('abcdef012345G789ABCDEF'); }).to.throw('unrecognized hex char'); - }); - - it('cannot parse hex string with invalid size into array', () => { - // Assert: - expect(() => { convert.hexToUint8('abcdef012345G789ABCDE'); }).to.throw('hex string has unexpected size'); - }); - }); - - describe('uint8ToHex', () => { - it('can format empty array into hex string', () => { - // Act: - const actual = convert.uint8ToHex(Uint8Array.of()); - - // Assert: - expect(actual).to.equal(''); - }); - - it('can format single value array into hex string', () => { - // Act: - const actual = convert.uint8ToHex(Uint8Array.of(0xD2)); - - // Assert: - expect(actual).to.equal('D2'); - }); - - it('can format multi value array into hex string', () => { - // Act: - const actual = convert.uint8ToHex(Uint8Array.of(0x02, 0x6E, 0xE4, 0x15, 0xFC, 0x15)); - - // Assert: - expect(actual).to.equal('026EE415FC15'); - }); - }); - - describe('tryParseUint', () => { - const addTryParseSuccessTest = (name, str, expectedValue) => { - it(name, () => { - // Act: - const value = convert.tryParseUint(str); - - // Assert: - expect(value).to.equal(expectedValue); - }); - }; - - addTryParseSuccessTest('can parse decimal string', '14952', 14952); - addTryParseSuccessTest('can parse zero decimal string', '0', 0); - addTryParseSuccessTest('can parse decimal string with all digits', '1234567890', 1234567890); - addTryParseSuccessTest('can parse decimal string with zeros', '10002', 10002); - addTryParseSuccessTest('can parse max safe integer decimal string', Number.MAX_SAFE_INTEGER.toString(), 9007199254740991); - - const addTryParseFailureTest = (name, str) => { - it(name, () => { - // Act: - const value = convert.tryParseUint(str); - - // Assert: - expect(value).to.equal(undefined); - }); - }; - - addTryParseFailureTest('cannot parse decimal string with left padding', ' 14952'); - addTryParseFailureTest('cannot parse decimal string with right padding', '14952 '); - addTryParseFailureTest('cannot parse decimal string too large', '9007199254740992'); - addTryParseFailureTest('cannot parse zeros string', '00'); - addTryParseFailureTest('cannot parse octal string', '0123'); - addTryParseFailureTest('cannot parse hex string', '0x14A52'); - addTryParseFailureTest('cannot parse double string', '14.52'); - addTryParseFailureTest('cannot parse negative decimal string', '-14952'); - addTryParseFailureTest('cannot parse arbitrary string', 'catapult'); - }); - - describe('uint8ToUint32', () => { - it('uint8 array with zero length can be converted to uint32 array', () => { - // Act: - const actual = convert.uint8ToUint32(Uint8Array.of()); - - // Assert: - expect(actual).to.deep.equal(Uint32Array.of()); - }); - - it('uint8 array with length multiple of four can be converted to uint32 array', () => { - // Act: - const actual = convert.uint8ToUint32(Uint8Array.of(0x02, 0x6E, 0x89, 0xAB, 0xCD, 0xEF, 0xE4, 0x15)); - - // Assert: - expect(actual).to.deep.equal(Uint32Array.of(0xAB896E02, 0x15E4EFCD)); - }); - - it('uint8 array with length not multiple of four cannot be converted to uint32 array', () => { - // Assert: - expect(() => { convert.uint8ToUint32(Uint8Array.of(0x02, 0x6E, 0xE4, 0x15, 0x15)); }) - .to.throw('byte length of Uint32Array should be a multiple of 4'); - }); - }); - - describe('uint32ToUint8', () => { - it('uint32 array with zero length can be converted to uint8 array', () => { - // Act: - const actual = convert.uint32ToUint8(Uint32Array.of()); - - // Assert: - expect(actual).to.deep.equal(Uint8Array.of()); - }); - - it('uint32 array with nonzero length can be converted to uint8 array', () => { - // Act: - const actual = convert.uint32ToUint8(Uint32Array.of(0xAB896E02, 0x15E4EFCD)); - - // Assert: - expect(actual).to.deep.equal(Uint8Array.of(0x02, 0x6E, 0x89, 0xAB, 0xCD, 0xEF, 0xE4, 0x15)); - }); - }); - - describe('signed <-> unsigned byte', () => { - const testCases = [ - { signed: -128, unsigned: 0x80, description: 'min negative' }, - { signed: -127, unsigned: 0x81, description: 'min negative plus one' }, - { signed: -87, unsigned: 0xA9, description: 'negative' }, - { signed: -1, unsigned: 0xFF, description: 'negative one' }, - { signed: 0, unsigned: 0, description: 'zero' }, - { signed: 1, unsigned: 0x01, description: 'positive one' }, - { signed: 57, unsigned: 0x39, description: 'positive' }, - { signed: 126, unsigned: 0x7E, description: 'max positive minus one' }, - { signed: 127, unsigned: 0x7F, description: 'max positive' } - ]; - - describe('uint8ToInt8', () => { - const failureTestCases = [ - { input: 256, description: 'one too large' }, - { input: 1000, description: 'very large' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot convert number that is ${testCase.description}`, () => { - // Assert: - expect(() => convert.uint8ToInt8(testCase.input)).to.throw(`input '${testCase.input}' is out of range`); - }); - }); - - testCases.forEach(testCase => { - it(`can convert ${testCase.description}`, () => { - // Act: - const value = convert.uint8ToInt8(testCase.unsigned); - - // Assert: - expect(value).to.equal(testCase.signed); - }); - }); - }); - - describe('int8ToUint8', () => { - const failureTestCases = [ - { input: -1000, description: 'very small' }, - { input: -129, description: 'one too small' }, - { input: 128, description: 'one too large' }, - { input: 1000, description: 'very large' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot convert number that is ${testCase.description}`, () => { - // Assert: - expect(() => convert.int8ToUint8(testCase.input)).to.throw(`input '${testCase.input}' is out of range`); - }); - }); - - testCases.forEach(testCase => { - it(`can convert ${testCase.description}`, () => { - // Act: - const value = convert.int8ToUint8(testCase.signed); - - // Assert: - expect(value).to.equal(testCase.unsigned); - }); - }); - }); - }); - - describe('signed <-> unsigned 16bits integer', () => { - const testCases = [ - { signed: -32768, unsigned: 0x8000, description: 'min negative' }, - { signed: -32767, unsigned: 0x8001, description: 'min negative plus one' }, - { signed: -287, unsigned: 0xFEE1, description: 'negative' }, - { signed: -1, unsigned: 0xFFFF, description: 'negative one' }, - { signed: 0, unsigned: 0, description: 'zero' }, - { signed: 1, unsigned: 0x0001, description: 'positive one' }, - { signed: 257, unsigned: 0x0101, description: 'positive' }, - { signed: 32766, unsigned: 0x7FFE, description: 'max positive minus one' }, - { signed: 32767, unsigned: 0x7FFF, description: 'max positive' } - ]; - - describe('uint16ToInt16', () => { - const failureTestCases = [ - { input: 65536, description: 'one too large' }, - { input: 100000, description: 'very large' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot convert number that is ${testCase.description}`, () => { - // Assert: - expect(() => convert.uint16ToInt16(testCase.input)).to.throw(`input '${testCase.input}' is out of range`); - }); - }); - - testCases.forEach(testCase => { - it(`can convert ${testCase.description}`, () => { - // Act: - const value = convert.uint16ToInt16(testCase.unsigned); - - // Assert: - expect(value).to.equal(testCase.signed); - }); - }); - }); - - describe('int16ToUint16', () => { - const failureTestCases = [ - { input: -100000, description: 'very small' }, - { input: -32769, description: 'one too small' }, - { input: 32768, description: 'one too large' }, - { input: 100000, description: 'very large' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot convert number that is ${testCase.description}`, () => { - // Assert: - expect(() => convert.int16ToUint16(testCase.input)).to.throw(`input '${testCase.input}' is out of range`); - }); - }); - - testCases.forEach(testCase => { - it(`can convert ${testCase.description}`, () => { - // Act: - const value = convert.int16ToUint16(testCase.signed); - - // Assert: - expect(value).to.equal(testCase.unsigned); - }); - }); - }); - }); - - describe('signed <-> unsigned 32bits integer', () => { - const testCases = [ - { signed: -2147483648, unsigned: 0x80000000, description: 'min negative' }, - { signed: -2147483647, unsigned: 0x80000001, description: 'min negative plus one' }, - { signed: -2877657, unsigned: 0xFFD41727, description: 'negative' }, - { signed: -1, unsigned: 0xFFFFFFFF, description: 'negative one' }, - { signed: 0, unsigned: 0, description: 'zero' }, - { signed: 1, unsigned: 0x01, description: 'positive one' }, - { signed: 4565655, unsigned: 0x0045AA97, description: 'positive' }, - { signed: 2147483646, unsigned: 0x7FFFFFFE, description: 'max positive minus one' }, - { signed: 2147483647, unsigned: 0x7FFFFFFF, description: 'max positive' } - ]; - - describe('uint32ToInt32', () => { - const failureTestCases = [ - { input: 4294967296, description: 'one too large' }, - { input: 100000000000, description: 'very large' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot convert number that is ${testCase.description}`, () => { - // Assert: - expect(() => convert.uint32ToInt32(testCase.input)).to.throw(`input '${testCase.input}' is out of range`); - }); - }); - - testCases.forEach(testCase => { - it(`can convert ${testCase.description}`, () => { - // Act: - const value = convert.uint32ToInt32(testCase.unsigned); - - // Assert: - expect(value).to.equal(testCase.signed); - }); - }); - }); - - describe('int32ToUint32', () => { - const failureTestCases = [ - { input: -100000000000, description: 'very small' }, - { input: -2147483649, description: 'one too small' }, - { input: 4294967296, description: 'one too large' }, - { input: 100000000000, description: 'very large' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot convert number that is ${testCase.description}`, () => { - // Assert: - expect(() => convert.int32ToUint32(testCase.input)).to.throw(`input '${testCase.input}' is out of range`); - }); - }); - - testCases.forEach(testCase => { - it(`can convert ${testCase.description}`, () => { - // Act: - const value = convert.int32ToUint32(testCase.signed); - - // Assert: - expect(value).to.equal(testCase.unsigned); - }); - }); - }); - }); -}); diff --git a/catapult-sdk/test/utils/formattingUtils_spec.js b/catapult-sdk/test/utils/formattingUtils_spec.js deleted file mode 100644 index 3f22e869a..000000000 --- a/catapult-sdk/test/utils/formattingUtils_spec.js +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const formattingUtils = require('../../src/utils/formattingUtils'); -const { expect } = require('chai'); - -const createEntity = seed => ({ foo: seed, bar: seed + 1, bazz: seed + 2 }); - -const formatter = { - format: entity => ({ - foo: entity.foo * 2, - bar: entity.bar * 3, - bazz: entity.bazz * 5 - }) -}; - -describe('formatting utils', () => { - describe('format array', () => { - it('can format empty array', () => { - // Act: - const formattedResult = formattingUtils.formatArray(formatter, []); - - // Assert: - expect(formattedResult).to.deep.equal([]); - }); - - it('can format array with single element', () => { - // Arrange: - const entity = createEntity(5); - - // Act: - const formattedResult = formattingUtils.formatArray(formatter, [entity]); - - // Assert: - expect(formattedResult).to.deep.equal([{ foo: 10, bar: 18, bazz: 35 }]); - }); - - it('can format array with multiple elements', () => { - // Arrange: - const entity1 = createEntity(2); - const entity2 = createEntity(5); - const entity3 = createEntity(11); - - // Act: - const formattedResult = formattingUtils.formatArray(formatter, [entity1, entity2, entity3]); - - // Assert: - expect(formattedResult).to.deep.equal([ - { foo: 4, bar: 9, bazz: 20 }, - { foo: 10, bar: 18, bazz: 35 }, - { foo: 22, bar: 36, bazz: 65 }]); - }); - }); - - describe('format page', () => { - it('can format empty page', () => { - // Act: - const formattedResult = formattingUtils.formatPage(formatter, { data: [], pagination: {} }); - - // Assert: - expect(formattedResult).to.deep.equal({ data: [], pagination: {} }); - }); - - it('can format page with single element', () => { - // Arrange: - const entity = createEntity(5); - const paginatedEntity = { - data: [entity], - pagination: { numberOfEntities: 1 } - }; - - // Act: - const formattedResult = formattingUtils.formatPage(formatter, paginatedEntity); - - // Assert: - expect(formattedResult).to.deep.equal({ - data: [{ foo: 10, bar: 18, bazz: 35 }], - pagination: { numberOfEntities: 1 } - }); - }); - - it('can format page with multiple elements', () => { - // Arrange: - const paginatedEntity = { - data: [createEntity(2), createEntity(5), createEntity(11)], - pagination: { numberOfEntities: 3 } - }; - - // Act: - const formattedResult = formattingUtils.formatPage(formatter, paginatedEntity); - - // Assert: - expect(formattedResult).to.deep.equal({ - data: [ - { foo: 4, bar: 9, bazz: 20 }, - { foo: 10, bar: 18, bazz: 35 }, - { foo: 22, bar: 36, bazz: 65 } - ], - pagination: { numberOfEntities: 3 } - }); - }); - }); -}); diff --git a/catapult-sdk/test/utils/future_spec.js b/catapult-sdk/test/utils/future_spec.js deleted file mode 100644 index 82efca994..000000000 --- a/catapult-sdk/test/utils/future_spec.js +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const future = require('../../src/utils/future'); -const { expect } = require('chai'); - -describe('future', () => { - describe('makeRetryable', () => { - const makeRetryable = (numRetries, futureSupplier, waitTimeSupplier) => { - const capture = { - counts: { - futureSupplier: 0, - waitTimeSupplier: 0 - }, - waitTimeParams: [] - }; - - return { - capture, - future: future.makeRetryable( - () => futureSupplier(++capture.counts.futureSupplier), - numRetries, - (i, err) => { - capture.waitTimeParams.push({ id: i, message: err.message }); - return waitTimeSupplier(++capture.counts.waitTimeSupplier); - } - ) - }; - }; - - it('does not retry if future succeeds on first attempt', () => { - // Arrange: - const state = makeRetryable(5, () => Promise.resolve(123), () => 7); - const { counts } = state.capture; - - // Act: - return state.future.then(value => { - // Assert: - expect(counts.futureSupplier).to.equal(1); - expect(counts.waitTimeSupplier).to.equal(0); - expect(value).to.equal(123); - }); - }); - - it('fails if all retry attempts are exhausted', () => { - // Arrange: - const state = makeRetryable(5, id => Promise.reject(Error(`bad future ${id}`)), () => 7); - const { counts } = state.capture; - - // Act: - return state.future - .then(() => { throw Error('future unexpectedly succeded'); }) - .catch(err => { - // Assert: - expect(counts.futureSupplier).to.equal(5); - expect(counts.waitTimeSupplier).to.equal(4); - expect(err.message).to.equal('bad future 5'); - - expect(state.capture.waitTimeParams).to.deep.equal([ - { id: 1, message: 'bad future 1' }, - { id: 2, message: 'bad future 2' }, - { id: 3, message: 'bad future 3' }, - { id: 4, message: 'bad future 4' } - ]); - }); - }); - - it('fails if all retry attempts are exhausted (maxAttempts === 1)', () => { - // Arrange: - const state = makeRetryable(1, id => Promise.reject(Error(`bad future ${id}`)), () => 7); - const { counts } = state.capture; - - // Act: - return state.future - .then(() => { throw Error('future unexpectedly succeded'); }) - .catch(err => { - // Assert: - expect(counts.futureSupplier).to.equal(1); - expect(counts.waitTimeSupplier).to.equal(0); - expect(err.message).to.equal('bad future 1'); - }); - }); - - it('succeeds if some attempts failed but later attempt succeeded', () => { - // Arrange: - const state = makeRetryable(5, id => (3 === id ? Promise.resolve(123) : Promise.reject(Error(`bad future ${id}`))), () => 7); - const { counts } = state.capture; - - // Act: - return state.future.then(value => { - // Assert: - expect(counts.futureSupplier).to.equal(3); - expect(counts.waitTimeSupplier).to.equal(2); - expect(value).to.equal(123); - - expect(state.capture.waitTimeParams).to.deep.equal([ - { id: 1, message: 'bad future 1' }, - { id: 2, message: 'bad future 2' } - ]); - }); - }); - - it('honors supplied wait time', () => { - // Arrange: - const createFutureSupplier = terminalValue => id => - (4 === id ? Promise.resolve(terminalValue) : Promise.reject(Error(`bad future ${id}`))); - - const state1 = makeRetryable(5, createFutureSupplier(111), id => id * id * 4); // 56: 4 + 16 + 36 - const state2 = makeRetryable(5, createFutureSupplier(222), id => id * 7); // ---- 42: 7 + 14 + 21 - const state3 = makeRetryable(5, createFutureSupplier(333), () => 20); // -------- 60: 20 + 20 + 20 - - // Act: - return Promise.race([state1.future, state2.future, state3.future]).then(value => { - // Assert: the second future with the smallest cumulative wait should complete first - expect(value).to.equal(222); - }); - }); - }); -}); diff --git a/catapult-sdk/test/utils/objects_spec.js b/catapult-sdk/test/utils/objects_spec.js deleted file mode 100644 index 62c67c148..000000000 --- a/catapult-sdk/test/utils/objects_spec.js +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const objects = require('../../src/utils/objects'); -const { expect } = require('chai'); - -describe('objects', () => { - const propertyTypeDescriptors = [ - { name: 'undefined', value: undefined }, - { name: 'null', value: null }, - { name: 'numeric', value: 7 }, // sample of a pod (something that does not have type 'object') - { name: 'object', value: { color: 'crimson' } }, - { name: 'array', value: [4, 9, 16] } - ]; - - describe('deepAssign', () => { - const addSimpleTest = (name, target, source) => { - it(name, () => { - // Act: - const result = objects.deepAssign({ foo: target }, { foo: source }); - - // Assert: - expect(result).to.deep.equal({ foo: source }); - }); - }; - - addSimpleTest('pod can replace pod of same type', 9, 4); - - const addLastPropertyTest = (description, value) => { - it(`last object property takes precedence (${description})`, () => { - // Act: - const result = objects.deepAssign({ name: 'alpha' }, { name: 'beta' }, { name: value }); - - // Assert: the value from the last object passed to deepAssign is used - expect(result).to.deep.equal({ name: value }); - }); - }; - - addLastPropertyTest('non-null', 'gamma'); - addLastPropertyTest('null', null); - addLastPropertyTest('undefined', undefined); - - // add tests for all descriptor combinations ensuring that any property type can replace any other property type - propertyTypeDescriptors.forEach(descriptor1 => { - it(`${descriptor1.name} can replace other types`, () => { - // Arrange: - let numTests = 0; - propertyTypeDescriptors.forEach(descriptor2 => { - if (descriptor1 !== descriptor2) { - // Act: - const result = objects.deepAssign({ foo: descriptor2.value }, { foo: descriptor1.value }); - - // Assert: - expect(result).to.deep.equal({ foo: descriptor1.value }); - ++numTests; - } - }); - - // Sanity: one iteration for each different type descriptor - expect(numTests).to.equal(4); - }); - }); - - it('unique properties are merged', () => { - // Act: - const result = objects.deepAssign({ a: 1, b: 2, c: 3 }, { d: 4, e: 5 }, { f: 6 }); - - // Assert: - expect(result).to.deep.equal({ - a: 1, - b: 2, - c: 3, - d: 4, - e: 5, - f: 6 - }); - }); - - it('unique subobject properties are merged', () => { - // Act: - const result = objects.deepAssign({ foo: { a: 1, b: 2, c: 3 } }, { foo: { d: 4, e: 5 } }, { foo: { f: 6 } }); - - // Assert: - expect(result).to.deep.equal({ - foo: { - a: 1, - b: 2, - c: 3, - d: 4, - e: 5, - f: 6 - } - }); - }); - - it('rightmost property values are used', () => { - // Act: - const result = objects.deepAssign({ a: 1, b: 2, c: 3 }, { b: 4, c: 5 }, { b: 6 }); - - // Assert: - expect(result).to.deep.equal({ - a: 1, - b: 6, - c: 5 - }); - }); - - it('rightmost subobject property values are used', () => { - // Act: - const result = objects.deepAssign({ foo: { a: 1, b: 2, c: 3 } }, { foo: { b: 4, c: 5 } }, { foo: { b: 6 } }); - - // Assert: - expect(result).to.deep.equal({ - foo: { - a: 1, - b: 6, - c: 5 - } - }); - }); - - addSimpleTest('shorter array can replace longer array', [1, 2, 6], [4, 9]); - addSimpleTest('longer array can replace shorter array', [4, 9], [1, 2, 6]); - }); - - describe('check schema against template', () => { - const createUnknownPropertyMessage = propertyName => `unknown '${propertyName}' key in config`; - - const createMistypedPropertyMessage = propertyName => `override '${propertyName}' property has wrong type`; - - it('does not allow undefined property to be replaced', () => { - // Arrange: - let numTests = 0; - propertyTypeDescriptors.forEach(descriptor => { - // Act + Assert: - const message = `${descriptor.name} cannot replace undefined`; - expect(() => objects.checkSchemaAgainstTemplate({ foo: undefined }, { foo: descriptor.value }), message) - .to.throw(createUnknownPropertyMessage('foo')); - ++numTests; - }); - - // Sanity: - expect(numTests).to.equal(5); - }); - - it('does not allow property to be replaced by different type', () => { - // Arrange: - let numTests = 0; - propertyTypeDescriptors.forEach(descriptor1 => propertyTypeDescriptors.forEach(descriptor2 => { - if (undefined !== descriptor1.value && descriptor1 !== descriptor2) { - // Act + Assert: - const message = `${descriptor2.name} cannot replace ${descriptor1.name}`; - expect(() => objects.checkSchemaAgainstTemplate({ foo: descriptor1.value }, { foo: descriptor2.value }), message) - .to.throw(createMistypedPropertyMessage('foo')); - ++numTests; - } - })); - - // Sanity: - expect(numTests).to.equal(16); - }); - - const addCompatibleTest = (name, target, source) => { - it(name, () => { - // Act + Assert: - expect(() => objects.checkSchemaAgainstTemplate({ foo: target }, { foo: source })).to.not.throw(); - }); - }; - - addCompatibleTest('allows null to be replaced by null', null, null); - addCompatibleTest('allows numeric to be replaced by numeric', 8, 7); - addCompatibleTest('allows object to be replaced by object', { foo: 6 }, { foo: 9 }); - addCompatibleTest('allows array to be replaced by array', [7, 5], [1, 2, 6]); - - it('does not allow subobject property to be replaced by different type', () => { - // Act + Assert: - expect(() => objects.checkSchemaAgainstTemplate({ foo: { bar: 6 } }, { foo: { bar: 'red' } })) - .to.throw(createMistypedPropertyMessage('bar')); - }); - - it('allows template-only property', () => { - // Act + Assert: bar is only in template - expect(() => objects.checkSchemaAgainstTemplate({ foo: 6, bar: 8 }, { foo: 7 })).to.not.throw(); - }); - - it('does not allow override-only property', () => { - // Act + Assert: bar is only in override object - expect(() => objects.checkSchemaAgainstTemplate({ foo: 6 }, { foo: 7, bar: 8 })) - .to.throw(createUnknownPropertyMessage('bar')); - }); - }); -}); diff --git a/catapult-sdk/test/utils/schemaFormatter_spec.js b/catapult-sdk/test/utils/schemaFormatter_spec.js deleted file mode 100644 index b60c0e1d1..000000000 --- a/catapult-sdk/test/utils/schemaFormatter_spec.js +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const SchemaType = require('../../src/utils/SchemaType'); -const schemaFormatter = require('../../src/utils/schemaFormatter'); -const { expect } = require('chai'); - -describe('schema formatter', () => { - describe('basic triggering', () => { - const assertFormattingRuleIsTriggered = (propertyType, propertySchema) => { - // Arrange: set up a formatting rule for the foo property type - const sample = { foo: [1, 2] }; - const schema = { foo: propertySchema }; - const formattingRules = { [propertyType]: value => value[0] }; - - // Act: - const format = schemaFormatter.format(sample, schema, {}, formattingRules); - - // Assert: - expect(format).to.deep.equal({ foo: 1 }); - }; - - it('can format property with custom type (number) in schema with matching formatting rule', () => { - // Assert: - assertFormattingRuleIsTriggered(111, 111); - }); - - it('can format property with custom type (object) in schema with matching formatting rule', () => { - // Assert: - assertFormattingRuleIsTriggered(111, { type: 111 }); - }); - - it('can format property with with type of value 0 (ModelType.none)', () => { - // Assert: - assertFormattingRuleIsTriggered(0, 0); - }); - - it('drops property if not defined in the schema', () => { - // Arrange: set up a formatting rule for the foo property type - const sample = { foo: [1, 2], bar: 3 }; - const schema = { foo: { type: 111 } }; - const formattingRules = { 111: value => value[0] }; - - // Act: - const format = schemaFormatter.format(sample, schema, {}, formattingRules); - - // Assert: - expect(format).to.deep.equal({ foo: 1 }); - }); - - it('can rename formatted property', () => { - // Arrange: set up a formatting rule for the foo property type - const sample = { foo: [1, 2] }; - const schema = { foo: { type: 112, resultKey: 'bar' } }; - const formattingRules = { 112: value => value[0] }; - - // Act: - const format = schemaFormatter.format(sample, schema, {}, formattingRules); - - // Assert: - expect(format).to.deep.equal({ bar: 1 }); - }); - }); - - describe('basic not triggering', () => { - const assertFormattingRuleIsNotTriggered = (propertyType, propertySchema) => { - // Arrange: set up a formatting rule for the foo property type - const sample = { foo: [1, 2] }; - const schema = { foo: propertySchema }; - const formattingRules = { [propertyType]: value => value[0] }; - - // Act: - const format = schemaFormatter.format(sample, schema, {}, formattingRules); - - // Assert: - expect(format).to.deep.equal({}); - }; - - it('ignores property with custom type (number) in schema without matching formatting rule', () => { - // Assert: - assertFormattingRuleIsNotTriggered(SchemaType.none, 111); - }); - - it('ignores property with custom type (object) in schema without matching formatting rule', () => { - // Assert: - assertFormattingRuleIsNotTriggered(SchemaType.none, { type: 111 }); - }); - - it('ignores property not in schema without default formatting rule', () => { - // Assert: - assertFormattingRuleIsNotTriggered(111, undefined); - }); - }); - - describe('nested formatting', () => { - describe('object', () => { - it('can format sub object', () => { - // Arrange: - const sample = { sub: { foo: 7 } }; - const schema = { sub: { type: SchemaType.object, schemaName: 'abc' } }; - const schemaDictionary = { abc: { foo: 11 } }; - const formattingRules = { 11: value => 2 * value }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ sub: { foo: 14 } }); - }); - - it('can format nested sub object (outer object same type)', () => { - // Arrange: - const subObjectPropertySchema = { type: SchemaType.object, schemaName: 'abc' }; - const sample = { sub: { foo: 7, sub2: { foo: 9 } } }; - const schema = { sub: subObjectPropertySchema }; - const schemaDictionary = { abc: { foo: 11, sub2: subObjectPropertySchema } }; - const formattingRules = { 11: value => 2 * value }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ sub: { foo: 14, sub2: { foo: 18 } } }); - }); - - it('can format nested sub object (outer object different type)', () => { - // Arrange: - const sample = { sub: { foo: 7, sub2: { bar: 9 } } }; - const schema = { sub: { type: SchemaType.object, schemaName: 'abc' } }; - const schemaDictionary = { - abc: { foo: 11, sub2: { type: SchemaType.object, schemaName: 'def' } }, - def: { bar: 12 } - }; - const formattingRules = { - 11: value => 2 * value, - 12: value => value * value - }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ sub: { foo: 14, sub2: { bar: 81 } } }); - }); - }); - - describe('array', () => { - const assertCanFormatArray = (originalArray, formattedArray, schemaName, schemaDictionary) => { - // Arrange: - const sample = { subarray: originalArray }; - const schema = { subarray: { type: SchemaType.array, schemaName } }; - const formattingRules = { 7: value => value[0] }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ subarray: formattedArray }); - }; - - it('can format empty sub array', () => { - // Assert: - assertCanFormatArray([], [], 'abc', { abc: { l: 7 } }); - }); - - it('can format non-empty sub array of objects', () => { - // Assert: - assertCanFormatArray( - [{ l: 'alpha' }, { l: 'beta' }, { l: 'gamma' }], - [{ l: 'a' }, { l: 'b' }, { l: 'g' }], - 'abc', - { abc: { l: 7 } } - ); - }); - - it('can format non-empty sub array of values', () => { - // Assert: - assertCanFormatArray( - ['alpha', 'beta', 'gamma'], - ['a', 'b', 'g'], - 7, - 7 - ); - }); - }); - - describe('dictionary', () => { - const assertCanFormatDictionary = (originalDictionary, formattedDictionary, schemaName, schemaDictionary) => { - // Arrange: - const sample = { subdictionary: originalDictionary }; - const schema = { subdictionary: { type: SchemaType.dictionary, schemaName } }; - const formattingRules = { 7: value => value[0] }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ subdictionary: formattedDictionary }); - }; - - it('can format empty dictionary', () => { - // Assert: - assertCanFormatDictionary({}, {}, 'abc', { abc: { l: 7 } }); - }); - - it('can format non-empty dictionary of objects', () => { - // Assert: - assertCanFormatDictionary( - { x: { l: 'alpha' }, y: { l: 'beta' }, z: { l: 'gamma' } }, - { x: { l: 'a' }, y: { l: 'b' }, z: { l: 'g' } }, - 'abc', - { abc: { l: 7 } } - ); - }); - - it('can format non-empty dictionary of values', () => { - // Assert: - assertCanFormatDictionary( - { x: 'alpha', y: 'beta', z: 'gamma' }, - { x: 'a', y: 'b', z: 'g' }, - 7, - 7 - ); - }); - }); - - it('can use conditional schema', () => { - // Arrange: - const sample1 = { transaction: { type: 1, value: 5 } }; - const sample2 = { transaction: { type: 2, value: 7 } }; - const schemaDictionary = { - type1: { value: 12345 }, - type2: { value: 54321 } - }; - const schema = { - transaction: { - type: SchemaType.object, - schemaName: entity => (1 === entity.type ? 'type1' : 'type2') - } - }; - const formattingRules = { - 12345: value => value + 10, - 54321: value => value + 100 - }; - - // Act: - const format1 = schemaFormatter.format(sample1, schema, schemaDictionary, formattingRules); - const format2 = schemaFormatter.format(sample2, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format1).to.deep.equal({ transaction: { value: 15 } }); - expect(format2).to.deep.equal({ transaction: { value: 107 } }); - }); - - it('can use conditional schema within arrays', () => { - // Arrange: - const sample = { subarray: [{ type: 1, value: 5 }, { type: 2, value: 7 }] }; - const schemaDictionary = { type1: { value: 12345 }, type2: { value: 54321 } }; - const schema = { - subarray: { - type: SchemaType.array, - schemaName: entity => (1 === entity.type ? 'type1' : 'type2') - } - }; - const formattingRules = { - 12345: value => value + 10, - 54321: value => value + 100 - }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ subarray: [{ value: 15 }, { value: 107 }] }); - }); - - it('can mix multiple rules', () => { - // Arrange: - const sample = { - bytes: Uint8Array.of(0xA5, 0xB2, 0x18), - u64: [1, 2], - other: 'abc', - sub: { foo: 7, sub2: { foo: 9 } }, - subarray: [{ l: 'alpha' }, { l: 'beta' }, { l: 'gamma' }] - }; - const schema = { - bytes: 7, - u64: 8, - sub: { type: SchemaType.object, resultKey: 'f', schemaName: 'def' }, - subarray: { type: SchemaType.array, resultKey: 'chs', schemaName: 'abc' } - }; - const schemaDictionary = { - abc: { l: { type: 11, resultKey: 'ch' } }, - def: { foo: { type: 12, resultKey: 'sq' } } - }; - const formattingRules = { - 7: value => value[0].toString(), - 8: value => value[0] + (value[1] * 10), - 11: value => value[1], - 12: value => value * value - }; - - // Act: - const format = schemaFormatter.format(sample, schema, schemaDictionary, formattingRules); - - // Assert: - expect(format).to.deep.equal({ - bytes: '165', - u64: 21, - f: { sq: 49 }, - chs: [{ ch: 'l' }, { ch: 'e' }, { ch: 'a' }] - }); - }); - }); -}); diff --git a/catapult-sdk/test/utils/uint64_spec.js b/catapult-sdk/test/utils/uint64_spec.js deleted file mode 100644 index 88d66051d..000000000 --- a/catapult-sdk/test/utils/uint64_spec.js +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const convert = require('../../src/utils/convert'); -const uint64 = require('../../src/utils/uint64'); -const { expect } = require('chai'); - -describe('uint64', () => { - describe('compact', () => { - it('can compact 32 bit value', () => { - // Act: - const result = uint64.compact([0x12345678, 0x00000000]); - - // Assert: - expect(result).to.equal(0x12345678); - }); - - it('can compact less than max safe integer', () => { - // Act: - const result = uint64.compact([0x00ABCDEF, 0x000FDFFF]); - - // Assert: - expect(result).to.equal(0xFDFFF00ABCDEF); - }); - - it('can compact max safe integer', () => { - // Sanity: - expect(0x1FFFFFFFFFFFFF).to.equal(Number.MAX_SAFE_INTEGER); - - // Act: - const result = uint64.compact([0xFFFFFFFF, 0x001FFFFF]); - - // Assert: - expect(result).to.equal(Number.MAX_SAFE_INTEGER); - }); - - it('cannot compact min unsafe integer', () => { - // Sanity: - expect(0x0020000000000000 + 1).to.equal(0x0020000000000000); - - // Act: - const result = uint64.compact([0x00000000, 0x00200000]); - - // Assert: - expect(result).to.deep.equal([0x00000000, 0x00200000]); - }); - - it('cannot compact greater than min unsafe integer', () => { - // Act: - const result = uint64.compact([0xF0000000, 0x01000D00]); - - // Assert: - expect(result).to.deep.equal([0xF0000000, 0x01000D00]); - }); - }); - - describe('fromUint', () => { - const failureTestCases = [ - { number: 0x0020000000000000, description: 'min unsafe integer' }, - { number: 0x01000D00F0000000, description: 'greater than min unsafe integer' }, - { number: -1, description: 'negative' }, - { number: 1234.56, description: 'floating point' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot parse number that is ${testCase.description}`, () => { - // Assert: - expect(() => uint64.fromUint(testCase.number)).to.throw(`number cannot be converted to uint '${testCase.number}'`); - }); - }); - - const successTestCases = [ - { number: 0, uint64: [0, 0], description: '0' }, - { number: 0xA1B2, uint64: [0xA1B2, 0], description: '(0, 8)' }, - { number: 0x12345678, uint64: [0x12345678, 0], description: '8' }, - { number: 0xABCD12345678, uint64: [0x12345678, 0xABCD], description: '(8, 16)' }, - { number: 0x0014567890ABCDEF, uint64: [0x90ABCDEF, 0x00145678], description: '14' }, - { number: Number.MAX_SAFE_INTEGER, uint64: [0xFFFFFFFF, 0x001FFFFF], description: '14 (max value)' } - ]; - - successTestCases.forEach(testCase => { - it(`can parse numeric with ${testCase.description} significant digits`, () => { - // Act: - const value = uint64.fromUint(testCase.number); - - // Assert: - expect(value).to.deep.equal(testCase.uint64); - }); - }); - }); - - const hexTestCases = [ - { str: '0000000000000000', value: [0, 0], description: '0' }, - { str: '000000000000A1B2', value: [0xA1B2, 0], description: '(0, 8)' }, - { str: '0000000012345678', value: [0x12345678, 0], description: '8' }, - { str: '0000ABCD12345678', value: [0x12345678, 0xABCD], description: '(8, 16)' }, - { str: '1234567890ABCDEF', value: [0x90ABCDEF, 0x12345678], description: '16' }, - { str: 'FFFFFFFFFFFFFFFF', value: [0xFFFFFFFF, 0xFFFFFFFF], description: '16 (max value)' } - ]; - - describe('fromBytes', () => { - hexTestCases.forEach(testCase => { - it(`can parse byte array with ${testCase.description} significant digits`, () => { - // Arrange: prepare little-endian bytes - const bytes = convert.hexToUint8(testCase.str).reverse(); - - // Act: - const value = uint64.fromBytes(bytes); - - // Assert: - expect(value).to.deep.equal(testCase.value); - }); - }); - - it('cannot parse byte array with invalid size into uint64', () => { - // Arrange: - const errorMessage = 'byte array has unexpected size'; - - // Assert: - [0, 3, 4, 5, 7, 9].forEach(size => { - expect(() => { uint64.fromBytes(new Uint8Array(size)); }, `size ${size}`).to.throw(errorMessage); - }); - }); - }); - - describe('toBytes', () => { - it('can parse uint64 to Uint8Array', () => { - const result = uint64.toBytes([0x00ABCDEF, 0x000FDFFF]); - expect(result).to.deep.equal(new Uint8Array([0xEF, 0xCD, 0xAB, 0x00, 0xFF, 0xDF, 0x0F, 0x00])); - }); - }); - - describe('fromBytes32', () => { - const fromBytes32TestCases = [ - { str: '00000000', value: [0, 0], description: '0' }, - { str: '0000A1B2', value: [0xA1B2, 0], description: '(0, 8)' }, - { str: '12345678', value: [0x12345678, 0], description: '8' }, - { str: 'FFFFFFFF', value: [0xFFFFFFFF, 0], description: '8 (max value)' } - ]; - - fromBytes32TestCases.forEach(testCase => { - it(`can parse byte array with ${testCase.description} significant digits`, () => { - // Arrange: prepare little-endian bytes - const bytes = convert.hexToUint8(testCase.str).reverse(); - - // Act: - const value = uint64.fromBytes32(bytes); - - // Assert: - expect(value).to.deep.equal(testCase.value); - }); - }); - - it('cannot parse byte array with invalid size into uint64', () => { - // Arrange: - const errorMessage = 'byte array has unexpected size'; - - // Assert: - [0, 3, 5, 7, 8, 9].forEach(size => { - expect(() => { uint64.fromBytes32(new Uint8Array(size)); }, `size ${size}`).to.throw(errorMessage); - }); - }); - }); - - describe('fromHex', () => { - hexTestCases.forEach(testCase => { - it(`can parse hex string with ${testCase.description} significant digits`, () => { - // Act: - const value = uint64.fromHex(testCase.str); - - // Assert: - expect(value).to.deep.equal(testCase.value); - }); - }); - - it('cannot parse hex string with invalid characters into uint64', () => { - // Assert: - expect(() => { uint64.fromHex('0000000012345G78'); }).to.throw('unrecognized hex char'); // contains 'G' - }); - - it('cannot parse hex string with invalid size into uint64', () => { - // Arrange: - const errorMessage = 'hex string has unexpected size'; - - // Assert: - expect(() => { uint64.fromHex(''); }).to.throw(errorMessage); // empty string - expect(() => { uint64.fromHex('1'); }).to.throw(errorMessage); // odd number of chars - expect(() => { uint64.fromHex('ABCDEF12'); }).to.throw(errorMessage); // too short - expect(() => { uint64.fromHex('1234567890ABCDEF12'); }).to.throw(errorMessage); // too long - }); - }); - - describe('toHex', () => { - hexTestCases.forEach(testCase => { - it(`can format hex string with ${testCase.description} significant digits`, () => { - // Act: - const str = uint64.toHex(testCase.value); - - // Assert: - expect(str).to.equal(testCase.str); - }); - }); - }); - - describe('isZero', () => { - const zeroTestCases = [ - { description: 'low and high are zero', value: [0, 0], isZero: true }, - { description: 'low is nonzero and high is zero', value: [1, 0], isZero: false }, - { description: 'low is zero and high is nonzero', value: [0, 1], isZero: false }, - { description: 'low and high are nonzero', value: [74, 12], isZero: false } - ]; - - zeroTestCases.forEach(testCase => { - it(`returns ${testCase.isZero} when ${testCase.description}`, () => { - // Act: - const isZero = uint64.isZero(testCase.value); - - // Assert: - expect(isZero).to.equal(testCase.isZero); - }); - }); - }); - - describe('toString', () => { - const successTestCases = [ - { str: '0', value: [0, 0], description: 'min value' }, - { str: '4294967295', value: [4294967295, 0], description: '8 significant digits' }, - { str: '18446744069414584320', value: [0, 4294967295], description: '(0, 8) significant digits' }, - { str: '193338964773', value: [65436453, 45], description: 'number' }, - { str: '12774881867138931535', value: [3127188303, 2974383967], description: 'big number' }, - { str: '18446744073709551615', value: [4294967295, 4294967295], description: 'max value' } - ]; - - successTestCases.forEach(testCase => { - it(`can parse uint64 values to string (${testCase.description})`, () => { - expect(uint64.toString(testCase.value)).to.deep.equal(testCase.str); - }); - }); - }); - - describe('fromString', () => { - const failureTestCases = [ - { str: '', value: [4294967295, 4294967295], description: 'empty string' }, - { str: undefined, value: [4294967295, 4294967295], description: 'undefined string' }, - { str: null, value: [4294967295, 4294967295], description: 'null string' }, - { str: '3546.5446', value: [4294967295, 4294967295], description: 'decimals' }, - { str: '35,44,56\'46.5446', value: [4294967295, 4294967295], description: 'wrong characters' }, - { str: 's4565678', value: [4294967295, 4294967295], description: 'wrong string' } - ]; - - failureTestCases.forEach(testCase => { - it(`cannot parse numeric strings into uint64 (${testCase.description})`, () => { - expect(() => uint64.fromString(testCase.str)).to.throw(`input string is not a valid numeric string '${testCase.str}'`); - }); - }); - - const successTestCases = [ - { str: '0', value: [0, 0], description: 'min value' }, - { str: '5678', value: [5678, 0], description: 'small number' }, - { str: '8765873000863846', value: [3663517798, 2040963], description: 'big number' }, - { str: '4294967295', value: [4294967295, 0], description: 'max 32 bits' }, - { str: '9007199254740993', value: [1, 2097152], description: 'max safe intger + 2' }, - { str: '18446744073709551615', value: [4294967295, 4294967295], description: 'max value' } - ]; - - successTestCases.forEach(testCase => { - it(`can parse numeric strings into uint64 (${testCase.description})`, () => { - expect(uint64.fromString(testCase.str)).to.deep.equal(testCase.value); - }); - }); - }); - - describe('compare', () => { - const successTestCases = [ - { a: '0', b: '0', value: 0 }, - { a: '20', b: '10', value: 1 }, - { a: '10', b: '20', value: -1 }, - { a: '20', b: '20', value: 0 }, - { a: '18446744073709500000', b: '438', value: 1 }, - { a: '438', b: '18446744073709500000', value: -1 }, - { a: '18446744073709551615', b: '438', value: 1 }, - { a: '438', b: '18446744073709551615', value: -1 }, - { a: '18446744073709551615', b: '18446744073709551615', value: 0 } - ]; - - successTestCases.forEach(testCase => { - it(`compare (${testCase.a}) and (${testCase.b} should be (${testCase.value})`, () => { - const a = uint64.fromString(testCase.a); - const b = uint64.fromString(testCase.b); - expect(uint64.compare(a, b)).to.equal(testCase.value); - }); - }); - }); - - describe('multiply', () => { - const successTestCases = [ - { - factorA: [0, 0], - factorB: [0, 0], - result: [0, 0], - description: 'min value' - }, - { - factorA: [25, 0], - factorB: [4, 0], - result: [100, 0], - description: 'small value' - }, - { - factorA: [4294967295, 0], - factorB: [4294967295, 0], - result: [1, 4294967294], - description: 'big value' - }, - { - factorA: [16843009, 16843009], - factorB: [255, 0], - result: [4294967295, 4294967295], - description: 'max value' - } - ]; - - successTestCases.forEach(testCase => { - it(`can multiply uint64 values (${testCase.description})`, () => { - expect(uint64.multiply(testCase.factorA, testCase.factorB)).to.deep.equal(testCase.result); - }); - }); - }); -}); diff --git a/catapult-sdk/yarn.lock b/catapult-sdk/yarn.lock deleted file mode 100644 index 947d5a0d4..000000000 --- a/catapult-sdk/yarn.lock +++ /dev/null @@ -1,2953 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/generator@^7.15.4", "@babel/generator@^7.4.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.4.tgz#85acb159a267ca6324f9793986991ee2022a05b0" - integrity sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw== - dependencies: - "@babel/types" "^7.15.4" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-function-name@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" - integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== - dependencies: - "@babel/helper-get-function-arity" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/helper-get-function-arity@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" - integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-hoist-variables@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" - integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-split-export-declaration@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" - integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.15.4", "@babel/parser@^7.4.3": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae" - integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g== - -"@babel/runtime-corejs3@^7.10.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz#403139af262b9a6e8f9ba04a6fdcebf8de692bf1" - integrity sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg== - dependencies: - core-js-pure "^3.16.0" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.15.4", "@babel/template@^7.4.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" - integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/traverse@^7.4.3": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" - integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.15.4", "@babel/types@^7.4.0": - version "7.15.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" - integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== - dependencies: - "@babel/helper-validator-identifier" "^7.14.9" - to-fast-properties "^2.0.0" - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -acorn-jsx@^5.2.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== - dependencies: - default-require-extensions "^2.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - -array-includes@^3.1.1, array-includes@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array.prototype.flat@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" - integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -array.prototype.flatmap@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" - integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -axe-core@^4.0.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" - integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -caching-transform@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-3.0.2.tgz#601d46b91eca87687a281e71cef99791b0efca70" - integrity sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w== - dependencies: - hasha "^3.0.0" - make-dir "^2.0.0" - package-hash "^3.0.0" - write-file-atomic "^2.4.2" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chai@^4.2.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.0.0, chalk@^2.1.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -confusing-browser-globals@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" - integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== - -convert-source-map@^1.6.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -core-js-pure@^3.16.0: - version "3.18.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.1.tgz#097d34d24484be45cea700a448d1e74622646c80" - integrity sha512-kmW/k8MaSuqpvA1xm2l3TVlBuvW+XBkcaOroFUpO3D4lsTGQWBTb/tBDCf/PNkkPLrwgrkQRIYNPB0CeqGJWGQ== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -coveralls@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.1.tgz#f5d4431d8b5ae69c5079c8f8ca00d64ac77cf081" - integrity sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww== - dependencies: - js-yaml "^3.13.1" - lcov-parse "^1.0.0" - log-driver "^1.2.7" - minimist "^1.2.5" - request "^2.88.2" - -cp-file@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.2.0.tgz#40d5ea4a1def2a9acdd07ba5c0b0246ef73dc10d" - integrity sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA== - dependencies: - graceful-fs "^4.1.2" - make-dir "^2.0.0" - nested-error-stacks "^2.0.0" - pify "^4.0.1" - safe-buffer "^5.0.1" - -cross-env@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d" - integrity sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ== - dependencies: - cross-spawn "^6.0.5" - -cross-spawn@^4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -damerau-levenshtein@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" - integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@4.3.2, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -diff@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.0.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-airbnb-base@^14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" - integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-config-airbnb@^18.1.0: - version "18.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9" - integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== - dependencies: - eslint-config-airbnb-base "^14.2.1" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== - dependencies: - debug "^3.2.7" - pkg-dir "^2.0.0" - -eslint-plugin-import@^2.19.1: - version "2.24.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" - integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== - dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" - has "^1.0.3" - is-core-module "^2.6.0" - minimatch "^3.0.4" - object.values "^1.1.4" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" - resolve "^1.20.0" - tsconfig-paths "^3.11.0" - -eslint-plugin-jsx-a11y@^6.2.3: - version "6.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" - integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== - dependencies: - "@babel/runtime" "^7.11.2" - aria-query "^4.2.2" - array-includes "^3.1.1" - ast-types-flow "^0.0.7" - axe-core "^4.0.2" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.6" - emoji-regex "^9.0.0" - has "^1.0.3" - jsx-ast-utils "^3.1.0" - language-tags "^1.0.5" - -eslint-plugin-react-hooks@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0" - integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g== - -eslint-plugin-react@^7.19.0: - version "7.26.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e" - integrity sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ== - dependencies: - array-includes "^3.1.3" - array.prototype.flatmap "^1.2.4" - doctrine "^2.1.0" - estraverse "^5.2.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.0.4" - object.entries "^1.1.4" - object.fromentries "^2.0.4" - object.hasown "^1.0.0" - object.values "^1.1.4" - prop-types "^15.7.2" - resolve "^2.0.0-next.3" - semver "^6.3.0" - string.prototype.matchall "^4.0.5" - -eslint-scope@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== - dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^5.0.0, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hasha@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" - integrity sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk= - dependencies: - is-stream "^1.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -import-fresh@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-core-module@^2.2.0, is-core-module@^2.6.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - -is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== - dependencies: - call-bind "^1.0.0" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== - -istanbul-lib-hook@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz#c95695f383d4f8f60df1f04252a9550e15b5b133" - integrity sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA== - dependencies: - append-transform "^1.0.0" - -istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" - -istanbul-lib-report@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== - dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" - -istanbul-lib-source-maps@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" - source-map "^0.6.1" - -istanbul-reports@^2.2.4: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== - dependencies: - html-escaper "^2.0.0" - -js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" - integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== - dependencies: - array-includes "^3.1.3" - object.assign "^4.1.2" - -language-subtag-registry@~0.3.2: - version "0.3.21" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" - integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= - dependencies: - language-subtag-registry "~0.3.2" - -lcov-parse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" - integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - -lodash@^4.17.14, lodash@^4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-driver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" - integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - -mime-db@1.50.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== - dependencies: - mime-db "1.50.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha-jenkins-reporter@^0.4.6: - version "0.4.7" - resolved "https://registry.yarnpkg.com/mocha-jenkins-reporter/-/mocha-jenkins-reporter-0.4.7.tgz#59505d59a9fdeb64ee8270f13d8ca6c48c1dfad7" - integrity sha512-ek05WBoGX9G5B29QmFw67H92ZcvZcp62RASaHWqiZOWjc/G2YlKBeu7t60J5wpaQP1rFS8T9S85ed/3iDdf/2A== - dependencies: - diff "4.0.1" - mkdirp "^0.5.4" - xml "^1.0.1" - -mocha@^9.1.0: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -nested-error-stacks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" - integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -nyc@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-14.1.1.tgz#151d64a6a9f9f5908a1b73233931e4a0a3075eeb" - integrity sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw== - dependencies: - archy "^1.0.0" - caching-transform "^3.0.2" - convert-source-map "^1.6.0" - cp-file "^6.2.0" - find-cache-dir "^2.1.0" - find-up "^3.0.0" - foreground-child "^1.5.6" - glob "^7.1.3" - istanbul-lib-coverage "^2.0.5" - istanbul-lib-hook "^2.0.7" - istanbul-lib-instrument "^3.3.0" - istanbul-lib-report "^2.0.8" - istanbul-lib-source-maps "^3.0.6" - istanbul-reports "^2.2.4" - js-yaml "^3.13.1" - make-dir "^2.1.0" - merge-source-map "^1.1.0" - resolve-from "^4.0.0" - rimraf "^2.6.3" - signal-exit "^3.0.2" - spawn-wrap "^1.4.2" - test-exclude "^5.2.3" - uuid "^3.3.2" - yargs "^13.2.2" - yargs-parser "^13.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.entries@^1.1.2, object.entries@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.fromentries@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.hasown@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" - integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.values@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-hash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e" - integrity sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA== - dependencies: - graceful-fs "^4.1.15" - hasha "^3.0.0" - lodash.flattendeep "^4.4.0" - release-zalgo "^1.0.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexp.prototype.flags@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= - dependencies: - es6-error "^4.0.1" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.10.0, resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -resolve@^2.0.0-next.3: - version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" - integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.6.2, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -rxjs@^6.6.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spawn-wrap@^1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.3.tgz#81b7670e170cca247d80bf5faf0cfb713bdcf848" - integrity sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw== - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.6.2" - signal-exit "^3.0.2" - which "^1.3.0" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" - integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.matchall@^4.0.5: - version "4.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" - integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.3.1" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-json-comments@3.1.1, strip-json-comments@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tsconfig-paths@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" - integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -tweetnacl@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.2.9, which@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^2.4.2: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^13.0.0, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^13.2.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/docker-build-local.sh b/docker-build-local.sh deleted file mode 100644 index 9dbb980ef..000000000 --- a/docker-build-local.sh +++ /dev/null @@ -1 +0,0 @@ -docker build -t symbol-rest-local . diff --git a/rest/.eslintrc b/rest/.eslintrc deleted file mode 100644 index 66c8db532..000000000 --- a/rest/.eslintrc +++ /dev/null @@ -1,128 +0,0 @@ ---- -env: - es6: true - node: true -extends: airbnb -parserOptions: - sourceType: module - -rules: - indent: - - error - - tab - linebreak-style: - - error - - unix - quotes: - - error - - single - semi: - - error - - always - yoda: - - error - - always - curly: - - error - - multi-or-nest - - consistent - max-len: - - error - - code: 140 - - max-classes-per-file: - - off - prefer-object-spread: - - off - - nonblock-statement-body-position: - - error - - below - implicit-arrow-linebreak: - - off - - no-tabs: - - off - no-bitwise: - - off - no-plusplus: - - off - no-mixed-operators: - - error - - allowSamePrecedence: true - no-param-reassign: - - error - - props: false - no-underscore-dangle: - - error - - allow: - - _id # mongodb identifier - - camelcase: - - off # for consts, e.g. Foo_Bar - comma-dangle: - - error - - never - default-case: - - off - - arrow-parens: - - error - - as-needed - func-names: - - error - - never - func-style: - - error - - expression - wrap-iife: - - error - - inside - - prefer-destructuring: - - error - - object: true - array: false - - valid-jsdoc: - - error - - requireReturn: false - prefer: - arg: param - argument: param - class: constructor - return: returns - preferType: - Boolean: boolean - Number: number - Object: object - String: string - - import/order: - - error - - newlines-between: never - groups: - - index - - sibling - - parent - - internal - - external - - builtin - alphabetize: - order: asc - - import/extensions: - - error - - never - import/no-absolute-path: - - error - import/no-unresolved: - - 2 - import/no-deprecated: - - error - import/named: - - error - class-methods-use-this: - - off - consistent-return: - - off diff --git a/rest/bootstrap-preset-local.yml b/rest/bootstrap-preset-local.yml deleted file mode 100644 index e382c1629..000000000 --- a/rest/bootstrap-preset-local.yml +++ /dev/null @@ -1,24 +0,0 @@ -#nodeEqualityStrategy: public-key -logLevel: 'Debug' -throttlingBurst: 35 -throttlingRate: 1000 -#votingKeyLinkV2: 360000 -#importanceBlock: 360000 -#accountRestrictionsV2: 360000 -nodes: - - repeat: 0 - - trustedHosts: '127.0.0.1, 172.20.0.25, 172.20.0.1' - localNetworks: '127.0.0.1, 172.20.0.25, 172.20.0.1' - brokerOpenPort: 7902 - openPort: '{{add $index 7900}}' -gateways: - - excludeDockerService: true - name: rest - apiNodeConfigPath: target/gateways/rest/api-node-config - restLoggingFilename: target/rest.log - databaseHost: localhost - apiNodeHost: localhost - apiNodeBrokerHost: localhost -nemesis: - mosaics: - - accounts: 20 diff --git a/rest/bootstrap-preset-mainnet.yml b/rest/bootstrap-preset-mainnet.yml deleted file mode 100644 index 8c8f0932e..000000000 --- a/rest/bootstrap-preset-mainnet.yml +++ /dev/null @@ -1,21 +0,0 @@ -#nodeEqualityStrategy: public-key -logLevel: 'Debug' -throttlingBurst: 35 -throttlingRate: 1000 -databases: - - name: db - openPort: true -nodes: - - trustedHosts: '127.0.0.1, 172.20.0.25, 172.20.0.1' - localNetworks: '127.0.0.1, 172.20.0.25, 172.20.0.1' - openPort: true - brokerOpenPort: 7902 -gateways: - - excludeDockerService: true - name: rest - apiNodeConfigPath: target/gateways/rest/api-node-config - restLoggingFilename: target/rest.log - databaseHost: localhost - apiNodeHost: localhost - restProtocol: HTTP - diff --git a/rest/bootstrap-preset-testnet.yml b/rest/bootstrap-preset-testnet.yml deleted file mode 100644 index 8c8f0932e..000000000 --- a/rest/bootstrap-preset-testnet.yml +++ /dev/null @@ -1,21 +0,0 @@ -#nodeEqualityStrategy: public-key -logLevel: 'Debug' -throttlingBurst: 35 -throttlingRate: 1000 -databases: - - name: db - openPort: true -nodes: - - trustedHosts: '127.0.0.1, 172.20.0.25, 172.20.0.1' - localNetworks: '127.0.0.1, 172.20.0.25, 172.20.0.1' - openPort: true - brokerOpenPort: 7902 -gateways: - - excludeDockerService: true - name: rest - apiNodeConfigPath: target/gateways/rest/api-node-config - restLoggingFilename: target/rest.log - databaseHost: localhost - apiNodeHost: localhost - restProtocol: HTTP - diff --git a/rest/package.json b/rest/package.json deleted file mode 100644 index 05fce24b2..000000000 --- a/rest/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "catapult-api-rest", - "version": "0.0.0", - "description": "", - "main": "src/index.js", - "scripts": { - "version": "echo $npm_package_version", - "start": "node src/index.js", - "start:dev": "nodemon src/index.js target/gateways/rest/rest.json", - "test": "mocha --full-trace --recursive", - "test:coverage": "nyc npm test && nyc report --reporter=text-lcov", - "test:jenkins": "cross-env JUNIT_REPORT_PATH=test-results.xml mocha --reporter mocha-jenkins-reporter --mongoHost db --forbid-only --full-trace --recursive test || exit 0", - "test:travis": "nyc npm test && nyc report --reporter=text-lcov | coveralls", - "lint": "eslint src test", - "lint:fix": "eslint src test --fix", - "lint:jenkins": "eslint -o tests.catapult.lint.xml -f junit src test || exit 0", - "bootstrap-clean": "symbol-bootstrap clean", - "bootstrap-start": "symbol-bootstrap start -a light -c bootstrap-preset-local.yml --healthCheck --noPassword", - "bootstrap-start-testnet": "symbol-bootstrap start -p testnet -a dual -c bootstrap-preset-testnet.yml --healthCheck --noPassword --upgrade", - "bootstrap-start-mainnet": "symbol-bootstrap start -p testnet -a dual -c bootstrap-preset-mainnet.yml --healthCheck --noPassword --upgrade", - "bootstrap-start-detached": "symbol-bootstrap start -a light -c bootstrap-preset.yml --detached --healthCheck --noPassword --upgrade", - "bootstrap-stop": "symbol-bootstrap stop", - "bootstrap-run": "symbol-bootstrap run", - "bootstrap-run-detached": "symbol-bootstrap run --detached --healthCheck", - "bootstrap-compose": "symbol-bootstrap compose", - "bootstrap-config": "symbol-bootstrap config -a light -c bootstrap-preset.yml" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "chai": "^4.2.0", - "coveralls": "^3.1.1", - "cross-env": "^5.2.0", - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.1.0", - "eslint-plugin-import": "^2.19.1", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.19.0", - "eslint-plugin-react-hooks": "^2.5.0", - "hippie": "^0.6.1", - "minimist": "^1.2.0", - "mocha": "^9.1.0", - "mocha-jenkins-reporter": "^0.4.3", - "nodemon": "^2.0.6", - "nyc": "^14.1.1", - "rimraf": "^2.6.3", - "sinon": "^7.3.2", - "symbol-bootstrap": "^1.1.0" - }, - "dependencies": { - "catapult-sdk": "link:../catapult-sdk", - "ini": "^1.3.5", - "mongodb": "^3.3.0-beta2", - "restify": "^8.3.3", - "restify-errors": "^8.0.0", - "sshpk": "1.16.1", - "winston": "^3.2.1", - "ws": "^7.1.0", - "zeromq": "^5.2.8" - } -} diff --git a/rest/resources/rest.json b/rest/resources/rest.json deleted file mode 100644 index 4da424299..000000000 --- a/rest/resources/rest.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "network": { - "name": "testnet", - "description": "catapult public test network" - }, - - "port": 3000, - "protocol": "HTTPS", - "sslKeyPath": "", - "sslCertificatePath": "", - "crossDomain": { - "allowedHosts": ["*"], - "allowedMethods": ["GET", "POST", "PUT", "OPTIONS"] - }, - "uncirculatingAccountPublicKeys": [ - "A4739036FD7EFED2750A51EE9D1D3113BA3F9849E0889213CED7F221B2AA1A20", - "2BF1E1F3072E3BE0CD851E4741E101E33DB19C163895F69AA890E7CF177C878C" - ], - "extensions": [ - "accountLink", - "aggregate", - "lockHash", - "lockSecret", - "mosaic", - "metadata", - "multisig", - "namespace", - "receipts", - "restrictions", - "transfer" - ], - - "db": { - "url": "mongodb://localhost:27017/", - "name": "catapult", - "pageSizeMin": 10, - "pageSizeMax": 100, - "pageSizeDefault": 20, - "maxConnectionAttempts": 5, - "baseRetryDelay": 500, - "connectionPoolSize": 10 - }, - - "apiNode": { - "host": "127.0.0.1", - "port": 7900, - "timeout": 1000, - "tlsClientCertificatePath": "/", - "tlsClientKeyPath": "/", - "tlsCaCertificatePath": "/", - "networkPropertyFilePath": "/", - "nodePropertyFilePath": "/" - }, - - "websocket": { - "mq": { - "host": "127.0.0.1", - "port": 7902, - "monitorInterval": 500, - "connectTimeout": 10000, - "monitorLoggingThrottle": 60000, - "maxSubscriptions": 500 - }, - "allowOptionalAddress": true - }, - - "throttling": { - "burst": 20, - "rate": 5 - }, - - "logging": { - "console": { - "formats": ["colorize", "simple"], - - "level": "verbose", - "handleExceptions": true - }, - "file": { - "formats": ["prettyPrint"], - - "level": "verbose", - "handleExceptions": true, - - "filename": "catapult-rest.log", - "maxsize": 20971520, - "maxFiles": 100 - } - }, - - "numBlocksTransactionFeeStats": 300, - - "deployment": { - "deploymentTool": "", - "deploymentToolVersion": "", - "lastUpdatedDate": "" - } -} diff --git a/rest/src/connection/MessageChannelBuilder.js b/rest/src/connection/MessageChannelBuilder.js deleted file mode 100644 index 2e743660e..000000000 --- a/rest/src/connection/MessageChannelBuilder.js +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { ServerMessageHandler } = require('./serverMessageHandlers'); -const catapult = require('catapult-sdk'); - -const createBlockDescriptor = (marker, handler) => ({ - filter: topicParam => { - if (topicParam) - throw new Error('unexpected param to block subscription'); - - return marker; - }, - handler -}); - -const { convert } = catapult.utils; -const { namespace, address } = catapult.model; - -const createPolicyBasedAddressFilter = (markerByte, emptyAddressHandler, networkIdentifier) => topicParam => { - if (!topicParam) - return emptyAddressHandler(markerByte); - - // If the sent param is an namespace id hex like C0FB8AA409916260 - if (convert.isHexString(topicParam) && 16 === topicParam.length) { - const addressByteArray = namespace.encodeNamespace(convert.hexToUint8(topicParam), networkIdentifier); - return Buffer.concat([Buffer.of(markerByte), Buffer.from(addressByteArray)]); - } - // When it's a encoded address. - // TAHNZXQBC57AA7KJTMGS3PJPZBXN7DV5JHJU42A - const addressByteArray = address.stringToAddress(topicParam); - return Buffer.concat([Buffer.of(markerByte), Buffer.from(addressByteArray)]); -}; - -/** - * Builder for creating message channel information. - */ -class MessageChannelBuilder { - /** - * Creates a builder. - * @param {object} config Message queue configuration. - * @param {number} networkIdentifier the network identifier - */ - constructor(config, networkIdentifier) { - this.descriptors = {}; - this.channelMarkers = {}; - - const emptyAddressHandler = config && config.allowOptionalAddress - ? markerByte => Buffer.of(markerByte) - : () => { throw new Error('address param missing from address subscription'); }; - - this.createAddressFilter = markerChar => - createPolicyBasedAddressFilter(markerChar.charCodeAt(0), emptyAddressHandler, networkIdentifier); - - // add basic descriptors - this.descriptors.block = createBlockDescriptor( - Buffer.of(0x49, 0x6A, 0xCA, 0x80, 0xE4, 0xD8, 0xF2, 0x9F), - ServerMessageHandler.block - ); - this.descriptors.finalizedBlock = createBlockDescriptor( - Buffer.of(0x54, 0x79, 0xCE, 0x31, 0xA0, 0x32, 0x48, 0x4D), - ServerMessageHandler.finalizedBlock - ); - this.add('confirmedAdded', 'a', ServerMessageHandler.transaction); - this.add('unconfirmedAdded', 'u', ServerMessageHandler.transaction); - this.add('unconfirmedRemoved', 'r', ServerMessageHandler.transactionHash); - this.descriptors.status = { - filter: this.createAddressFilter('s'), - handler: ServerMessageHandler.transactionStatus - }; - } - - /** - * Adds support for a new channel. - * @param {string} name Channel name. - * @param {string} markerChar Channel marker character. - * @param {function} handler Channel data handler. - */ - add(name, markerChar, handler) { - if (name in this.descriptors) - throw Error(`'${name}' channel has already been registered`); - - if (1 !== markerChar.length) - throw Error('channel marker must be single character'); - - if (markerChar in this.channelMarkers) - throw Error(`'${markerChar}' channel marker has already been registered`); - - this.descriptors[name] = { filter: this.createAddressFilter(markerChar), handler }; - this.channelMarkers[markerChar] = 1; - } - - /** - * Builds and returns an object composed of all configured channel information. - * @returns {object} An object composed of all configured channel information. - */ - build() { - return this.descriptors; - } -} - -module.exports = MessageChannelBuilder; diff --git a/rest/src/connection/catapultConnection.js b/rest/src/connection/catapultConnection.js deleted file mode 100644 index 36cd59821..000000000 --- a/rest/src/connection/catapultConnection.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); - -const { PacketParser } = catapult.parser; - -const rejectOnClose = reject => () => reject(errors.createServiceUnavailableError('connection failed')); - -/** - * A catapult connection for interacting with api nodes. - * @class CatapultConnection - */ -module.exports = { - /** - * Wraps a catapult connection around a socket connection. - * @param {net.Socket} connection Socket connection to wrap. - * @returns {object} A catapult connection wrapped around the socket connection. - */ - wrap: connection => ({ - /** - * Initiates a write operation. - * @param {Buffer} payload Payload to write. - * @returns {Promise} Promise that is resolved upon completion of the write operation. - */ - send: payload => - new Promise((resolve, reject) => { - const innerReject = rejectOnClose(reject); - connection.once('close', innerReject); - connection.write(payload, () => { - connection.removeListener('close', innerReject); - resolve(); - }); - }), - - /** - * Sends a payload and waits for a response. - * @param {Buffer} payload Payload to be sent through the connection. - * @param {number} timeoutMs Timeout after which the promise is rejected because data is missing. - * @returns {Promise} Promise that is resolved upon completion of the read operation. - */ - pushPull(payload, timeoutMs) { - const listen = () => new Promise((resolve, reject) => { - const innerReject = rejectOnClose(reject); - const packetParser = new PacketParser(); - connection.once('close', innerReject); - connection.on('data', data => { - packetParser.push(data); - }); - - packetParser.onPacket(packet => { - connection.removeListener('close', innerReject); - connection.end(); - resolve(packet); - }); - }); - const promise = this.send(payload) - .then(listen); - - const timeout = new Promise((resolve, reject) => { - const id = setTimeout(() => { - clearTimeout(id); - connection.end(); - rejectOnClose(reject)(); - }, timeoutMs); - }); - return Promise.race([ - promise, - timeout - ]); - } - }) -}; diff --git a/rest/src/connection/connectionService.js b/rest/src/connection/connectionService.js deleted file mode 100644 index 1bbd422bc..000000000 --- a/rest/src/connection/connectionService.js +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapultConnection = require('./catapultConnection'); -const errors = require('../server/errors'); -const tls = require('tls'); - -/** - * Creates a catapult connection service for connecting to catapult servers. - * This is used for sending data (e.g. transactions) to a server over an authenticated connection. - * Current implementation only supports maintaining a connection to a single server but can be extended if needed. - * @param {object} config Service configuration. - * @param {Function} logger A logging function. - * @returns {object} Catapult connection service. - */ -module.exports.createConnectionService = (config, logger = () => {}) => { - const node = config.apiNode; - const aliveConnections = {}; - // the connection is not persisted until authentication is done, and this may take a while, - // to avoid duplicate connections those are cached in the following object - const authorizingConnectionPromises = {}; - - /** - * Opens a new connection authenticated to catapult. - * @param {boolean} isPersistent Determines whether the new connection should be pooled and kept open for reuse. - * @returns {Promise} A promise bound to the creation of the connection. - */ - const openAuthorizedConnection = isPersistent => { - logger(`connecting to ${node.host}:${node.port}`); - - const contextOptions = { - minVersion: 'TLSv1.3', - key: node.key, - cert: node.certificate, - ca: node.caCertificate - // sigalgs: 'ed25519' - }; - let secureContext; - try { - secureContext = tls.createSecureContext(contextOptions); - } catch (error) { - logger('an error occurred with the provided TLS key and certificates before trying to establish any connection to the server'); - throw error; - } - - const connectionOptions = { - host: node.host, - port: node.port, - secureContext, - // skip hostname checks since this is not a web-https case - checkServerIdentity: () => undefined - }; - - const connectionPromise = new Promise((resolve, reject) => { - const serverSocket = tls.connect(connectionOptions); - - serverSocket - .once('secureConnect', () => { - if (serverSocket.authorized) { - // wrap the socket in a catapult connection and save it - const serverConnection = catapultConnection.wrap(serverSocket); - if (isPersistent) { - aliveConnections[node] = serverConnection; - delete authorizingConnectionPromises[node]; - } - // return, and resolve the connection for possible queued connections on `authorizingConnectionPromises` - resolve(serverConnection); - return serverConnection; - } - - logger(`failed while connecting to the node ${node.host}:${node.port}`, serverSocket.authorizationError); - reject(serverSocket.authorizationError); - throw serverSocket.authorizationError; - }) - .on('error', err => { - // capture error, otherwise net default handler will be called - // default error handler issues reject(), that would go through bootstraper and toRestError(). - // the result might contain information about api node IP and port, because it might be different host, - // that information shouldn't be available to rest clients. - logger(`error raised by ${node.host}:${node.port} connection: `, err); - }) - .on('close', () => { - if (isPersistent) - delete aliveConnections[node]; - - reject(errors.createServiceUnavailableError('connection failed')); - }); - }); - - if (isPersistent) - authorizingConnectionPromises[node] = connectionPromise; - - return connectionPromise; - }; - - return { - /** - * Leases an available connection. - * @returns {module:connection/catapultConnection~CatapultConnection} A connection. - */ - lease: () => { - const authorizingPromise = authorizingConnectionPromises[node]; - if (authorizingPromise) - return authorizingPromise; - - const connection = aliveConnections[node]; - if (connection) - return Promise.resolve(connection); - - return openAuthorizedConnection(true); - }, - - /** - * Creates a new connection that gets automatically closed after being used. - * @returns {module:connection/catapultConnection~CatapultConnection} A connection. - */ - singleUse: () => openAuthorizedConnection(false) - }; -}; diff --git a/rest/src/connection/serverMessageHandlers.js b/rest/src/connection/serverMessageHandlers.js deleted file mode 100644 index cf2d25832..000000000 --- a/rest/src/connection/serverMessageHandlers.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); - -const { uint64 } = catapult.utils; - -const parserFromData = binaryData => { - const parser = new catapult.parser.BinaryParser(); - parser.push(binaryData); - return parser; -}; - -const ServerMessageHandler = Object.freeze({ - block: (codec, emit) => (topic, binaryBlock, hash, generationHash) => { - const block = codec.deserialize(parserFromData(binaryBlock)); - emit({ type: 'blockHeaderWithMetadata', payload: { block, meta: { hash, generationHash } } }); - }, - - finalizedBlock: (codec, emit) => (topic, binaryBlock) => { - const parser = parserFromData(binaryBlock); - - const finalizationEpoch = parser.uint32(); - const finalizationPoint = parser.uint32(); - const height = parser.uint64(); - const hash = parser.buffer(catapult.constants.sizes.hash256); - emit({ - type: 'finalizedBlock', - payload: { - finalizationEpoch, finalizationPoint, height, hash - } - }); - }, - - transaction: (codec, emit) => (topic, binaryTransaction, hash, merkleComponentHash, height) => { - const transaction = codec.deserialize(parserFromData(binaryTransaction)); - const meta = { hash, merkleComponentHash, height: uint64.fromBytes(height) }; - emit({ type: 'transactionWithMetadata', payload: { transaction, meta } }); - }, - - transactionHash: (codec, emit) => (topic, hash) => { - emit({ type: 'transactionWithMetadata', payload: { meta: { hash } } }); - }, - - transactionStatus: (codec, emit) => (topic, buffer) => { - const parser = parserFromData(buffer); - - const hash = parser.buffer(catapult.constants.sizes.hash256); - const deadline = parser.uint64(); - const code = parser.uint32(); - emit({ type: 'transactionStatus', payload: { hash, code, deadline } }); - } -}); - -module.exports = { - ServerMessageHandler -}; diff --git a/rest/src/connection/zmqService.js b/rest/src/connection/zmqService.js deleted file mode 100644 index 8863f4487..000000000 --- a/rest/src/connection/zmqService.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const zmqUtils = require('./zmqUtils'); -const zmq = require('zeromq'); - -const createZmqSocket = (key, zmqConfig, logger, currentSocketCount) => { - const zsocket = zmq.socket('sub'); - zsocket.key = key; - zmqUtils.prepareZsocket(zsocket, zmqConfig, logger); - - zsocket.connect(`tcp://${zmqConfig.host}:${zmqConfig.port}`); - logger.info(`Current zmq subscription count: ${currentSocketCount + 1}`); - return zsocket; -}; - -const findSubscriptionInfo = (key, emitter, codec, channelDescriptors) => { - const [topicCategory, topicParam] = key.split('/'); - if (!(topicCategory in channelDescriptors)) - throw new Error(`unknown topic category ${topicCategory}`); - - const descriptor = channelDescriptors[topicCategory]; - const handler = descriptor.handler(codec, data => { emitter.emit(key, data); }); - const filter = descriptor.filter(topicParam); - return { filter, handler }; -}; - -/** - * Service for creating channel-specific zmq sockets. - * @param {object} zmqConfig Configuration for configuring sockets. - * @param {object} codec Codec used to deserialize zmq messages. - * @param {object} channelDescriptors Registered message channel descriptors. - * @param {object} logger Level-based logger object. - * @returns {object} Newly created zmq connection service that is a stripped down EventEmitter. - */ -module.exports.createZmqConnectionService = (zmqConfig, codec, channelDescriptors, logger) => - zmqUtils.createMultisocketEmitter((key, emitter, currentSocketCount) => { - if (currentSocketCount === (!zmqConfig.maxSubscriptions ? 500 : zmqConfig.maxSubscriptions)) - throw new Error('Max subscriptions reached.'); - - logger.info(`subscribing to ${key}`); - const subscriptionInfo = findSubscriptionInfo(key, emitter, codec, channelDescriptors); - - const zsocket = createZmqSocket(key, zmqConfig, logger, currentSocketCount); - // the second param (handler) gets called with the provided args in the message, which vary depending on the defined handler type - // (block, transaction, transactionStatus...) - zsocket.subscribe(subscriptionInfo.filter); - zsocket.on('message', subscriptionInfo.handler); - return zsocket; - }); diff --git a/rest/src/connection/zmqUtils.js b/rest/src/connection/zmqUtils.js deleted file mode 100644 index 7b44b7c22..000000000 --- a/rest/src/connection/zmqUtils.js +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const EventEmitter = require('events'); - -const logAllMonitorEvents = (zsocket, throttle, logger) => { - const eventNameLevelPairs = { - connect: 'info', - connect_delay: 'debug', - connect_retry: 'info', - - listen: 'debug', - bind_error: 'error', - accept: 'debug', - accept_error: 'error', - close: 'info', - close_error: 'error', - disconnect: 'warn', - - monitor_error: 'error' - }; - - const createLogHandler = (name, level) => { - let lastTime; - return (value, endpoint) => { - const currentTime = new Date(); - const shouldThrottle = undefined !== lastTime && throttle > currentTime - lastTime; - lastTime = currentTime; - - // skip this noisy log - if (shouldThrottle) - return; - - const formattedValue = undefined === value ? '' : ` (${value})`; - logger[level](`zmq ${zsocket.key}: ${name} ${endpoint}${formattedValue}`); - }; - }; - Object.keys(eventNameLevelPairs).forEach(eventName => { - zsocket.on(eventName, createLogHandler(eventName, eventNameLevelPairs[eventName])); - }); -}; - -module.exports = { - /** - * Prepares a zmq socket for a connection. - * @param {zmq.Socket} zsocket Zmq socket. - * @param {object} zmqConfig Zmq configuration. - * @param {logger} logger Level-based logger object. - */ - prepareZsocket: (zsocket, zmqConfig, logger) => { - // override close to - // 1. call unmonitor (required because of monitor call below) - // 2. raise a zsocket_close event (cannot use 'close' because zmq monitor is already using 'close' to signal something else) - let connectTimeoutTimerId; - const originalZsocketClose = zsocket.close; - zsocket.close = () => { - // prevent the timer from attempting another close (zmq socket close is not idempotent and can only be called once) - clearTimeout(connectTimeoutTimerId); - - zsocket.unmonitor(); - originalZsocketClose.call(zsocket); - zsocket.emit('zsocket_close'); - }; - - const closeWithError = (message, err) => { - logger.error(`zmq ${zsocket.key}: ${message}`, err); - zsocket.close(); - }; - - // log all monitor events - logAllMonitorEvents(zsocket, zmqConfig.monitorLoggingThrottle, logger); - - // zmq js still forwards errors to error event that need to be handled - zsocket.on('error', err => { - closeWithError('error from zsocket', err); - }); - - // zmq appears to attempt to connect to a socket forever, so add some timeout - connectTimeoutTimerId = setTimeout(() => { - closeWithError('connection attempt timed out'); - }, zmqConfig.connectTimeout); - - zsocket.once('connect', () => { - clearTimeout(connectTimeoutTimerId); - }); - - // enable monitoring (0 => read all events each interval) - zsocket.monitor(zmqConfig.monitorInterval, 0); - }, - - /** - * Creates a multisocket emitter. - * @param {function} zsocketFactory Factory for creating a zmq socket given a key. - * @returns {object} Event emitter with partial interface (on, removeAllListeners, listenerCount). - */ - createMultisocketEmitter: zsocketFactory => { - const emitter = new EventEmitter(); - const zsockets = {}; - const isSubEvent = key => -1 !== key.indexOf('.'); - const isValidSubEvent = key => key.endsWith('.close'); - const multisocketEmitter = { - on: (key, callback) => { - if (isSubEvent(key)) { - if (!isValidSubEvent(key)) - throw Error(`${key} indicates an unsupported subevent`); - } else if (!(key in zsockets)) { - const zsocket = zsocketFactory(key, emitter, multisocketEmitter.zsocketCount()); - zsocket.on('zsocket_close', () => { - // firing of close indicates socket is fully closed, so prevent it from being closed again - // by bypassing close in removeAllListeners - delete zsockets[key]; - - emitter.emit(`${key}.close`); - multisocketEmitter.removeAllListeners(key); - }); - zsockets[key] = zsocket; - } - - emitter.on(key, callback); - }, - - removeAllListeners: key => { - if (isSubEvent(key)) - throw Error(`${key} must be a channel`); - - emitter.removeAllListeners(key); - emitter.removeAllListeners(`${key}.close`); - if (!(key in zsockets)) - return; - - const zsocket = zsockets[key]; - delete zsockets[key]; - zsocket.close(); - }, - - listenerCount: key => emitter.listenerCount(key), - - /** - * Gets the number of active zmq sockets. - * @returns {numeric} Number of active zmq sockets. - */ - zsocketCount: () => Object.keys(zsockets).length, - - /** - * Closes all zsockets. - */ - close: () => { - Object.keys(zsockets).forEach(key => { - multisocketEmitter.removeAllListeners(key); - }); - } - }; - - return multisocketEmitter; - } -}; diff --git a/rest/src/db/CatapultDb.js b/rest/src/db/CatapultDb.js deleted file mode 100644 index 25a180da2..000000000 --- a/rest/src/db/CatapultDb.js +++ /dev/null @@ -1,648 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module db/CatapultDb */ - -const connector = require('./connector'); -const { convertToLong, buildOffsetCondition, uniqueLongList } = require('./dbUtils'); -const MultisigDb = require('../plugins/multisig/MultisigDb'); -const catapult = require('catapult-sdk'); -const MongoDb = require('mongodb'); - -const { EntityType } = catapult.model; -const { ObjectId } = MongoDb; - -const isAggregateType = document => EntityType.aggregateComplete === document.transaction.type - || EntityType.aggregateBonded === document.transaction.type; - -const createSanitizer = () => ({ - copyAndDeleteId: dbObject => { - if (dbObject) { - Object.assign(dbObject.meta, { id: dbObject._id }); - delete dbObject._id; - } - - return dbObject; - }, - - deleteId: dbObject => { - if (dbObject) - delete dbObject._id; - - return dbObject; - }, - - deleteIds: dbObjects => { - dbObjects.forEach(dbObject => { - delete dbObject._id; - }); - return dbObjects; - }, - - renameId: dbObject => { - if (dbObject) { - dbObject.id = dbObject._id; - delete dbObject._id; - } - - return dbObject; - }, - - renameIds: dbObjects => { - dbObjects.forEach(dbObject => { - dbObject.id = dbObject._id; - delete dbObject._id; - }); - return dbObjects; - } -}); - -const mapToPromise = dbObject => Promise.resolve(null === dbObject ? undefined : dbObject); - -const pickTopImportance = wrappedAccount => { - const { account } = wrappedAccount; - if (0 < account.importances.length) { - const importanceSnapshot = account.importances.shift(); - account.importance = importanceSnapshot.value; - account.importanceHeight = importanceSnapshot.height; - } else { - account.importance = convertToLong(0); - account.importanceHeight = convertToLong(0); - } - delete account.importances; - return wrappedAccount; -}; - -const TransactionGroup = Object.freeze({ - confirmed: 'transactions', - unconfirmed: 'unconfirmedTransactions', - partial: 'partialTransactions' -}); - -class CatapultDb { - // region construction / connect / disconnect - - constructor(options) { - this.networkId = options.networkId; - if (!this.networkId) - throw Error('network id is required'); - - this.pagingOptions = { - pageSizeMin: options.pageSizeMin, - pageSizeMax: options.pageSizeMax, - pageSizeDefault: options.pageSizeDefault - }; - this.sanitizer = createSanitizer(); - } - - connect(url, dbName, connectionPoolSize) { - return connector.connectToDatabase(url, dbName, connectionPoolSize || 10) - .then(client => { - this.client = client; - this.database = client.db(); - }); - } - - close() { - if (!this.database) - return Promise.resolve(); - - return new Promise(resolve => { - this.client.close(resolve); - this.client = undefined; - this.database = undefined; - }); - } - - // endregion - - // region helpers - - queryDocument(collectionName, conditions, projection) { - const collection = this.database.collection(collectionName); - return collection.findOne(conditions, { projection }) - .then(mapToPromise); - } - - queryDocuments(collectionName, conditions) { - const collection = this.database.collection(collectionName); - return collection.find(conditions) - .toArray() - .then(this.sanitizer.deleteIds); - } - - queryDocumentsAndCopyIds(collectionName, conditions, options = {}) { - const collection = this.database.collection(collectionName); - return collection.find(conditions) - .project(options.projection) - .toArray() - .then(this.sanitizer.renameIds); - } - - // endregion - - // region retrieval - - /** - * Retrieves sizes of database collections. - * @returns {Promise} Promise that resolves to the sizes of collections in the database. - */ - storageInfo() { - const blockCountPromise = this.database.collection('blocks').estimatedDocumentCount(); - const transactionCountPromise = this.database.collection('transactions').estimatedDocumentCount(); - const accountCountPromise = this.database.collection('accounts').estimatedDocumentCount(); - return Promise.all([blockCountPromise, transactionCountPromise, accountCountPromise]) - .then(storageInfo => ({ numBlocks: storageInfo[0], numTransactions: storageInfo[1], numAccounts: storageInfo[2] })); - } - - chainStatisticCurrent() { - return this.queryDocument('chainStatistic', {}, { _id: 0 }) - .then(chainStatistic => chainStatistic.current); - } - - latestFinalizedBlock() { - return this.database.collection('finalizedBlocks') - .findOne({}, { sort: [['block.height', -1]], projection: { _id: 0 } }) - .then(mapToPromise); - } - - /** - * Retrieves filtered and paginated blocks. - * @param {Uint8Array} signerPublicKey Filters by signer public key - * @param {Uint8Array} beneficiaryAddress Filters by beneficiary address - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Blocks page. - */ - blocks(signerPublicKey, beneficiaryAddress, options) { - const sortingOptions = { - id: '_id', - height: 'block.height' - }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== signerPublicKey) - conditions['block.signerPublicKey'] = Buffer.from(signerPublicKey); - - if (undefined !== beneficiaryAddress) - conditions['block.beneficiaryAddress'] = Buffer.from(beneficiaryAddress); - - const removeFields = ['meta.transactionMerkleTree', 'meta.statementMerkleTree']; - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - - return this.queryPagedDocuments(conditions, removeFields, sortConditions, 'blocks', options); - } - - blockAtHeight(height) { - return this.queryDocument( - 'blocks', - { 'block.height': convertToLong(height) }, - { 'meta.transactionMerkleTree': 0, 'meta.statementMerkleTree': 0 } - ).then(this.sanitizer.renameId); - } - - /** - * Returns the blocks (or a projection of the blocks) for the given heights. - * @param {Long[]} heights the array of long heights - * @param {object} projection optional projection, by default it excludes the transactionMerkleTree and statementMerkleTree fields - * @returns {Promise} with the blocks objects or projections. - */ - blocksAtHeights(heights, projection) { - if (!heights.length) - return Promise.resolve([]); - - return this.queryDocumentsAndCopyIds( - 'blocks', - { 'block.height': { $in: heights } }, - { projection: projection || { 'meta.transactionMerkleTree': 0, 'meta.statementMerkleTree': 0 } } - ); - } - - blockWithMerkleTreeAtHeight(height, merkleTreeName) { - const blockMerkleTreeNames = ['transactionMerkleTree', 'statementMerkleTree']; - const excludedMerkleTrees = {}; - blockMerkleTreeNames.filter(merkleTree => merkleTree !== merkleTreeName) - .forEach(merkleTree => { excludedMerkleTrees[`meta.${merkleTree}`] = 0; }); - return this.queryDocument('blocks', { 'block.height': convertToLong(height) }, excludedMerkleTrees) - .then(this.sanitizer.deleteId); - } - - /** - * Retrieves the fee multiplier for the last (higher on the chain) numBlocks blocks - * @param {int} numBlocks Number of blocks to retrieve. - * @returns {Promise} Promise that resolves to feeMultiplier array - */ - latestBlocksFeeMultiplier(numBlocks) { - if (0 === numBlocks) - return Promise.resolve([]); - - return this.database.collection('blocks').find() - .sort({ 'block.height': -1 }) - .limit(numBlocks) - .project({ 'block.feeMultiplier': 1 }) - .toArray() - .then(blocks => Promise.resolve(blocks.map(block => block.block.feeMultiplier))); - } - - queryDependentDocuments(collectionName, aggregateIds) { - if (0 === aggregateIds.length) - return Promise.resolve([]); - - return this.queryDocumentsAndCopyIds(collectionName, { 'meta.aggregateId': { $in: aggregateIds } }); - } - - /** - * Makes a paginated query with the provided arguments. - * @param {array} queryConditions The conditions that determine the query results, may be empty. - * @param {array} removedFields Field names to be hidden from the query results, may be empty. - * @param {object} sortConditions Condition that describes the order of the results, must be set. - * @param {string} collectionName Name of the collection to be queried. - * @param {object} options Pagination options, must contain `pageSize` and `pageNumber` (starting at 1). - * @param {function} mapper to transform each element of the page. - * @returns {Promise.} Page result, contains the attributes `data` with the actual results, and `paging` with pagination - * metadata - which is comprised of: `pageNumber`, and `pageSize`. - */ - queryPagedDocuments(queryConditions, removedFields, sortConditions, collectionName, options, mapper) { - const { pageSize } = options; - const pageIndex = options.pageNumber - 1; - - const projection = {}; - removedFields.forEach(field => { projection[field] = 0; }); - - return this.database.collection(collectionName) - .find(queryConditions) - .project(projection) - .sort(sortConditions) - .skip(pageSize * pageIndex) - .limit(pageSize) - .toArray() - .then(this.sanitizer.renameIds) - .then(xs => (mapper ? xs.map(mapper) : xs)) - .then(result => ({ - data: result, - pagination: { - pageNumber: options.pageNumber, - pageSize - } - })); - } - - /** - * Retrieves filtered and paginated transactions. - * @param {string} group Transactions group on which the query is made. - * @param {object} filters Filters to be applied: `address` for an involved address in the query, `signerPublicKey`, `recipientAddress`, - * `height`, `fromHeight`, `toHeight`, `embedded`, `transferMosaicId`, `fromTransferAmount`, `toTransferAmount`, `transactionTypes` - * array of uint. - * If `address` is provided, other account related filters are omitted. - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Transactions page. - */ - async transactions(group, filters, options) { - const sortingOptions = { id: '_id' }; - - const buildAccountConditions = async () => { - // Check multisig graph if address is used in search criteria for cosigning, - // Then, show transactions for other cosigers. - if (undefined !== filters.address) { - if ('partial' === group) { - const multisigEntries = await new MultisigDb(this).multisigsByAddresses([filters.address]); - - if (multisigEntries.length && multisigEntries[0].multisig.multisigAddresses.length) { - const buffers = multisigEntries[0].multisig.multisigAddresses.map(address => address.buffer); - buffers.push(Buffer.from(filters.address)); - return { 'meta.addresses': { $in: buffers } }; - } - } - return { 'meta.addresses': Buffer.from(filters.address) }; - } - const accountConditions = {}; - if (undefined !== filters.signerPublicKey) - accountConditions['transaction.signerPublicKey'] = Buffer.from(filters.signerPublicKey); - if (undefined !== filters.recipientAddress) - accountConditions['transaction.recipientAddress'] = Buffer.from(filters.recipientAddress); - return accountConditions; - }; - - const buildConditions = async () => { - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== filters.fromHeight || undefined !== filters.toHeight) { - const heightPath = 'meta.height'; - conditions[heightPath] = {}; - - if (undefined !== filters.fromHeight) - conditions[heightPath].$gte = convertToLong(filters.fromHeight); - - if (undefined !== filters.toHeight) - conditions[heightPath].$lte = convertToLong(filters.toHeight); - } - - if (undefined !== filters.height) - conditions['meta.height'] = convertToLong(filters.height); - - if (!filters.embedded) - conditions['meta.aggregateId'] = { $exists: false }; - - if (undefined !== filters.transactionTypes) - conditions['transaction.type'] = { $in: filters.transactionTypes }; - - /** transfer transaction specific filters */ - if (undefined !== filters.transferMosaicId) - conditions['transaction.mosaics.id'] = convertToLong(filters.transferMosaicId); - - if (undefined !== filters.fromTransferAmount || undefined !== filters.toTransferAmount) { - const amountPath = 'transaction.mosaics.amount'; - conditions[amountPath] = {}; - - if (undefined !== filters.fromTransferAmount) - conditions[amountPath].$gte = convertToLong(filters.fromTransferAmount); - - if (undefined !== filters.toTransferAmount) - conditions[amountPath].$lte = convertToLong(filters.toTransferAmount); - } - - const accountConditions = await buildAccountConditions(); - if (accountConditions) - conditions = Object.assign(conditions, accountConditions); - - return conditions; - }; - - const removedFields = ['meta.addresses']; - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - const conditions = await buildConditions(); - - return this.queryPagedDocuments(conditions, removedFields, sortConditions, TransactionGroup[group], options).then(async page => { - const data = await this.addBlockMetaToTransactionList(page.data); - return ({ - ...page, - data - }); - }); - } - - transactionsByIdsImpl(collectionName, conditions) { - return this.queryDocumentsAndCopyIds(collectionName, conditions, { projection: { 'meta.addresses': 0 } }) - .then(list => this.addBlockMetaToTransactionList(list)).then(documents => Promise.all(documents.map(document => { - if (!document || !isAggregateType(document)) - return document; - - return this.queryDependentDocuments(collectionName, [document.id]).then(dependentDocuments => { - dependentDocuments.forEach(dependentDocument => { - if (!document.transaction.transactions) - document.transaction.transactions = []; - if (document.meta.timestamp !== undefined && document.meta.feeMultiplier !== undefined) { - dependentDocument.meta.timestamp = document.meta.timestamp; - dependentDocument.meta.feeMultiplier = document.meta.feeMultiplier; - } - document.transaction.transactions.push(dependentDocument); - }); - - return document; - }); - }))); - } - - /** - * It retrieves and adds the block information to the transactions' meta. - * - * The block information includes its timestamp and feeMultiplier - * - * @param {object[]} list the transaction list without the added block information. - * @returns {Promise} the list with the added block information. - */ - addBlockMetaToTransactionList(list) { - return this.addBlockMetaToEntityList(list, ['timestamp', 'feeMultiplier'], item => item.meta.height); - } - - /** - * It retrieves and adds the block information to the entities' meta. - * - * @param {object[]} list the entity list without the added block information. - * @param {string[]} fields the list of fields to be be copied from the block's to the entity's meta. - * @param {Function} getHeight a function that returns the block's height of a given entity. - * @returns {Promise} this list with the added block information. - */ - async addBlockMetaToEntityList(list, fields, getHeight) { - const isValidHeight = height => height && 0 !== height.toInt(); - - const blockHeights = uniqueLongList( - list.map(item => getHeight(item)).filter(isValidHeight) - ); - - const projection = { - 'block.height': 1, - ...fields.reduce((acc, field) => { - acc[`block.${field}`] = 1; - return acc; - }, {}) - }; - const blocks = await this.blocksAtHeights(blockHeights, projection); - - return list.map(item => { - const height = getHeight(item); - if (!isValidHeight(height)) - return item; - const block = blocks.find( - blockInfo => blockInfo.block.height.equals( - height - ) - ); - if (!block) { - throw new Error( - `Cannot find block with height ${height.toString()}` - ); - } - item.meta = item.meta || {}; - fields.forEach(field => { - const value = block.block[field]; - if (value === undefined) { - throw new Error( - `Cannot find ${field} in block with height ${height.toString()}` - ); - } - item.meta[field] = value; - }); - return item; - }); - } - - transactionsByIds(group, ids) { - return this.transactionsByIdsImpl(TransactionGroup[group], { _id: { $in: ids.map(id => new ObjectId(id)) } }); - } - - transactionsByHashes(group, hashes) { - return this.transactionsByIdsImpl(TransactionGroup[group], { 'meta.hash': { $in: hashes.map(hash => Buffer.from(hash)) } }); - } - - /** - * Return (id, name, parent) tuples for transactions with type and with id in set of ids. - * @param {*} ids Set of transaction ids. - * @param {*} transactionType Transaction type. - * @param {object} fieldNames Descriptor for fields used in query. - * @returns {Promise.} Promise that is resolved when tuples are ready. - */ - findNamesByIds(ids, transactionType, fieldNames) { - const queriedIds = ids.map(convertToLong); - const conditions = { - $match: { - 'transaction.type': transactionType, - [`transaction.${fieldNames.id}`]: { $in: queriedIds } - } - }; - - const grouping = { - $group: { - _id: `$transaction.${fieldNames.id}`, - [fieldNames.id]: { $first: `$transaction.${fieldNames.id}` }, - [fieldNames.name]: { $first: `$transaction.${fieldNames.name}` }, - [fieldNames.parentId]: { $first: `$transaction.${fieldNames.parentId}` } - } - }; - - const collection = this.database.collection('transactions'); - return collection.aggregate([conditions, grouping], { promoteLongs: false }) - .sort({ _id: -1 }) - .toArray() - .then(this.sanitizer.deleteIds); - } - - // region account retrieval - - /** - * Retrieves filtered and paginated accounts - * @param {Uint8Array} address Filters by address - * @param {uint64} mosaicId Filters by accounts with some mosaicId balance. Required if provided `sortField` is `balance` - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Accounts page. - */ - accounts(address, mosaicId, options) { - const sortingOptions = { id: '_id', balance: 'account.mosaics.amount' }; - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== address) - conditions['account.address'] = Buffer.from(address); - - if (undefined !== mosaicId) - conditions['account.mosaics.id'] = convertToLong(mosaicId); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - - let queryPromise; - if ('balance' === options.sortField) { - const { pageSize } = options; - const pageIndex = options.pageNumber - 1; - - // fetch result sorted by specific mosaic amount, this unwinds mosaics and only returns matching mosaics (incomplete response) - queryPromise = this.database.collection('accounts') - .aggregate([], { promoteLongs: false }) - .unwind('$account.mosaics') - .match(conditions) - .sort(sortConditions) - .skip(pageSize * pageIndex) - .limit(pageSize) - .toArray() - .then(accounts => { - const accountIds = accounts.map(account => account._id); - const newConditions = { _id: { $in: accountIds } }; - // repeat the response with the found and sorted account ids, so that the result can be complete with all the mosaics - // Second query set pageIndex to 0; - return this.queryPagedDocuments(newConditions, [], {}, 'accounts', - { pageSize, pageNumber: 1 }) - .then(fullAccountsPage => { - // $in results do not preserve query order - fullAccountsPage.data.sort((account1, account2) => - accountIds.findIndex(accountId => accountId.equals(account1.id)) - - accountIds.findIndex(accountId => accountId.equals(account2.id))); - fullAccountsPage.pagination.pageNumber = options.pageNumber; - return fullAccountsPage; - }); - }); - } else { - queryPromise = this.queryPagedDocuments(conditions, [], sortConditions, 'accounts', options); - } - - return queryPromise.then(accountsPage => { - accountsPage.data.map(pickTopImportance); - return accountsPage; - }); - } - - accountsByIds(ids) { - // id will either have address property or publicKey property set; in the case of publicKey, convert it to address - const buffers = ids.map(id => Buffer.from((id.publicKey - ? catapult.model.address.publicKeyToAddress(id.publicKey, this.networkId) : id.address))); - return this.database.collection('accounts') - .find({ 'account.address': { $in: buffers } }) - .toArray() - .then(this.sanitizer.renameIds) - .then(entities => entities.map(pickTopImportance)); - } - - // endregion - - // region failed transaction - - /** - * Retrieves transaction results for the given hashes. - * @param {Array.} hashes Transaction hashes. - * @returns {Promise.} Promise that resolves to the array of hash / validation result pairs. - */ - transactionsByHashesFailed(hashes) { - const buffers = hashes.map(hash => Buffer.from(hash)); - return this.queryDocuments('transactionStatuses', { 'status.hash': { $in: buffers } }); - } - - // endregion - - // region utils - - /** - * Retrieves account publickey projection for the given address. - * @param {Uint8Array} accountAddress Account address. - * @returns {Promise} Promise that resolves to the account public key. - */ - addressToPublicKey(accountAddress) { - const conditions = { 'account.address': Buffer.from(accountAddress) }; - const projection = { 'account.publicKey': 1 }; - return this.queryDocument('accounts', conditions, projection); - } - - // endregion -} - -module.exports = CatapultDb; diff --git a/rest/src/db/connector.js b/rest/src/db/connector.js deleted file mode 100644 index 7608494b9..000000000 --- a/rest/src/db/connector.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MongoDb = require('mongodb'); -const winston = require('winston'); - -const connector = { - connectToDatabase(url, dbName, connectionPoolSize) { - const connectionString = `${url}${dbName}`; - return MongoDb.MongoClient.connect(connectionString, { poolSize: connectionPoolSize, promoteLongs: false, useNewUrlParser: true }) - .then(client => { - winston.verbose(`connected to mongo at ${connectionString}`); - return client; - }); - } -}; - -module.exports = connector; diff --git a/rest/src/db/dbFormattingRules.js b/rest/src/db/dbFormattingRules.js deleted file mode 100644 index 89ac9bf19..000000000 --- a/rest/src/db/dbFormattingRules.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { longToUint64, bufferToUnresolvedAddress } = require('./dbUtils'); -const catapult = require('catapult-sdk'); -const { Binary } = require('mongodb'); - -const { ModelType, status } = catapult.model; -const { convert, uint64 } = catapult.utils; - -/** - * Some of the formatters here may be branched depending on whether the received data comes from MongoDb or simple JavaScript. This happens - * because those formatters take data from the database and expose it to the API, and in some uncommon cases, data is fabricated outside of - * the database environment, and is then exposed to the API, however, the underlying types are not those of the databse. This architecture - * couples the database and the API a great deal, and this would probably need to be decoupled into two stages/layers (database parsing, and - * internal objects parsing). However, since the vast majority of times data is streamed directly untouched from the database to the API, - * this has not been decoupled yet. - */ - -module.exports = { - [ModelType.none]: value => value, - [ModelType.binary]: value => (convert.uint8ToHex(value.buffer instanceof ArrayBuffer ? value : value.buffer)), - [ModelType.objectId]: value => (undefined === value ? '' : value.toHexString().toUpperCase()), - [ModelType.statusCode]: value => status.toString(value >>> 0), - [ModelType.string]: value => value.toString(), - [ModelType.uint8]: value => value, - // `uint16` required solely because accountRestrictions->restrictionAdditions array has uint16 provided as binary - [ModelType.uint16]: value => (value instanceof Binary ? Buffer.from(value.buffer).readInt16LE(0) : value), - [ModelType.uint32]: value => convert.int32ToUint32(value), - [ModelType.uint64]: value => uint64.toString(longToUint64(value)), - // `uint64HexIdentifier` requires branching accountRestrictions->restrictionAdditions provides uint64 as binary - [ModelType.uint64HexIdentifier]: value => uint64.toHex(value instanceof Binary ? uint64.fromBytes(value.buffer) : longToUint64(value)), - [ModelType.int]: value => value.valueOf(), - [ModelType.boolean]: value => value, - [ModelType.encodedAddress]: value => bufferToUnresolvedAddress(value) -}; diff --git a/rest/src/db/dbUtils.js b/rest/src/db/dbUtils.js deleted file mode 100644 index b1e1b87cf..000000000 --- a/rest/src/db/dbUtils.js +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); -const MongoDb = require('mongodb'); - -const { Long, ObjectId } = MongoDb; -const { address } = catapult.model; - -const convertToLong = value => { - if (Number.isInteger(value)) - return Long.fromNumber(value); - - // if value is an array, assume it is a uint64 - if (Array.isArray(value)) - return new Long(value[0], value[1]); - - if (value instanceof Long) - return value; - - throw errors.createInvalidArgumentError(`${value} has an invalid format: not integer or uint64`); -}; - -const dbUtils = { - /** - * Converts number to long. - * @param {object} value Value to convert. - * @returns {MongoDb.Long} Converted value. - */ - convertToLong, - - /** - * Converts long to uint64. - * @param {Long} value Value to convert. - * @returns {uint64} Converted value. - */ - longToUint64: value => { - if (value instanceof Long) - return [value.getLowBitsUnsigned(), value.getHighBits() >>> 0]; - - throw errors.createInvalidArgumentError(`${value} has an invalid format: not long`); - }, - - /** - * Generates an offset condition depending on the offset type, and sorting options provided. - * @param {object} options Sorting options, must contain `offset`, `offsetType`, `sortField`, and `sortDirection`. - * @param {object} sortFieldDbRelation Determines the database path of the provided sort field. - * @returns {object} Offset condition if offset was provided, otherwise returns undefined. - */ - buildOffsetCondition: (options, sortFieldDbRelation) => { - const offsetTypeToDbObject = { - objectId: objectIdString => new ObjectId(objectIdString), - uint64: convertToLong, - uint64Hex: convertToLong - }; - - if (undefined !== options.offset) { - const offsetRequiresParsing = Object.keys(offsetTypeToDbObject).includes(options.offsetType); - const offset = offsetRequiresParsing ? offsetTypeToDbObject[options.offsetType](options.offset) : options.offset; - return { [sortFieldDbRelation[options.sortField]]: { [1 === options.sortDirection ? '$gt' : '$lt']: offset } }; - } - return undefined; - }, - - /** - * Formats binary to a base32 address or hex address - * @param {MongoDb.Binary} binary Address|NamespaceId from MongoDb. - * @param {boolean} formatAddressUsingBase32 if base32 format should be used when formatting an address. Hex otherwise. - * @returns {string} the address in base32 format or hex format depending on formatAddressUsingBase32 - */ - bufferToUnresolvedAddress: (binary, formatAddressUsingBase32) => { - if (!binary) - return undefined; - - const getBuffer = () => { - if ((binary instanceof MongoDb.Binary)) - return binary.buffer; - - if ((binary instanceof Uint8Array)) - return binary; - - throw new Error( - `Cannot convert binary address, unknown ${binary.constructor.name} type` - ); - }; - return formatAddressUsingBase32 ? address.addressToString(getBuffer()) : catapult.utils.convert.uint8ToHex(getBuffer()); - }, - - /** - * Creates copy of the array without duplicated longs. - * @param {Long[]} duplicatedIds of {Long} objects. - * @returns {Long[]} copy of the original list without duplicated values. - */ - uniqueLongList: duplicatedIds => duplicatedIds.filter((height, index) => - index === duplicatedIds.findIndex(anotherHeight => anotherHeight.equals(height))) -}; -module.exports = dbUtils; diff --git a/rest/src/db/entityEmitterFactory.js b/rest/src/db/entityEmitterFactory.js deleted file mode 100644 index 37c2e1d0c..000000000 --- a/rest/src/db/entityEmitterFactory.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const winston = require('winston'); -const EventEmitter = require('events'); - -module.exports = { - createEntityEmitter: createOpEmitter => { - const entityEmitter = new EventEmitter(); - return createOpEmitter({ ns: 'catapult.blocks', op: 'i' }) - .then(opEmitter => { - opEmitter.on('op', doc => { - entityEmitter.emit('block', doc.o); - }); - opEmitter.on('error', err => { - winston.error('detected error watching blocks', err); - entityEmitter.emit('error', err); - }); - }) - .then(() => entityEmitter); - } -}; diff --git a/rest/src/index.js b/rest/src/index.js deleted file mode 100644 index 6f6951604..000000000 --- a/rest/src/index.js +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { createConnectionService } = require('./connection/connectionService'); -const { createZmqConnectionService } = require('./connection/zmqService'); -const CatapultDb = require('./db/CatapultDb'); -const dbFormattingRules = require('./db/dbFormattingRules'); -const routeSystem = require('./plugins/routeSystem'); -const allRoutes = require('./routes/allRoutes'); -const bootstrapper = require('./server/bootstrapper'); -const formatters = require('./server/formatters'); -const messageFormattingRules = require('./server/messageFormattingRules'); -const catapult = require('catapult-sdk'); -const sshpk = require('sshpk'); -const winston = require('winston'); -const fs = require('fs'); - -const createLoggingTransportConfiguration = loggingConfig => { - const transportConfig = Object.assign({}, loggingConfig); - - // map specified formats into a winston function - delete transportConfig.formats; - const logFormatters = loggingConfig.formats.map(name => winston.format[name]()); - transportConfig.format = winston.format.combine(...logFormatters); - return transportConfig; -}; - -const configureLogging = config => { - const transports = [new winston.transports.File(createLoggingTransportConfiguration(config.file))]; - if ('production' !== process.env.NODE_ENV) - transports.push(new winston.transports.Console(createLoggingTransportConfiguration(config.console))); - - // configure default logger so that it adds timestamp to all logs - winston.configure({ - format: winston.format.timestamp(), - transports - }); -}; - -const validateConfig = config => { - if (config.crossDomain && (!config.crossDomain.allowedHosts || !config.crossDomain.allowedMethods)) - throw Error('provided CORS configuration is incomplete'); -}; - -const loadConfig = () => { - let configFiles = process.argv.slice(2); - if (0 === configFiles.length) - configFiles = ['../resources/rest.json']; - - let config; - configFiles.forEach(configFile => { - winston.info(`loading config from ${configFile}`); - const partialConfig = JSON.parse(fs.readFileSync(configFile, 'utf8')); - if (config) { - // override config - catapult.utils.objects.checkSchemaAgainstTemplate(config, partialConfig); - catapult.utils.objects.deepAssign(config, partialConfig); - } else { - // primary config - config = partialConfig; - } - }); - - validateConfig(config); - - return config; -}; - -const createServiceManager = () => { - const shutdownHandlers = []; - return { - pushService: (object, shutdownHandlerName) => { - shutdownHandlers.push(() => { object[shutdownHandlerName](); }); - }, - stopAll: () => { - while (0 < shutdownHandlers.length) - shutdownHandlers.pop()(); - } - }; -}; - -const connectToDbWithRetry = (db, config) => catapult.utils.future.makeRetryable( - () => db.connect(config.url, config.name, config.connectionPoolSize), - config.maxConnectionAttempts, - (i, err) => { - const waitTime = (2 ** (i - 1)) * config.baseRetryDelay; - winston.warn(`db connection failed, retrying in ${waitTime}ms`, err); - return waitTime; - } -); - -const createServer = config => { - const modelSystem = catapult.plugins.catapultModelSystem.configure(config.extensions, { - json: dbFormattingRules, - ws: messageFormattingRules - }); - return { - server: bootstrapper.createServer(config, formatters.create(modelSystem.formatters), config.throttling), - codec: modelSystem.codec - }; -}; - -const registerRoutes = (server, db, services) => { - // 1. create a services view for extension routes - const servicesView = { - config: { - network: services.config.network, - pageSize: { - min: services.config.db.pageSizeMin || 10, - max: services.config.db.pageSizeMax || 100, - default: services.config.db.pageSizeDefault || 20 - }, - apiNode: services.config.apiNode, - websocket: services.config.websocket, - numBlocksTransactionFeeStats: services.config.numBlocksTransactionFeeStats, - deployment: services.config.deployment, - - uncirculatingAccountPublicKeys: services.config.uncirculatingAccountPublicKeys - }, - connections: services.connectionService - }; - - // 2. configure extension routes - const { transactionStates, messageChannelDescriptors } = routeSystem.configure(services.config.extensions, server, db, servicesView); - - // 3. augment services with extension-dependent config and services - servicesView.config.transactionStates = transactionStates; - servicesView.zmqService = createZmqConnectionService(services.config.websocket.mq, services.codec, messageChannelDescriptors, winston); - - // 4. configure basic routes - allRoutes.register(server, db, servicesView); -}; - -(() => { - const config = loadConfig(); - - configureLogging(config.logging); - winston.verbose('finished loading rest server config', config); - - // Loading and caching certificates. - config.apiNode = { - ...config.apiNode, - certificate: fs.readFileSync(config.apiNode.tlsClientCertificatePath), - key: fs.readFileSync(config.apiNode.tlsClientKeyPath), - caCertificate: fs.readFileSync(config.apiNode.tlsCaCertificatePath) - }; - const nodeCertKey = sshpk.parsePrivateKey(config.apiNode.key); - config.apiNode.nodePublicKey = nodeCertKey.toPublic().part.A.data; - - const network = catapult.model.networkInfo.networks[config.network.name]; - if (!network) { - winston.error(`no network found with name: '${config.network.name}'`); - return; - } - - const serviceManager = createServiceManager(); - const db = new CatapultDb({ - networkId: network.id, - - // to be removed when old pagination is not used anymore - // json settings should also be moved from config.db to config.api or similar - pageSizeMin: config.db.pageSizeMin, - pageSizeMax: config.db.pageSizeMax - }); - - serviceManager.pushService(db, 'close'); - - winston.info(`connecting to ${config.db.url} (database:${config.db.name})`); - connectToDbWithRetry(db, config.db) - .then(() => { - winston.info('registering routes'); - const serverAndCodec = createServer(config); - const { server } = serverAndCodec; - serviceManager.pushService(server, 'close'); - - const connectionConfig = { - apiNode: config.apiNode - }; - const connectionService = createConnectionService(connectionConfig, winston.verbose); - registerRoutes(server, db, { codec: serverAndCodec.codec, config, connectionService }); - - winston.info(`listening on port ${config.port}`); - server.listen(config.port); - }) - .catch(err => { - winston.error('rest server is exiting due to error', err); - serviceManager.stopAll(); - }); - - process.on('SIGINT', () => { - winston.info('SIGINT detected, shutting down rest server'); - serviceManager.stopAll(); - }); -})(); diff --git a/rest/src/plugins/AccountType.js b/rest/src/plugins/AccountType.js deleted file mode 100644 index ec82c8b56..000000000 --- a/rest/src/plugins/AccountType.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** - * Account id types. - * @enum {string} - * @exports db/AccountType - */ -const AccountType = { - /** Account id is a public key */ - publicKey: 'publicKey', - - /** Account id is an address */ - address: 'address' -}; - -module.exports = AccountType; diff --git a/rest/src/plugins/CatapultRestPlugin.js b/rest/src/plugins/CatapultRestPlugin.js deleted file mode 100644 index d062e164c..000000000 --- a/rest/src/plugins/CatapultRestPlugin.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/CatapultRestPlugin */ - -// this file only contains an interface for prettier documentation, so ignore no-unused-vars warnings - -/* eslint-disable no-unused-vars */ - -/** - * A transaction state descriptor. - * @typedef {object} TransactionStateDescriptor - * @property {string} friendlyName Friendly name. - * @property {string} dbPostfix Database function name postfix. - * @property {string} routePostfix Route postfix. - */ - -/** - * Adds rest support for a particular subsystem. - * @interface - */ -module.exports = { - /** - * Creates a plugin specific database. - * @instance - * @param {module:db/CatapultDb} db Catapult database. - */ - createDb: db => {}, - - /** - * Registers transaction state descriptors. - * @instance - * @param {array} states Transaction state descriptors. - */ - registerTransactionStates: states => {}, - - /** - * Registers message channels. - * @instance - * @param {module:connection/MessageChannelBuilder~MessageChannelBuilder} builder Message channel builder. - */ - registerMessageChannels: builder => {}, - - /** - * Registers route extensions. - * @instance - * @param {...args} args Arguments needed to register the routes. - */ - registerRoutes: (...args) => {} -}; - -/* eslint-enable */ diff --git a/rest/src/plugins/aggregate/aggregate.js b/rest/src/plugins/aggregate/aggregate.js deleted file mode 100644 index 2e68037a2..000000000 --- a/rest/src/plugins/aggregate/aggregate.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/aggregate */ -const aggregateRoutes = require('./aggregateRoutes'); -const { ServerMessageHandler } = require('../../connection/serverMessageHandlers'); -const catapult = require('catapult-sdk'); - -const { BinaryParser } = catapult.parser; - -/** - * Creates an aggregate plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: () => {}, - - registerTransactionStates: states => { - states.push({ friendlyName: 'partial', dbPostfix: 'Partial', routePostfix: '/partial' }); - }, - - registerMessageChannels: builder => { - builder.add('partialAdded', 'p', ServerMessageHandler.transaction); - builder.add('partialRemoved', 'q', ServerMessageHandler.transactionHash); - builder.add('cosignature', 'c', (codec, emit) => (topic, buffer) => { - const parser = new BinaryParser(); - parser.push(buffer); - - const version = parser.uint64(); - const signerPublicKey = parser.buffer(catapult.constants.sizes.signerPublicKey); - const signature = parser.buffer(catapult.constants.sizes.signature); - const parentHash = parser.buffer(catapult.constants.sizes.hash256); - emit({ - type: 'aggregate.cosignature', - payload: { - version, - signerPublicKey, - signature, - parentHash - } - }); - }); - }, - - registerRoutes: (...args) => { - aggregateRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/aggregate/aggregateRoutes.js b/rest/src/plugins/aggregate/aggregateRoutes.js deleted file mode 100644 index 37cb77e2f..000000000 --- a/rest/src/plugins/aggregate/aggregateRoutes.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { convert, uint64 } = catapult.utils; -const { PacketType } = catapult.packet; - -module.exports = { - register: (server, db, services) => { - const parseUint64StringToUint8Buffer = numericString => convert.hexToUint8(uint64.toHex(uint64.fromString(numericString))); - const parseHexParam = (params, key) => routeUtils.parseArgument(params, key, convert.hexToUint8); - - routeUtils.addPutPacketRoute( - server, - services.connections, - { routeName: '/transactions/partial', packetType: PacketType.pushPartialTransactions }, - params => parseHexParam(params, 'payload') - ); - - routeUtils.addPutPacketRoute( - server, - services.connections, - { routeName: '/transactions/cosignature', packetType: PacketType.pushDetachedCosignatures }, - params => Buffer.concat( - [parseUint64StringToUint8Buffer(params.version)].concat( - ['signerPublicKey', 'signature', 'parentHash'].map(key => parseHexParam(params, key)) - ) - ) - ); - } -}; diff --git a/rest/src/plugins/empty.js b/rest/src/plugins/empty.js deleted file mode 100644 index cf2268d0a..000000000 --- a/rest/src/plugins/empty.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/empty */ - -/** - * Creates an empty plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: () => undefined, - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: () => {} -}; diff --git a/rest/src/plugins/lockHash/LockHashDb.js b/rest/src/plugins/lockHash/LockHashDb.js deleted file mode 100644 index 129ee2da9..000000000 --- a/rest/src/plugins/lockHash/LockHashDb.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { buildOffsetCondition } = require('../../db/dbUtils'); - -class LockHashDb { - /** - * Creates LockHashDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - // region lock retrieval - - /** - * Retrieves hash lock infos for given accounts filtered and paginated. - * @param {array<{Uint8Array}>} addresses Account addresses. - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Hash lock infos for all accounts. - */ - hashLocks(addresses, options) { - const sortingOptions = { id: '_id' }; - const buffers = addresses.map(address => Buffer.from(address)); - let conditions = {}; - if (addresses.length) - conditions['lock.ownerAddress'] = { $in: buffers }; - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, 'hashLocks', options); - } - - /** - * Retrieves hash info for given hash. - * @param {Uint8Array[]} ids Lock hash. - * @returns {Promise.} Hash lock info for a hash. - */ - hashLockByHash(ids) { - const hashes = ids.map(id => Buffer.from(id)); - const conditions = { 'lock.hash': { $in: hashes } }; - const collection = this.catapultDb.database.collection('hashLocks'); - return collection.find(conditions) - .sort({ _id: -1 }) - .toArray() - .then(entities => Promise.resolve(this.catapultDb.sanitizer.renameIds(entities))); - } - - // endregion -} - -module.exports = LockHashDb; diff --git a/rest/src/plugins/lockHash/lockHash.js b/rest/src/plugins/lockHash/lockHash.js deleted file mode 100644 index fda5dee3d..000000000 --- a/rest/src/plugins/lockHash/lockHash.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/lockHash */ -const LockHashDb = require('./LockHashDb'); -const lockHashRoutes = require('./lockHashRoutes'); - -/** - * Creates a lock hash plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new LockHashDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - lockHashRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/lockHash/lockHashRoutes.js b/rest/src/plugins/lockHash/lockHashRoutes.js deleted file mode 100644 index 41d063a18..000000000 --- a/rest/src/plugins/lockHash/lockHashRoutes.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const merkleUtils = require('../../routes/merkleUtils'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -module.exports = { - register: (server, db, services) => { - const sender = routeUtils.createSender('hashLockInfo'); - - server.get('/account/:address/lock/hash', (req, res, next) => { - const accountAddress = routeUtils.parseArgument(req.params, 'address', 'address'); - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, { id: 'objectId' }); - return db.hashLocks([accountAddress], options) - .then(result => sender.sendPage(res, next)(result)); - }); - - // Search - server.get('/lock/hash', (req, res, next) => { - const accountAddresses = req.params.address ? [routeUtils.parseArgument(req.params, 'address', 'address')] : []; - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, { id: 'objectId' }); - return db.hashLocks(accountAddresses, options) - .then(result => sender.sendPage(res, next)(result)); - }); - - // Get by ids - routeUtils.addGetPostDocumentRoutes( - server, - sender, - { base: '/lock/hash', singular: 'hash', plural: 'hashes' }, - params => db.hashLockByHash(params), - routeUtils.namedParserMap.hash256 - ); - - // Merkle - server.get('/lock/hash/:hash/merkle', (req, res, next) => { - const hash = routeUtils.parseArgument(req.params, 'hash', 'hash256'); - const state = PacketType.hashLockStatePath; - return merkleUtils.requestTree(services, state, - hash).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/plugins/lockSecret/LockSecretDb.js b/rest/src/plugins/lockSecret/LockSecretDb.js deleted file mode 100644 index 0b532b90a..000000000 --- a/rest/src/plugins/lockSecret/LockSecretDb.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { buildOffsetCondition } = require('../../db/dbUtils'); - -class LockSecretDb { - /** - * Creates LockSecretDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - // region lock retrieval - - /** - * Retrieves secret infos for given accounts filtered and paginated. - * @param {array<{Uint8Array}>} addresses Account addresses. - * @param {Uint8Array} secret Secret hash. - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Secret lock infos for all accounts. - */ - secretLocks(addresses, secret, options) { - const sortingOptions = { id: '_id' }; - const buffers = addresses.map(address => Buffer.from(address)); - let conditions = {}; - - if (addresses.length) - conditions['lock.ownerAddress'] = { $in: buffers }; - - if (undefined !== secret) - conditions['lock.secret'] = Buffer.from(secret); - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, 'secretLocks', options); - } - - secretLocksByCompositeHash(ids) { - const compositeHashes = ids.map(id => Buffer.from(id)); - const conditions = { 'lock.compositeHash': { $in: compositeHashes } }; - const collection = this.catapultDb.database.collection('secretLocks'); - return collection.find(conditions) - .sort({ _id: -1 }) - .toArray() - .then(entities => Promise.resolve(this.catapultDb.sanitizer.renameIds(entities))); - } - - // endregion -} - -module.exports = LockSecretDb; diff --git a/rest/src/plugins/lockSecret/lockSecret.js b/rest/src/plugins/lockSecret/lockSecret.js deleted file mode 100644 index 01d47083a..000000000 --- a/rest/src/plugins/lockSecret/lockSecret.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/lockSecret */ -const LockSecretDb = require('./LockSecretDb'); -const lockSecretRoutes = require('./lockSecretRoutes'); - -/** - * Creates a lock secret plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new LockSecretDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - lockSecretRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/lockSecret/lockSecretRoutes.js b/rest/src/plugins/lockSecret/lockSecretRoutes.js deleted file mode 100644 index 9ecce0404..000000000 --- a/rest/src/plugins/lockSecret/lockSecretRoutes.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const merkleUtils = require('../../routes/merkleUtils'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -module.exports = { - register: (server, db, services) => { - const sender = routeUtils.createSender('secretLockInfo'); - - server.get('/account/:address/lock/secret', (req, res, next) => { - const { params } = req; - const accountAddresses = params.address ? [routeUtils.parseArgument(params, 'address', 'address')] : []; - const secret = params.secret ? routeUtils.parseArgument(params, 'secret', 'hash256') : undefined; - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, { id: 'objectId' }); - return db.secretLocks(accountAddresses, secret, options) - .then(result => sender.sendPage(res, next)(result)); - }); - - server.get('/lock/secret', (req, res, next) => { - const { params } = req; - const accountAddresses = params.address ? [routeUtils.parseArgument(params, 'address', 'address')] : []; - const secret = params.secret ? routeUtils.parseArgument(params, 'secret', 'hash256') : undefined; - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, { id: 'objectId' }); - return db.secretLocks(accountAddresses, secret, options) - .then(result => sender.sendPage(res, next)(result)); - }); - - routeUtils.addGetPostDocumentRoutes( - server, - sender, - { base: '/lock/secret', singular: 'compositeHash', plural: 'compositeHashes' }, - params => db.secretLocksByCompositeHash(params), - routeUtils.namedParserMap.hash256 - ); - - server.get('/lock/secret/:compositeHash/merkle', (req, res, next) => { - const compositeHash = routeUtils.parseArgument(req.params, 'compositeHash', 'hash256'); - const state = PacketType.secretLockStatePath; - return merkleUtils.requestTree(services, state, - compositeHash).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/plugins/metadata/MetadataDb.js b/rest/src/plugins/metadata/MetadataDb.js deleted file mode 100644 index d08c3d50e..000000000 --- a/rest/src/plugins/metadata/MetadataDb.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong, buildOffsetCondition } = require('../../db/dbUtils'); - -class MetadataDb { - /** - * Creates MetadataDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - /** - * Retrieves filtered and paginated metadata. - * @param {Uint8Array} sourceAddress Metadata source address - * @param {Uint8Array} targetAddress Metadata target address - * @param {Uint64} scopedMetadataKey Metadata scoped key - * @param {Uint64} targetId Metadata target id - * @param {Uint32} metadataType Metadata type - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Metadata page. - */ - metadata(sourceAddress, targetAddress, scopedMetadataKey, targetId, metadataType, options) { - const sortingOptions = { id: '_id' }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== sourceAddress) - conditions['metadataEntry.sourceAddress'] = Buffer.from(sourceAddress); - - if (undefined !== targetAddress) - conditions['metadataEntry.targetAddress'] = Buffer.from(targetAddress); - - if (undefined !== scopedMetadataKey) - conditions['metadataEntry.scopedMetadataKey'] = convertToLong(scopedMetadataKey); - - if (undefined !== targetId) - conditions['metadataEntry.targetId'] = convertToLong(targetId); - - if (undefined !== metadataType) - conditions['metadataEntry.metadataType'] = metadataType; - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, 'metadata', options); - } - - metadatasByCompositeHash(ids) { - const compositeHashes = ids.map(id => Buffer.from(id)); - const conditions = { 'metadataEntry.compositeHash': { $in: compositeHashes } }; - const collection = this.catapultDb.database.collection('metadata'); - return collection.find(conditions) - .sort({ _id: -1 }) - .toArray() - .then(entities => Promise.resolve(this.catapultDb.sanitizer.renameIds(entities))); - } -} - -module.exports = MetadataDb; diff --git a/rest/src/plugins/metadata/metadata.js b/rest/src/plugins/metadata/metadata.js deleted file mode 100644 index 47606f88d..000000000 --- a/rest/src/plugins/metadata/metadata.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/metadata */ -const MetadataDb = require('./MetadataDb'); -const metadataRoutes = require('./metadataRoutes'); - -/** - * Creates a metadata plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new MetadataDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - metadataRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/metadata/metadataRoutes.js b/rest/src/plugins/metadata/metadataRoutes.js deleted file mode 100644 index 472a117f7..000000000 --- a/rest/src/plugins/metadata/metadataRoutes.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const merkleUtils = require('../../routes/merkleUtils'); -const routeResultTypes = require('../../routes/routeResultTypes'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -module.exports = { - register: (server, db, services) => { - const metadataSender = routeUtils.createSender(routeResultTypes.metadata); - - server.get('/metadata', (req, res, next) => { - const { params } = req; - const sourceAddress = params.sourceAddress ? routeUtils.parseArgument(params, 'sourceAddress', 'address') : undefined; - const targetAddress = params.targetAddress ? routeUtils.parseArgument(params, 'targetAddress', 'address') : undefined; - const scopedMetadataKey = params.scopedMetadataKey - ? routeUtils.parseArgument(params, 'scopedMetadataKey', 'uint64hex') : undefined; - const targetId = params.targetId ? routeUtils.parseArgument(params, 'targetId', 'uint64hex') : undefined; - const metadataType = params.metadataType ? routeUtils.parseArgument(params, 'metadataType', 'uint') : undefined; - - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, { id: 'objectId' }); - - return db.metadata(sourceAddress, targetAddress, scopedMetadataKey, targetId, metadataType, options) - .then(result => metadataSender.sendPage(res, next)(result)); - }); - - routeUtils.addGetPostDocumentRoutes( - server, - metadataSender, - { base: '/metadata', singular: 'compositeHash', plural: 'compositeHashes' }, - params => db.metadatasByCompositeHash(params), - routeUtils.namedParserMap.hash256 - ); - - // this endpoint is here because it is expected to support requests by block other than - server.get('/metadata/:compositeHash/merkle', (req, res, next) => { - const compositeHash = routeUtils.parseArgument(req.params, 'compositeHash', 'hash256'); - const state = PacketType.metadataStatePath; - return merkleUtils.requestTree(services, state, compositeHash).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/plugins/mosaic/MosaicDb.js b/rest/src/plugins/mosaic/MosaicDb.js deleted file mode 100644 index 9467a2d7a..000000000 --- a/rest/src/plugins/mosaic/MosaicDb.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { buildOffsetCondition } = require('../../db/dbUtils'); -const MongoDb = require('mongodb'); - -const { Long } = MongoDb; - -class MosaicDb { - /** - * Creates MosaicDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - /** - * Retrieves filtered and paginated mosaics. - * @param {Uint8Array} ownerAddress Mosaic owner address - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Mosaics page. - */ - mosaics(ownerAddress, options) { - const sortingOptions = { id: '_id' }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== ownerAddress) - conditions['mosaic.ownerAddress'] = Buffer.from(ownerAddress); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, 'mosaics', options); - } - - /** - * Retrieves mosaics given their ids. - * @param {Array.} ids Mosaic ids. - * @returns {Promise.} Mosaics. - */ - mosaicsByIds(ids) { - const mosaicIds = ids.map(id => new Long(id[0], id[1])); - const conditions = { 'mosaic.id': { $in: mosaicIds } }; - const collection = this.catapultDb.database.collection('mosaics'); - return collection.find(conditions) - .sort({ _id: -1 }) - .toArray() - .then(entities => Promise.resolve(this.catapultDb.sanitizer.renameIds(entities))); - } -} - -module.exports = MosaicDb; diff --git a/rest/src/plugins/mosaic/mosaic.js b/rest/src/plugins/mosaic/mosaic.js deleted file mode 100644 index b626fa2b1..000000000 --- a/rest/src/plugins/mosaic/mosaic.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/mosaic */ -const MosaicDb = require('./MosaicDb'); -const mosaicRoutes = require('./mosaicRoutes'); -const supplyRoutes = require('./supplyRoutes'); - -/** - * Creates a mosaic plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new MosaicDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - mosaicRoutes.register(...args); - supplyRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/mosaic/mosaicRoutes.js b/rest/src/plugins/mosaic/mosaicRoutes.js deleted file mode 100644 index 43c4aaa39..000000000 --- a/rest/src/plugins/mosaic/mosaicRoutes.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const merkleUtils = require('../../routes/merkleUtils'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -const { uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - const mosaicSender = routeUtils.createSender('mosaicDescriptor'); - - server.get('/mosaics', (req, res, next) => { - const ownerAddress = req.params.ownerAddress ? routeUtils.parseArgument(req.params, 'ownerAddress', 'address') : undefined; - - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, { id: 'objectId' }); - - return db.mosaics(ownerAddress, options) - .then(result => mosaicSender.sendPage(res, next)(result)); - }); - - routeUtils.addGetPostDocumentRoutes( - server, - mosaicSender, - { base: '/mosaics', singular: 'mosaicId', plural: 'mosaicIds' }, - params => db.mosaicsByIds(params), - uint64.fromHex - ); - - // this endpoint is here because it is expected to support requests by block other than - server.get('/mosaics/:mosaicId/merkle', (req, res, next) => { - const mosaicId = routeUtils.parseArgument(req.params, 'mosaicId', - 'uint64hex'); - const state = PacketType.mosaicStatePath; - - return merkleUtils.requestTree(services, state, - uint64.toBytes(mosaicId)).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/plugins/mosaic/supplyRoutes.js b/rest/src/plugins/mosaic/supplyRoutes.js deleted file mode 100644 index 9e3ea4898..000000000 --- a/rest/src/plugins/mosaic/supplyRoutes.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { longToUint64 } = require('../../db/dbUtils'); -const routeUtils = require('../../routes/routeUtils'); -const AccountType = require('../AccountType'); -const catapult = require('catapult-sdk'); -const ini = require('ini'); -const fs = require('fs'); -const util = require('util'); - -const { convert, uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - const sender = routeUtils.createSender('supply'); - - const convertToFractionalWholeUnits = (value, divisibility) => (Number(value) / (10 ** divisibility)).toFixed(divisibility); - - const propertyValueToMosaicId = value => uint64.fromHex(value.replace(/'/g, '').replace('0x', '')); - - const readAndParseNetworkPropertiesFile = () => { - const readFile = util.promisify(fs.readFile); - return readFile(services.config.apiNode.networkPropertyFilePath, 'utf8') - .then(fileData => ini.parse(fileData)); - }; - - const getMosaicProperties = async currencyMosaicId => { - const mosaics = await db.mosaicsByIds([currencyMosaicId]); - return { - totalSupply: mosaics[0].mosaic.supply.toNumber(), - divisibility: mosaics[0].mosaic.divisibility - }; - }; - - const getUncirculatingAccountIds = propertiesObject => { - const publicKeys = [propertiesObject.network.nemesisSignerPublicKey].concat(services.config.uncirculatingAccountPublicKeys); - return publicKeys.map(publicKey => ({ [AccountType.publicKey]: convert.hexToUint8(publicKey) })); - }; - - const lookupMosaicAmount = (mosaics, currencyMosaicId) => { - const matchingMosaic = mosaics.find(mosaic => { - const mosaicId = longToUint64(mosaic.id); // convert Long to uint64 - return 0 === uint64.compare(currencyMosaicId, mosaicId); - }); - - return undefined === matchingMosaic ? 0 : matchingMosaic.amount.toNumber(); - }; - - server.get('/network/currency/supply/circulating', (req, res, next) => readAndParseNetworkPropertiesFile() - .then(async propertiesObject => { - const currencyMosaicId = propertyValueToMosaicId(propertiesObject.chain.currencyMosaicId); - const currencyMosaicProperties = await getMosaicProperties(currencyMosaicId); - - const accounts = await db.catapultDb.accountsByIds(getUncirculatingAccountIds(propertiesObject)); - const burnedSupply = accounts.reduce( - (sum, account) => sum + lookupMosaicAmount(account.account.mosaics, currencyMosaicId), - 0 - ); - - sender.sendPlainText(res, next)(convertToFractionalWholeUnits( - currencyMosaicProperties.totalSupply - burnedSupply, - currencyMosaicProperties.divisibility - )); - })); - - server.get('/network/currency/supply/total', (req, res, next) => readAndParseNetworkPropertiesFile() - .then(async propertiesObject => { - const currencyMosaicId = propertyValueToMosaicId(propertiesObject.chain.currencyMosaicId); - const currencyMosaicProperties = await getMosaicProperties(currencyMosaicId); - sender.sendPlainText(res, next)(convertToFractionalWholeUnits( - currencyMosaicProperties.totalSupply, - currencyMosaicProperties.divisibility - )); - })); - - server.get('/network/currency/supply/max', (req, res, next) => readAndParseNetworkPropertiesFile() - .then(async propertiesObject => { - const currencyMosaicId = propertyValueToMosaicId(propertiesObject.chain.currencyMosaicId); - const currencyMosaicProperties = await getMosaicProperties(currencyMosaicId); - - const maxSupply = parseInt(propertiesObject.chain.maxMosaicAtomicUnits.replace(/'/g, ''), 10); - sender.sendPlainText(res, next)(convertToFractionalWholeUnits(maxSupply, currencyMosaicProperties.divisibility)); - })); - } -}; diff --git a/rest/src/plugins/multisig/MultisigDb.js b/rest/src/plugins/multisig/MultisigDb.js deleted file mode 100644 index d8525b5bc..000000000 --- a/rest/src/plugins/multisig/MultisigDb.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -class MultisigDb { - /** - * Creates MultisigDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - // region multisig retrieval - - /** - * Retrieves the multisig entries for given account addresses. - * @param {array<{Uint8Array}>} addresses Addresses. - * @returns {Promise.} Multisig entries for all addresses. - */ - multisigsByAddresses(addresses) { - const buffers = addresses.map(address => Buffer.from(address)); - return this.catapultDb.queryDocuments('multisigs', { 'multisig.accountAddress': { $in: buffers } }); - } - - // endregion -} - -module.exports = MultisigDb; diff --git a/rest/src/plugins/multisig/multisig.js b/rest/src/plugins/multisig/multisig.js deleted file mode 100644 index b24551241..000000000 --- a/rest/src/plugins/multisig/multisig.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/multisig */ -const MultisigDb = require('./MultisigDb'); -const multisigRoutes = require('./multisigRoutes'); - -/** - * Creates a multisig plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new MultisigDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - multisigRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/multisig/multisigRoutes.js b/rest/src/plugins/multisig/multisigRoutes.js deleted file mode 100644 index ca291ac6c..000000000 --- a/rest/src/plugins/multisig/multisigRoutes.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const multisigUtils = require('./multisigUtils'); -const merkleUtils = require('../../routes/merkleUtils'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -module.exports = { - register: (server, db, services) => { - server.get('/account/:address/multisig', (req, res, next) => { - const accountAddress = routeUtils.parseArgument(req.params, 'address', 'address'); - - return db.multisigsByAddresses([accountAddress]) - .then(routeUtils.createSender('multisigEntry').sendOne(req.params.address, res, next)); - }); - - server.get('/account/:address/multisig/merkle', (req, res, next) => { - const accountAddress = routeUtils.parseArgument(req.params, 'address', 'address'); - const state = PacketType.multisigStatePath; - return merkleUtils.requestTree(services, state, - accountAddress).then(response => { - res.send(response); - next(); - }); - }); - - server.get('/account/:address/multisig/graph', (req, res, next) => { - const accountAddress = routeUtils.parseArgument(req.params, 'address', 'address'); - return multisigUtils.getMultisigGraph(db, accountAddress) - .then(response => { - const sender = routeUtils.createSender('multisigGraph'); - return undefined === response - ? sender.sendOne(req.params.address, res, next)(response) - : sender.sendArray(req.params.address, res, next)(response); - }); - }); - } -}; diff --git a/rest/src/plugins/multisig/multisigUtils.js b/rest/src/plugins/multisig/multisigUtils.js deleted file mode 100644 index 56f5c7433..000000000 --- a/rest/src/plugins/multisig/multisigUtils.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const multisigUtils = { - getMultisigGraph: (db, address) => { - const getMultisigEntries = (multisigEntries, fieldName) => { - const addresses = new Set(); - multisigEntries.forEach(multisigEntry => multisigEntry.multisig[fieldName].forEach(multisigAddress => { - addresses.add(multisigAddress.buffer); - })); - - return db.multisigsByAddresses(Array.from(addresses)); - }; - - const multisigLevels = []; - return db.multisigsByAddresses([address]) - .then(multisigEntries => { - if (0 === multisigEntries.length) - return Promise.resolve(undefined); - - multisigLevels.push({ - level: 0, - multisigEntries: [multisigEntries[0]] - }); - - return Promise.resolve(multisigEntries[0]); - }) - .then(multisigEntry => { - if (undefined === multisigEntry) - return Promise.resolve(undefined); - - const handleUpstream = (level, multisigEntries) => getMultisigEntries(multisigEntries, 'multisigAddresses') - .then(entries => { - if (0 === entries.length) - return Promise.resolve(); - - multisigLevels.unshift({ level, multisigEntries: entries }); - return handleUpstream(level - 1, entries); - }); - - const handleDownstream = (level, multisigEntries) => getMultisigEntries(multisigEntries, 'cosignatoryAddresses') - .then(entries => { - if (0 === entries.length) - return Promise.resolve(); - - multisigLevels.push({ level, multisigEntries: entries }); - return handleDownstream(level + 1, entries); - }); - - const upstreamPromise = handleUpstream(-1, [multisigEntry]); - const downstreamPromise = handleDownstream(1, [multisigEntry]); - return Promise.all([upstreamPromise, downstreamPromise]) - .then(() => multisigLevels); - }); - } - -}; - -module.exports = multisigUtils; diff --git a/rest/src/plugins/namespace/NamespaceDb.js b/rest/src/plugins/namespace/NamespaceDb.js deleted file mode 100644 index f7a998905..000000000 --- a/rest/src/plugins/namespace/NamespaceDb.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong, buildOffsetCondition, longToUint64 } = require('../../db/dbUtils'); -const catapult = require('catapult-sdk'); - -const { uint64 } = catapult.utils; - -const createLatestConditions = (catapultDb, height) => { - if (height) { - return ({ - $and: [{ 'meta.latest': true }, { - $or: [ - { 'namespace.endHeight': convertToLong(-1) }, - { 'namespace.endHeight': { $gt: height } }] - }] - }); - } - return { 'meta.latest': true }; -}; - -const addActiveFlag = (namespace, height) => { - if (!namespace) - return namespace; - - // What about calculated fields in mongo? - const endHeightUint64 = longToUint64(namespace.namespace.endHeight); - const heightUint64 = longToUint64(convertToLong(height)); - namespace.meta.active = 1 === uint64.compare(endHeightUint64, heightUint64); - return namespace; -}; - -class NamespaceDb { - /** - * Creates NamespaceDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - // region namespace retrieval - - /** - * Retrieves filtered and paginated namespaces. - * @param {Uint32} aliasType Namespace alias type - * @param {module:catapult.utils/uint64~uint64} level0 Namespace level0 - * @param {Uint8Array} ownerAddress Namespace owner address - * @param {Uint32} registrationType Namespace registration type - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Namespaces page. - */ - async namespaces(aliasType, level0, ownerAddress, registrationType, options) { - const sortingOptions = { id: '_id' }; - let conditions = {}; - const { height } = await this.catapultDb.chainStatisticCurrent(); - const activeConditions = createLatestConditions(this.catapultDb); - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== aliasType) - conditions['namespace.alias.type'] = aliasType; - - if (undefined !== level0) - conditions['namespace.level0'] = convertToLong(level0); - - if (undefined !== ownerAddress) - conditions['namespace.ownerAddress'] = Buffer.from(ownerAddress); - - if (undefined !== registrationType) - conditions['namespace.registrationType'] = registrationType; - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments({ $and: [activeConditions, conditions] }, [], - sortConditions, 'namespaces', options, n => addActiveFlag(n, height)); - } - - /** - * Retrieves a namespace. - * @param {module:catapult.utils/uint64~uint64} id Namespace id. - * @returns {Promise.} Namespace. - */ - async namespaceById(id) { - const { height } = await this.catapultDb.chainStatisticCurrent(); - const activeConditions = createLatestConditions(this.catapultDb); - const topLevelConditions = { $or: [] }; - - for (let level = 0; 3 > level; ++level) { - const conditions = []; - conditions.push(activeConditions); - conditions.push({ [`namespace.level${level}`]: convertToLong(id) }); - conditions.push({ 'namespace.depth': level + 1 }); - topLevelConditions.$or.push({ $and: conditions }); - } - - return this.catapultDb.queryDocument('namespaces', topLevelConditions) - .then(this.catapultDb.sanitizer.renameId).then(n => addActiveFlag(n, height)); - } - - /** - * Retrieves non expired namespaces aliasing mosaics or addresses. - * @param {Array.} aliasType Alias type. - * @param {*} ids Set of mosaic or address ids. - * @returns {Promise.} Active namespaces aliasing ids. - */ - async activeNamespacesWithAlias(aliasType, ids) { - const aliasFilterCondition = { - [catapult.model.namespace.aliasType.mosaic]: () => ({ 'namespace.alias.mosaicId': { $in: ids.map(convertToLong) } }), - [catapult.model.namespace.aliasType.address]: () => ({ 'namespace.alias.address': { $in: ids.map(id => Buffer.from(id)) } }) - }; - const { height } = await this.catapultDb.chainStatisticCurrent(); - const activeConditions = await createLatestConditions(this.catapultDb, height); - - const conditions = { $and: [] }; - conditions.$and.push(aliasFilterCondition[aliasType]()); - conditions.$and.push({ 'namespace.alias.type': aliasType }); - conditions.$and.push(activeConditions); - - return this.catapultDb.queryDocuments('namespaces', conditions).then(ns => ns.map(n => addActiveFlag(n, height))); - } - - // endregion - - /** - * Retrieves transactions that registered the specified namespaces. - * @param {Array.} namespaceIds Namespace ids. - * @returns {Promise.} Register namespace transactions. - */ - registerNamespaceTransactionsByNamespaceIds(namespaceIds) { - const type = catapult.model.EntityType.registerNamespace; - const conditions = { $and: [] }; - conditions.$and.push({ 'transaction.id': { $in: namespaceIds } }); - conditions.$and.push({ 'transaction.type': type }); - return this.catapultDb.queryDocuments('transactions', conditions); - } -} - -module.exports = NamespaceDb; diff --git a/rest/src/plugins/namespace/namespace.js b/rest/src/plugins/namespace/namespace.js deleted file mode 100644 index 48be35815..000000000 --- a/rest/src/plugins/namespace/namespace.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/namespace */ -const NamespaceDb = require('./NamespaceDb'); -const namespaceRoutes = require('./namespaceRoutes'); - -/** - * Creates a namespace plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new NamespaceDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - namespaceRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/namespace/namespaceRoutes.js b/rest/src/plugins/namespace/namespaceRoutes.js deleted file mode 100644 index 49e9289aa..000000000 --- a/rest/src/plugins/namespace/namespaceRoutes.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const namespaceUtils = require('./namespaceUtils'); -const dbUtils = require('../../db/dbUtils'); -const merkleUtils = require('../../routes/merkleUtils'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); -const MongoDb = require('mongodb'); - -const { PacketType } = catapult.packet; -const { Binary } = MongoDb; -const { convertToLong } = dbUtils; -const { uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - const namespaceSender = routeUtils.createSender('namespaceDescriptor'); - - server.get('/namespaces', (req, res, next) => { - const { params } = req; - - const ownerAddress = params.ownerAddress ? routeUtils.parseArgument(params, 'ownerAddress', 'address') : undefined; - const registrationType = params.registrationType ? routeUtils.parseArgument(params, 'registrationType', 'uint') : undefined; - const level0 = params.level0 ? routeUtils.parseArgument(req.params, 'level0', uint64.fromHex) : undefined; - const aliasType = params.aliasType ? routeUtils.parseArgument(params, 'aliasType', 'uint') : undefined; - - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, { id: 'objectId' }); - - return db.namespaces(aliasType, level0, ownerAddress, registrationType, options) - .then(result => namespaceSender.sendPage(res, next)(result)); - }); - - server.get('/namespaces/:namespaceId', (req, res, next) => { - const namespaceId = routeUtils.parseArgument(req.params, 'namespaceId', uint64.fromHex); - return db.namespaceById(namespaceId) - .then(namespaceSender.sendOne(req.params.namespaceId, res, next)); - }); - - const collectNames = (namespaceNameTuples, namespaceIds) => { - const type = catapult.model.EntityType.registerNamespace; - return db.catapultDb.findNamesByIds(namespaceIds, type, { id: 'id', name: 'name', parentId: 'parentId' }) - .then(nameTuples => { - nameTuples.forEach(nameTuple => { - // db returns null instead of undefined when parentId is not present - if (null === nameTuple.parentId) - delete nameTuple.parentId; - - namespaceNameTuples.push(nameTuple); - }); - - // process all parent namespaces next - return nameTuples - .filter(nameTuple => undefined !== nameTuple.parentId) - .map(nameTuple => nameTuple.parentId); - }); - }; - - server.post('/namespaces/names', (req, res, next) => { - const namespaceIds = routeUtils.parseArgumentAsArray(req.params, 'namespaceIds', uint64.fromHex); - const nameTuplesFuture = new Promise(resolve => { - const namespaceNameTuples = []; - const chain = nextIds => { - if (0 === nextIds.length) - resolve(namespaceNameTuples); - else - collectNames(namespaceNameTuples, nextIds).then(chain); - }; - - collectNames(namespaceNameTuples, namespaceIds).then(chain); - }); - - return nameTuplesFuture.then(routeUtils.createSender('namespaceNameTuple').sendArray('namespaceIds', res, next)); - }); - - server.post('/namespaces/mosaic/names', namespaceUtils.aliasNamesRoutesProcessor( - db, - catapult.model.namespace.aliasType.mosaic, - req => routeUtils.parseArgumentAsArray(req.params, 'mosaicIds', uint64.fromHex).map(convertToLong), - (namespace, id) => namespace.namespace.alias.mosaicId.equals(id), - 'mosaicId', - 'mosaicNames' - )); - - server.post('/namespaces/account/names', namespaceUtils.aliasNamesRoutesProcessor( - db, - catapult.model.namespace.aliasType.address, - req => routeUtils.parseArgumentAsArray(req.params, 'addresses', 'address'), - (namespace, id) => Buffer.from(namespace.namespace.alias.address.value()) - .equals(Buffer.from(new Binary(Buffer.from(id)).value())), - 'address', - 'accountNames' - )); - - // this endpoint is here because it is expected to support requests by block other than - server.get('/namespaces/:namespaceId/merkle', (req, res, next) => { - const namespaceId = routeUtils.parseArgument(req.params, 'namespaceId', 'uint64hex'); - const state = PacketType.namespaceStatePath; - return merkleUtils.requestTree(services, state, - uint64.toBytes(namespaceId)).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/plugins/namespace/namespaceUtils.js b/rest/src/plugins/namespace/namespaceUtils.js deleted file mode 100644 index c5e6bf45e..000000000 --- a/rest/src/plugins/namespace/namespaceUtils.js +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const namespaceUtils = { - /** - * Returns function for processing alias names requests. - * @param {module:db/CatapultDb} catapultDb Catapult database. - * @param {numeric} aliasType Alias type. - * @param {Function} getParams Function to parse request params into ids. - * @param {Function} namespaceFilter Function to filter namespaces based on ids. - * @param {string} aliasFieldName Alias field name to show in the results. - * @param {string} schemaName Schema name to parse results. - * @returns {Function} Restify response function to process alias names requests. - */ - aliasNamesRoutesProcessor: ( - catapultDb, - aliasType, - getParams, - namespaceFilter, - aliasFieldName, - schemaName - ) => (req, res, next) => { - const getNewestTransactions = transactions => { - const uniqueTransactions = []; - transactions.sort((lhs, rhs) => { - if (lhs.meta.height.equals(rhs.meta.height)) - return rhs.meta.index > lhs.meta.index ? 1 : -1; - return rhs.meta.height.greaterThan(lhs.meta.height) ? 1 : -1; - }); - transactions.forEach(t => { - if (!uniqueTransactions.some(ut => ut.namespaceId.equals(t.transaction.id))) { - uniqueTransactions.push({ - namespaceId: t.transaction.id, - name: t.transaction.name.value() - }); - } - }); - return uniqueTransactions; - }; - - const getOnlyNamespacesWithRegisterTransaction = (namespaces, transactions) => - namespaces.filter(n => transactions - .some(t => t.transaction.id.equals(n.namespace[`level${n.namespace.depth - 1}`]))); - - const ids = getParams(req); - - return catapultDb.activeNamespacesWithAlias(aliasType, ids).then(namespaces => { - const namespaceIds = []; - namespaces.forEach(n => { - namespaceIds.push(n.namespace.level0); - if (2 <= n.namespace.depth) - namespaceIds.push(n.namespace.level1); - if (3 <= n.namespace.depth) - namespaceIds.push(n.namespace.level2); - }); - - return catapultDb.registerNamespaceTransactionsByNamespaceIds(namespaceIds).then(transactions => { - const namespacesWithRegisterTransaction = getOnlyNamespacesWithRegisterTransaction(namespaces, transactions); - const uniqueTransactions = getNewestTransactions(transactions); - const namesTuples = ids.map(id => { - let aliasName; - const names = []; - namespacesWithRegisterTransaction.filter(n => namespaceFilter(n, id)) - .forEach(n => { - aliasName = uniqueTransactions.find(t => t.namespaceId.equals(n.namespace.level0)).name; - if (2 <= n.namespace.depth) - aliasName += `.${uniqueTransactions.find(t => t.namespaceId.equals(n.namespace.level1)).name}`; - if (3 <= n.namespace.depth) - aliasName += `.${uniqueTransactions.find(t => t.namespaceId.equals(n.namespace.level2)).name}`; - if (-1 === names.indexOf(aliasName)) - names.push(aliasName); - }); - return { [aliasFieldName]: id, names }; - }); - - res.send({ payload: { [schemaName]: namesTuples }, type: schemaName }); - - return next(); - }); - }); - } -}; - -module.exports = namespaceUtils; diff --git a/rest/src/plugins/receipts/ReceiptsDb.js b/rest/src/plugins/receipts/ReceiptsDb.js deleted file mode 100644 index d29911f80..000000000 --- a/rest/src/plugins/receipts/ReceiptsDb.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong, buildOffsetCondition } = require('../../db/dbUtils'); -const catapult = require('catapult-sdk'); - -const { convert, uint64 } = catapult.utils; - -const isNamespaceId = id => 0 !== (0x80 & convert.hexToUint8(uint64.toHex(id))[0]); - -class ReceiptsDb { - /** - * Creates ReceiptsDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - /** - * Retrieves filtered and paginated transaction statements. - * @param {object} filters Filters to be applied: `height`, `receiptType`, `recipientAddress`, `senderAddress`, `targetAddress`, - * `artifactId`. - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Transaction statements page. - */ - transactionStatements(filters, options) { - const sortingOptions = { id: '_id' }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== filters.height) - conditions['statement.height'] = convertToLong(filters.height); - - if (undefined !== filters.receiptType) - conditions['statement.receipts.type'] = { $in: filters.receiptType }; - - if (undefined !== filters.recipientAddress) - conditions['statement.receipts.recipientAddress'] = Buffer.from(filters.recipientAddress); - - if (undefined !== filters.senderAddress) - conditions['statement.receipts.senderAddress'] = Buffer.from(filters.senderAddress); - - if (undefined !== filters.targetAddress) - conditions['statement.receipts.targetAddress'] = Buffer.from(filters.targetAddress); - - if (undefined !== filters.artifactId) { - const artifactIdType = isNamespaceId(filters.artifactId) ? 'namespaceId' : 'mosaicId'; - conditions[[`statement.receipts.${artifactIdType}`]] = convertToLong(filters.artifactId); - } - - if (undefined !== filters.fromHeight || undefined !== filters.toHeight) { - const heightPath = 'statement.height'; - conditions[heightPath] = {}; - - if (undefined !== filters.fromHeight) - conditions[heightPath].$gte = convertToLong(filters.fromHeight); - - if (undefined !== filters.toHeight) - conditions[heightPath].$lte = convertToLong(filters.toHeight); - } - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, - 'transactionStatements', options).then(page => this.addBlockMeta(page)); - } - - /** - * Retrieves filtered and paginated artifact resolution statements. - * @param {numeric} height Statement height. - * @param {Uint8Array} artifact Must be provided, determines the type of statements that are being fetched. May be `address`, or - * `mosaic`. - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Artifact statements page. - */ - artifactStatements(height, artifact, options) { - const sortingOptions = { id: '_id' }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== height) - conditions['statement.height'] = convertToLong(height); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, - `${artifact}ResolutionStatements`, options).then(page => this.addBlockMeta(page)); - } - - /** - * It retrieves and adds the blocks information to the statements' meta. - * - * The block information includes the its timestamp - * - * @param {object} page the page without meta in the items. - * @returns {Promise<{pagination, data}>} the page with the added block's meta to the items. - */ - async addBlockMeta(page) { - const data = await this.catapultDb.addBlockMetaToEntityList(page.data, ['timestamp'], item => item.statement.height); - return { data, pagination: page.pagination }; - } -} - -module.exports = ReceiptsDb; diff --git a/rest/src/plugins/receipts/receipts.js b/rest/src/plugins/receipts/receipts.js deleted file mode 100644 index bab85b4cd..000000000 --- a/rest/src/plugins/receipts/receipts.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/receipts */ -const ReceiptsDb = require('./ReceiptsDb'); -const receiptsRoutes = require('./receiptsRoutes'); - -/** - * Creates a receipts plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new ReceiptsDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - receiptsRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/receipts/receiptsRoutes.js b/rest/src/plugins/receipts/receiptsRoutes.js deleted file mode 100644 index 3180439f7..000000000 --- a/rest/src/plugins/receipts/receiptsRoutes.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeResultTypes = require('../../routes/routeResultTypes'); -const routeUtils = require('../../routes/routeUtils'); -const { NotFoundError } = require('restify-errors'); - -module.exports = { - register: (server, db, services) => { - server.get('/statements/transaction', (req, res, next) => { - const { params } = req; - const filters = { - height: params.height ? routeUtils.parseArgument(params, 'height', 'uint64') : undefined, - fromHeight: params.fromHeight ? routeUtils.parseArgument(params, 'fromHeight', 'uint64') : undefined, - toHeight: params.toHeight ? routeUtils.parseArgument(params, 'toHeight', 'uint64') : undefined, - receiptType: params.receiptType ? routeUtils.parseArgumentAsArray(params, 'receiptType', 'uint') : undefined, - recipientAddress: params.recipientAddress ? routeUtils.parseArgument(params, 'recipientAddress', 'address') : undefined, - senderAddress: params.senderAddress ? routeUtils.parseArgument(params, 'senderAddress', 'address') : undefined, - targetAddress: params.targetAddress ? routeUtils.parseArgument(params, 'targetAddress', 'address') : undefined, - artifactId: params.artifactId ? routeUtils.parseArgument(params, 'artifactId', 'uint64hex') : undefined - }; - - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, { id: 'objectId' }); - - return db.transactionStatements(filters, options) - .then(result => routeUtils.createSender(routeResultTypes.transactionStatement).sendPage(res, next)(result)); - }); - - server.get('/statements/resolutions/:artifact', (req, res, next) => { - const { artifact } = req.params; - if (!artifact || !['address', 'mosaic'].includes(artifact)) - return next(new NotFoundError()); - - const height = req.params.height ? routeUtils.parseArgument(req.params, 'height', 'uint64') : undefined; - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, { id: 'objectId' }); - - return db.artifactStatements(height, artifact, options) - .then(result => routeUtils.createSender(routeResultTypes[`${artifact}ResolutionStatement`]).sendPage(res, next)(result)); - }); - - server.get( - '/blocks/:height/statements/:hash/merkle', - routeUtils.blockRouteMerkleProcessor(db.catapultDb, 'statementsCount', 'statementMerkleTree') - ); - } -}; diff --git a/rest/src/plugins/restrictions/RestrictionsDb.js b/rest/src/plugins/restrictions/RestrictionsDb.js deleted file mode 100644 index ac1c86c45..000000000 --- a/rest/src/plugins/restrictions/RestrictionsDb.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong, buildOffsetCondition } = require('../../db/dbUtils'); - -class RestrictionsDb { - /** - * Creates RestrictionsDb around CatapultDb. - * @param {module:db/CatapultDb} db Catapult db instance. - */ - constructor(db) { - this.catapultDb = db; - } - - /** - * Retrieves account restrictions for the given addresses. - * @param {array} addresses Given addresses. - * @returns {Promise.} Owned account restrictions. - */ - accountRestrictionsByAddresses(addresses) { - const buffers = addresses.map(address => Buffer.from(address)); - const conditions = { 'accountRestrictions.address': { $in: buffers } }; - return this.catapultDb.queryDocuments('accountRestrictions', conditions); - } - - /** - * Retrieves filtered and paginated mosaic restrictions. - * @param {Uint8Array} address Mosaic restriction target address - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Mosaic restrictions page. - */ - accountRestrictions(address, options) { - const sortingOptions = { id: '_id' }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== address) - conditions['accountRestrictions.address'] = Buffer.from(address); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, 'accountRestrictions', options); - } - - /** - * Retrieves filtered and paginated mosaic restrictions. - * @param {Uint64} mosaicId Mosaic id - * @param {uint} entryType Mosaic restriction type - * @param {Uint8Array} targetAddress Mosaic restriction target address - * @param {object} options Options for ordering and pagination. Can have an `offset`, and must contain the `sortField`, `sortDirection`, - * `pageSize` and `pageNumber`. 'sortField' must be within allowed 'sortingOptions'. - * @returns {Promise.} Mosaic restrictions page. - */ - mosaicRestrictions(mosaicId, entryType, targetAddress, options) { - const sortingOptions = { id: '_id' }; - - let conditions = {}; - - const offsetCondition = buildOffsetCondition(options, sortingOptions); - if (offsetCondition) - conditions = Object.assign(conditions, offsetCondition); - - if (undefined !== mosaicId) - conditions['mosaicRestrictionEntry.mosaicId'] = convertToLong(mosaicId); - - if (undefined !== entryType) - conditions['mosaicRestrictionEntry.entryType'] = entryType; - - if (undefined !== targetAddress) - conditions['mosaicRestrictionEntry.targetAddress'] = Buffer.from(targetAddress); - - const sortConditions = { [sortingOptions[options.sortField]]: options.sortDirection }; - return this.catapultDb.queryPagedDocuments(conditions, [], sortConditions, 'mosaicRestrictions', options); - } - - mosaicRestrictionByCompositeHash(ids) { - const compositeHashes = ids.map(id => Buffer.from(id)); - const conditions = { 'mosaicRestrictionEntry.compositeHash': { $in: compositeHashes } }; - const collection = this.catapultDb.database.collection('mosaicRestrictions'); - return collection.find(conditions) - .sort({ _id: -1 }) - .toArray() - .then(entities => Promise.resolve(this.catapultDb.sanitizer.renameIds(entities))); - } -} - -module.exports = RestrictionsDb; diff --git a/rest/src/plugins/restrictions/restrictions.js b/rest/src/plugins/restrictions/restrictions.js deleted file mode 100644 index af2d31486..000000000 --- a/rest/src/plugins/restrictions/restrictions.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module plugins/restrictions */ -const RestrictionsDb = require('./RestrictionsDb'); -const restrictionsRoutes = require('./restrictionsRoutes'); - -/** - * Creates a restrictions plugin. - * @type {module:plugins/CatapultRestPlugin} - */ -module.exports = { - createDb: db => new RestrictionsDb(db), - - registerTransactionStates: () => {}, - - registerMessageChannels: () => {}, - - registerRoutes: (...args) => { - restrictionsRoutes.register(...args); - } -}; diff --git a/rest/src/plugins/restrictions/restrictionsRoutes.js b/rest/src/plugins/restrictions/restrictionsRoutes.js deleted file mode 100644 index 4847fd96f..000000000 --- a/rest/src/plugins/restrictions/restrictionsRoutes.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ -const merkleUtils = require('../../routes/merkleUtils'); -const routeResultTypes = require('../../routes/routeResultTypes'); -const routeUtils = require('../../routes/routeUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -const { uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - const accountRestrictionsSender = routeUtils.createSender('accountRestrictions'); - - // SEARCH - server.get('/restrictions/account', (req, res, next) => { - const { params } = req; - const address = params.address ? routeUtils.parseArgument(params, 'address', 'address') : undefined; - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, { id: 'objectId' }); - return db.accountRestrictions(address, options) - .then(result => accountRestrictionsSender.sendPage(res, next)(result)); - }); - - // GET ONE/MANY - routeUtils.addGetPostDocumentRoutes( - server, - accountRestrictionsSender, - { base: '/restrictions/account', singular: 'address', plural: 'addresses' }, - params => db.accountRestrictionsByAddresses(params), - routeUtils.namedParserMap.address - ); - - // MERKLE - server.get('/restrictions/account/:address/merkle', (req, res, next) => { - const encodedAddress = routeUtils.parseArgument(req.params, 'address', 'address'); - const state = PacketType.accountRestrictionsStatePath; - return merkleUtils.requestTree(services, state, - encodedAddress).then(response => { - res.send(response); - next(); - }); - }); - - // SEARCH - const mosaicRestrictionSender = routeUtils.createSender(routeResultTypes.mosaicRestrictions); - server.get('/restrictions/mosaic', (req, res, next) => { - const { params } = req; - const mosaicId = params.mosaicId ? routeUtils.parseArgument(params, 'mosaicId', uint64.fromHex) : undefined; - const entryType = params.entryType ? routeUtils.parseArgument(params, 'entryType', 'uint') : undefined; - const targetAddress = params.targetAddress ? routeUtils.parseArgument(params, 'targetAddress', 'address') : undefined; - - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, { id: 'objectId' }); - - return db.mosaicRestrictions(mosaicId, entryType, targetAddress, options) - .then(result => mosaicRestrictionSender.sendPage(res, next)(result)); - }); - - // GET ONE MANY - routeUtils.addGetPostDocumentRoutes( - server, - mosaicRestrictionSender, - { base: '/restrictions/mosaic', singular: 'compositeHash', plural: 'compositeHashes' }, - params => db.mosaicRestrictionByCompositeHash(params), - routeUtils.namedParserMap.hash256 - ); - - // GET MERKLE - server.get('/restrictions/mosaic/:compositeHash/merkle', (req, res, next) => { - const compositeHash = routeUtils.parseArgument(req.params, 'compositeHash', 'hash256'); - const state = PacketType.mosaicRestrictionsStatePath; - return merkleUtils.requestTree(services, state, - compositeHash).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/plugins/routeSystem.js b/rest/src/plugins/routeSystem.js deleted file mode 100644 index fe27e42a3..000000000 --- a/rest/src/plugins/routeSystem.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const aggregate = require('./aggregate/aggregate'); -const empty = require('./empty'); -const lockHash = require('./lockHash/lockHash'); -const lockSecret = require('./lockSecret/lockSecret'); -const metadata = require('./metadata/metadata'); -const mosaic = require('./mosaic/mosaic'); -const multisig = require('./multisig/multisig'); -const namespace = require('./namespace/namespace'); -const receipts = require('./receipts/receipts'); -const restrictions = require('./restrictions/restrictions'); -const MessageChannelBuilder = require('../connection/MessageChannelBuilder'); -const catapult = require('catapult-sdk'); - -const plugins = { - accountLink: empty, - aggregate, - lockHash, - lockSecret, - metadata, - mosaic, - multisig, - namespace, - receipts, - restrictions, - transfer: empty -}; - -module.exports = { - /** - * Gets the names of all supported plugins. - * @returns {array} Names of all supported plugins. - */ - supportedPluginNames: () => Object.keys(plugins), - - /** - * Configures the server with the specified extensions. - * @param {array} pluginNames Additional extensions to use. - * @param {object} server Server. - * @param {module:db/CatapultDb} db Catapult database. - * @param {object} services Supporting services. - * @returns {array} Additional transaction states to register. - */ - configure: (pluginNames, server, db, services) => { - const transactionStates = []; - const networkIdentifier = catapult.model.networkInfo.networks[services.config.network.name].id; - const messageChannelBuilder = new MessageChannelBuilder(services.config.websocket, networkIdentifier); - (pluginNames || []).forEach(pluginName => { - if (!plugins[pluginName]) - throw Error(`plugin '${pluginName}' not supported by route system`); - - const plugin = plugins[pluginName]; - plugin.registerTransactionStates(transactionStates); - plugin.registerMessageChannels(messageChannelBuilder); - plugin.registerRoutes(server, plugin.createDb(db), services); - }); - - return { - transactionStates, - messageChannelDescriptors: messageChannelBuilder.build() - }; - } -}; diff --git a/rest/src/routes/MerkelTree.js b/rest/src/routes/MerkelTree.js deleted file mode 100644 index dc7b1f7c4..000000000 --- a/rest/src/routes/MerkelTree.js +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); - -const { convert } = catapult.utils; - -class MerkleTree { - /** - * Creates merkle tree. - */ - constructor() { - this.tree = []; - } - - /** - * Decompose a bitmask to get number of bit's indices - * @param {number} mask bitmask - * @returns {string[]} array of the indices of bits - */ - getBitsFromMask(mask) { - const intValue = parseInt(`0x${convert.uint8ToHex(mask.reverse())}`, 16); - let index = 0; - const bits = []; - for (let i = 1; i <= intValue; i *= 2) { - if (0 < (intValue & i)) { - // bit value: i.toString(16) - bits.push(index.toString(16).toUpperCase()); - } - index++; - } - return bits; - } - - /** - * Calculate path length from given nibbles count - * @param {number} nibbleCount Nibbles count - * @returns {number} the length of the path - */ - getPathLength(nibbleCount) { - // 1 nibble = 0.5 bytes. - // Round up to the whole bytes - return Math.ceil(parseFloat(nibbleCount) / 2); - } - - /** - * Is branch node - * @param {number} marker node marker - * @returns {boolean} if tree node is branch - */ - isBranch(marker) { - return 0 === marker; - } - - /** - * Is leaf node - * @param {number} marker node marker - * @returns {boolean} if tree node is leaf - */ - isLeaf(marker) { - return 255 === marker; - } - - /** - * Recursively parse raw tree - * @param {Uint8Array} raw raw tree buffer - * @returns {Array} merkle tree - */ - parseMerkleTreeFromRaw(raw) { - if (!raw.length) - return this.tree; - - const marker = raw[0]; - const nibbleCount = raw[1]; - const pathLength = this.getPathLength(nibbleCount); - const path = raw.slice(2, 2 + pathLength); - if (this.isBranch(marker)) { - const lessBranch = this.parseBranch(raw.slice(2 + pathLength), path, nibbleCount); - return this.parseMerkleTreeFromRaw(lessBranch); - } - if (this.isLeaf(marker)) { - const lessLeaf = this.parseLeaf(raw.slice(2 + pathLength), path, nibbleCount); - return this.parseMerkleTreeFromRaw(lessLeaf); - } - throw new Error(`${convert.uint8ToHex(raw)} is not a branch or a leaf!`); - } - - /** - * Parse branch tree node - * @param {Uint8Array} offsetRaw partial raw buffer - * @param {Uint8Array} path merkle tree path - * @param {number} nibbleCount number of nibbles - * @returns {Uint8Array} unprocess raw buffer - */ - parseBranch(offsetRaw, path, nibbleCount) { - const linkMask = offsetRaw.slice(0, 2); // little endian - const bits = this.getBitsFromMask(linkMask); - const linksRaw = offsetRaw.slice(2, 2 + (32 * bits.length)); - const links = []; - for (let i = 0; i < bits.length; i++) { - links.push({ - bit: bits[i], - link: convert.uint8ToHex(linksRaw.slice(i * 32, (i * 32) + 32)) - }); - } - const encodedPath = convert.uint8ToHex(this.encodePath(path, nibbleCount, false)); - this.tree.push({ - type: 0, - path: convert.uint8ToHex(path), - encodedPath, - nibbleCount, - linkMask: convert.uint8ToHex(linkMask), - links, - branchHash: this.getBranchHash(encodedPath, links) - }); - return offsetRaw.slice(2 + (32 * bits.length)); - } - - /** - * Parse leaf tree node - * @param {Uint8Array} offsetRaw partial raw buffer - * @param {Uint8Array} path merkle tree path - * @param {number} nibbleCount number of nibbles - * @returns {Uint8Array} unprocess raw buffer - */ - parseLeaf(offsetRaw, path, nibbleCount) { - const value = convert.uint8ToHex(offsetRaw.slice(0, 32)); - const encodedPath = convert.uint8ToHex(this.encodePath(path, nibbleCount, true)); - this.tree.push({ - type: 255, - path: convert.uint8ToHex(path), - encodedPath, - nibbleCount, - value, - leafHash: this.getLeafHash(encodedPath, value) - }); - return offsetRaw.slice(32); - } - - /** - * Encode path depends on node type and nibble count - * @param {Uint8Array} path path buffer - * @param {number} nibbleCount number of nibbles - * @param {boolean} isLeaf is leaf node - * @returns {Uint8Array} encoded path - */ - encodePath(path, nibbleCount, isLeaf) { - const encodedKey = new Uint8Array(Math.floor(nibbleCount / 2) + 1); - encodedKey[0] = isLeaf ? 0x20 : 0; // set leaf flag - let i = 0; - if (1 === nibbleCount % 2) { - // set odd flag and merge in first nibble - encodedKey[0] = encodedKey[0] | 0x10 | this.nibbleAt(path, 0); - ++i; - } - - for (; i < nibbleCount; i += 2) - encodedKey[Math.floor(i / 2) + 1] = (this.nibbleAt(path, i) << 4) + this.nibbleAt(path, i + 1); - - return encodedKey; - } - - /** - * Get byte at given nibble index - * @param {Uint8Array} path path buffer - * @param {number} index nibble index - * @returns {number} byte - */ - nibbleAt(path, index) { - const byte = path[Math.floor((index / 2))]; - return 0 === index % 2 ? (byte & 0xf0) >> 4 : byte & 0x0f; - } - - /** - * Calculate branch hash. Hash(encodedPath + 16 links) - * @param {string} encodedPath encoded path of the branch in hexadecimal format - * @param {Array} links branch links array - * @returns {string} branch hash (Hash(encodedPath + links)) - */ - getBranchHash(encodedPath, links) { - const branchLinks = Array(16).fill(catapult.utils.convert.uint8ToHex(new Uint8Array(32))); - links.forEach(link => { - branchLinks[parseInt(`0x${link.bit}`, 16)] = link.link; - }); - return catapult.crypto.sha3Hasher.getHasher(32).update( - catapult.utils.convert.hexToUint8(encodedPath + branchLinks.join('')) - ) - .hex() - .toUpperCase(); - } - - /** - * Calculate leaf hash. Hash(encodedPath + leaf value) - * @param {string} encodedPath encoded path of the leaf in hexadecimal format - * @param {Array} leafValue leaf value - * @returns {string} leaf hash (Hash(encodedPath + leaf value)) - */ - getLeafHash(encodedPath, leafValue) { - return catapult.crypto.sha3Hasher.getHasher(32).update( - catapult.utils.convert.hexToUint8(encodedPath + leafValue) - ) - .hex() - .toUpperCase(); - } -} - -module.exports = MerkleTree; diff --git a/rest/src/routes/accountRoutes.js b/rest/src/routes/accountRoutes.js deleted file mode 100644 index fe4024187..000000000 --- a/rest/src/routes/accountRoutes.js +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const merkleUtils = require('./merkleUtils'); -const routeResultTypes = require('./routeResultTypes'); -const routeUtils = require('./routeUtils'); -const AccountType = require('../plugins/AccountType'); -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -module.exports = { - register: (server, db, services) => { - const sender = routeUtils.createSender(routeResultTypes.account); - - server.get('/accounts', (req, res, next) => { - const address = req.params.address ? routeUtils.parseArgument(req.params, 'address', 'address') : undefined; - const mosaicId = req.params.mosaicId ? routeUtils.parseArgument(req.params, 'mosaicId', 'uint64hex') : undefined; - - const offsetParsers = { - id: 'objectId', - balance: 'uint64' - }; - const options = routeUtils.parsePaginationArguments(req.params, services.config.pageSize, offsetParsers); - - if ('balance' === options.sortField && !mosaicId) - throw errors.createInvalidArgumentError('mosaicId must be provided when sorting by balance'); - - return db.accounts(address, mosaicId, options) - .then(result => sender.sendPage(res, next)(result)); - }); - - server.get('/accounts/:accountId', (req, res, next) => { - const [type, accountId] = routeUtils.parseArgument(req.params, 'accountId', 'accountId'); - return db.accountsByIds([{ [type]: accountId }]) - .then(sender.sendOne(req.params.accountId, res, next)); - }); - - server.post('/accounts', (req, res, next) => { - if (req.params.publicKeys && req.params.addresses) - throw errors.createInvalidArgumentError('publicKeys and addresses cannot both be provided'); - - const idOptions = Array.isArray(req.params.publicKeys) - ? { keyName: 'publicKeys', parserName: 'publicKey', type: AccountType.publicKey } - : { keyName: 'addresses', parserName: 'address', type: AccountType.address }; - - const accountIds = routeUtils.parseArgumentAsArray(req.params, idOptions.keyName, idOptions.parserName); - - return db.accountsByIds(accountIds.map(accountId => ({ [idOptions.type]: accountId }))) - .then(sender.sendArray(idOptions.keyName, res, next)); - }); - - // this endpoint is here because it is expected to support requests by block other than - server.get('/accounts/:accountId/merkle', (req, res, next) => { - const [type, accountId] = routeUtils.parseArgument(req.params, 'accountId', 'accountId'); - const encodedAddress = 'publicKey' === type ? catapult.model.address.publicKeyToAddress(accountId, db.networkId) : accountId; - const state = PacketType.accountStatePath; - return merkleUtils.requestTree(services, state, - encodedAddress).then(response => { - res.send(response); - next(); - }); - }); - } -}; diff --git a/rest/src/routes/allRoutes.js b/rest/src/routes/allRoutes.js deleted file mode 100644 index 5151d7917..000000000 --- a/rest/src/routes/allRoutes.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const accountRoutes = require('./accountRoutes'); -const blockRoutes = require('./blockRoutes'); -const chainRoutes = require('./chainRoutes'); -const finalizationRoutes = require('./finalizationRoutes'); -const networkRoutes = require('./networkRoutes'); -const nodeRoutes = require('./nodeRoutes'); -const transactionRoutes = require('./transactionRoutes'); -const transactionStatusRoutes = require('./transactionStatusRoutes'); -const wsRoutes = require('./wsRoutes'); - -module.exports = { - register: (...args) => { - const allRoutes = [ - accountRoutes, - blockRoutes, - chainRoutes, - finalizationRoutes, - networkRoutes, - nodeRoutes, - transactionRoutes, - transactionStatusRoutes, - wsRoutes]; - allRoutes.forEach(routes => { - routes.register(...args); - }); - } -}; diff --git a/rest/src/routes/blockRoutes.js b/rest/src/routes/blockRoutes.js deleted file mode 100644 index b871b692f..000000000 --- a/rest/src/routes/blockRoutes.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const dbFacade = require('./dbFacade'); -const routeResultTypes = require('./routeResultTypes'); -const routeUtils = require('./routeUtils'); -const catapult = require('catapult-sdk'); - -const { uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - server.get('/blocks', (req, res, next) => { - const { params } = req; - - const signerPublicKey = params.signerPublicKey ? routeUtils.parseArgument(params, 'signerPublicKey', 'publicKey') : undefined; - const beneficiaryAddress = params.beneficiaryAddress - ? routeUtils.parseArgument(params, 'beneficiaryAddress', 'address') - : undefined; - - const offsetParsers = { - id: 'objectId', - height: 'uint64' - }; - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, offsetParsers); - - return db.blocks(signerPublicKey, beneficiaryAddress, options) - .then(result => routeUtils.createSender(routeResultTypes.block).sendPage(res, next)(result)); - }); - - server.get('/blocks/:height', (req, res, next) => { - const height = routeUtils.parseArgument(req.params, 'height', 'uint64'); - - return dbFacade.runHeightDependentOperation(db, height, () => db.blockAtHeight(height)) - .then(result => result.payload) - .then(routeUtils.createSender(routeResultTypes.block).sendOne(uint64.toString(height), res, next)); - }); - - server.get( - '/blocks/:height/transactions/:hash/merkle', - routeUtils.blockRouteMerkleProcessor(db, 'transactionsCount', 'transactionMerkleTree') - ); - } -}; diff --git a/rest/src/routes/chainRoutes.js b/rest/src/routes/chainRoutes.js deleted file mode 100644 index 90d4d18bf..000000000 --- a/rest/src/routes/chainRoutes.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeResultTypes = require('./routeResultTypes'); - -module.exports = { - register: (server, db) => { - server.get('/chain/info', (req, res, next) => - Promise.all([ - db.chainStatisticCurrent(), - db.latestFinalizedBlock() - ]).then(dbResults => { - const chainInfoResult = dbResults[0]; - chainInfoResult.latestFinalizedBlock = dbResults[1].block; - res.send({ - payload: chainInfoResult, - type: routeResultTypes.chainInfo - }); - next(); - })); - } -}; diff --git a/rest/src/routes/dbFacade.js b/rest/src/routes/dbFacade.js deleted file mode 100644 index 57277ff1d..000000000 --- a/rest/src/routes/dbFacade.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong } = require('../db/dbUtils'); - -const extractFromMetadata = (group, transaction) => ({ - group, - code: 0, - hash: transaction.meta.hash, - deadline: transaction.transaction.deadline, - height: transaction.meta.height -}); - -const dbFacade = { - - /** - * Runs a database operation that is dependent on current chain height. - * @param {module:db/CatapultDb} db Catapult database. - * @param {numeric} height Request height. - * @param {function} operation Height-dependent operation that returns a promise. - * @returns {object} Operation result if the request height is no greater than the chain height, undefined otherwise. - */ - runHeightDependentOperation: (db, height, operation) => { - // notice that both the chain height and height-dependent operation are started at the same time in order to - // optimize the common case when the request height is valid - const chainStatisticPromise = db.chainStatisticCurrent(); - const operationPromise = operation(); - - return Promise.all([chainStatisticPromise, operationPromise]).then(results => { - const chainStatistic = results[0]; - const isRequestValid = convertToLong(height).lessThanOrEqual(chainStatistic.height); - return { - isRequestValid, - payload: isRequestValid ? results[1] : undefined - }; - }); - }, - - /** - * Retrieves transaction statuses by specified hashes. - * @param {module:db/CatapultDb} db Catapult database. - * @param {array} hashes Hashes of transactions to query. - * @param {array} additionalTransactionStates Additional transaction states. - * @returns {Promise.} Array of failed, unconfirmed and confirmed transactions. - */ - transactionStatusesByHashes: (db, hashes, additionalTransactionStates) => { - const transactionStates = [].concat( - // order matters and it determines the priority at which the status will be returned - // * this was agreed by the team, since a transaction with the same hash (same transaction), can be announced multiple times - // * and be present in different status collections at the same time also not sure if the same hash can be "failed" multiple - // * times for different reasons (codes) in the database - [{ dbPostfix: '', friendlyName: 'confirmed' }], - [{ dbPostfix: 'Unconfirmed', friendlyName: 'unconfirmed' }], - additionalTransactionStates - ); - - const promises = []; - transactionStates.forEach(state => { - const dbPromise = db.transactionsByHashes(state.friendlyName, hashes); - promises.push(dbPromise.then(objs => objs.map(transaction => extractFromMetadata(state.friendlyName, transaction)))); - }); - promises.push(db.transactionsByHashesFailed(hashes) - .then(objs => objs.map(status => status.status)) // removes wrapping property - .then(objs => objs.map(status => Object.assign(status, { group: 'failed' })))); - - return Promise.all(promises).then(tuple => { - const resultingStatuses = []; - tuple.forEach(statusArray => statusArray.forEach(statusResult => { - if (!resultingStatuses.some(status => 0 === status.hash.buffer.compare(statusResult.hash.buffer))) - resultingStatuses.push(statusResult); - })); - return resultingStatuses; - }); - } -}; - -module.exports = dbFacade; diff --git a/rest/src/routes/finalizationRoutes.js b/rest/src/routes/finalizationRoutes.js deleted file mode 100644 index a69af0643..000000000 --- a/rest/src/routes/finalizationRoutes.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeResultTypes = require('./routeResultTypes'); -const routeUtils = require('./routeUtils'); -const finalizationProofCodec = require('../sockets/finalizationProofCodec'); -const catapult = require('catapult-sdk'); -const { NotFoundError } = require('restify-errors'); - -const packetHeader = catapult.packet.header; -const { PacketType } = catapult.packet; -const { BinaryParser } = catapult.parser; -const { uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - const { connections } = services; - const { timeout } = services.config.apiNode; - - const sendRequestAndResponse = (requestPacket, res, next) => - connections.singleUse() - .then(connection => connection.pushPull(requestPacket, timeout)) - .then(packet => { - const binaryParser = new BinaryParser(); - binaryParser.push(packet.payload); - const payload = finalizationProofCodec.deserialize(binaryParser); - if (!payload) - return next(new NotFoundError()); - res.send({ payload, type: routeResultTypes.finalizationProof, formatter: 'ws' }); - return next(); - }); - - server.get('/finalization/proof/epoch/:epoch', (req, res, next) => { - const epoch = routeUtils.parseArgument(req.params, 'epoch', 'uint'); - - const uint32Size = 4; - const headerBuffer = packetHeader.createBuffer(PacketType.finalizationProofAtEpoch, packetHeader.size + uint32Size); - const epochBuffer = Buffer.alloc(uint32Size); - epochBuffer.writeUInt32LE(epoch); - const packetBuffer = Buffer.concat([headerBuffer, epochBuffer]); - - return sendRequestAndResponse(packetBuffer, res, next); - }); - - server.get('/finalization/proof/height/:height', (req, res, next) => { - const height = routeUtils.parseArgument(req.params, 'height', 'uint64'); - - const uint64Size = 8; - const headerBuffer = packetHeader.createBuffer(PacketType.finalizationProofAtHeight, packetHeader.size + uint64Size); - const heightBuffer = Buffer.from(uint64.toBytes(height)); - const packetBuffer = Buffer.concat([headerBuffer, heightBuffer]); - - return sendRequestAndResponse(packetBuffer, res, next); - }); - } -}; diff --git a/rest/src/routes/merkleUtils.js b/rest/src/routes/merkleUtils.js deleted file mode 100644 index 6b2cb163d..000000000 --- a/rest/src/routes/merkleUtils.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ -/* eslint-disable */ -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); -const MerkleTree = require('./MerkelTree'); - -const packetHeader = catapult.packet.header; -const { StatePathPacketTypes } = catapult.packet; -const { convert } = catapult.utils; - -const merkleUtils = { - /** - * It sends a merkle tree request to api server for the give state path and key. - * - * @param {service} services the service object used to call catapult api - * @param {PacketType} state the state path packet type from {StatePathPacketTypes} - * @param {Uint8Array} key the state identifier as byte array. - * @returns {Promise<{formatter: string, payload: *, type: *}>} the response payload ready to be sent as the http response. - */ - requestTree: (services, state, key) => { - if (!StatePathPacketTypes.includes(state)) - throw errors.createInvalidArgumentError('invalid `state` provided'); - - const buildResponse = packet => - { - const raw = convert.uint8ToHex(packet.payload); - return { raw, tree: new MerkleTree().parseMerkleTreeFromRaw(packet.payload)} - }; - const { connections } = services; - const { timeout } = services.config.apiNode; - const headerBuffer = packetHeader.createBuffer( - state, - packetHeader.size + key.length - ); - const heightBuffer = Buffer.from(key); - const packetBuffer = Buffer.concat([headerBuffer, heightBuffer]); - return connections - .singleUse() - .then(connection => connection.pushPull(packetBuffer, timeout)) - .then(packet => buildResponse(packet)); - }, -}; - -module.exports = merkleUtils; diff --git a/rest/src/routes/networkRoutes.js b/rest/src/routes/networkRoutes.js deleted file mode 100644 index 688a6be1c..000000000 --- a/rest/src/routes/networkRoutes.js +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); -const ini = require('ini'); -const fs = require('fs'); -const util = require('util'); - -const { uint64 } = catapult.utils; - -module.exports = { - register: (server, db, services) => { - const average = array => array.reduce((p, c) => p + c, 0) / array.length; - const median = array => { - array.sort((a, b) => a - b); - const mid = array.length / 2; - return mid % 1 ? array[mid - 0.5] : (array[mid - 1] + array[mid]) / 2; - }; - - const readAndParseNetworkPropertiesFile = () => { - const readFile = util.promisify(fs.readFile); - return readFile(services.config.apiNode.networkPropertyFilePath, 'utf8') - .then(fileData => ini.parse(fileData)); - }; - - const readAndParseNodePropertiesFile = () => { - const readFile = util.promisify(fs.readFile); - return readFile(services.config.apiNode.nodePropertyFilePath, 'utf8') - .then(fileData => ini.parse(fileData)); - }; - - const sanitizeInput = value => value.replace(/[^0-9]/g, ''); - - server.get('/network', (req, res, next) => { - res.send({ name: services.config.network.name, description: services.config.network.description }); - next(); - }); - - server.get('/network/properties', (req, res, next) => readAndParseNetworkPropertiesFile() - .then(propertiesObject => { - res.send({ - network: propertiesObject.network, - chain: propertiesObject.chain, - plugins: propertiesObject['plugin:catapult'].plugins - }); - next(); - }).catch(() => { - res.send(errors.createInvalidArgumentError('there was an error reading the network properties file')); - next(); - })); - - server.get('/network/fees/transaction', (req, res, next) => { - const numBlocksTransactionFeeStats = services.config.numBlocksTransactionFeeStats || 1; - const latestBlocksFeeMultiplier = db.latestBlocksFeeMultiplier(numBlocksTransactionFeeStats); - return Promise.all([readAndParseNodePropertiesFile(), latestBlocksFeeMultiplier, - readAndParseNetworkPropertiesFile()]).then(feeMultipliers => { - // defaultDynamicFeeMultiplier -> uint32 - const defaultDynamicFeeMultiplier = parseInt(sanitizeInput( - feeMultipliers[2].chain.defaultDynamicFeeMultiplier - ), 10); - const defaultedFeeMultipliers = feeMultipliers[1].map(f => (0 === f ? defaultDynamicFeeMultiplier : f)); - res.send({ - averageFeeMultiplier: Math.floor(average(defaultedFeeMultipliers)), - medianFeeMultiplier: Math.floor(median(defaultedFeeMultipliers)), - highestFeeMultiplier: Math.max(...feeMultipliers[1]), - lowestFeeMultiplier: Math.min(...feeMultipliers[1]), - minFeeMultiplier: Number(feeMultipliers[0].node.minFeeMultiplier.replace('\'', '')) - }); - next(); - }); - }); - - server.get('/network/fees/rental', (req, res, next) => readAndParseNetworkPropertiesFile().then(propertiesObject => { - const maxDifficultyBlocks = parseInt(sanitizeInput( - propertiesObject.chain.maxDifficultyBlocks - ), 10); - - // defaultDynamicFeeMultiplier -> uint32 - const defaultDynamicFeeMultiplier = parseInt(sanitizeInput( - propertiesObject.chain.defaultDynamicFeeMultiplier - ), 10); - - // rootNamespaceRentalFeePerBlock -> uint64 - const rootNamespaceRentalFeePerBlock = uint64.fromString(sanitizeInput( - propertiesObject['plugin:catapult'].plugins.namespace.rootNamespaceRentalFeePerBlock - )); - - // childNamespaceRentalFee -> uint64 - const childNamespaceRentalFee = uint64.fromString(sanitizeInput( - propertiesObject['plugin:catapult'].plugins.namespace.childNamespaceRentalFee - )); - - // mosaicRentalFee -> uint64 - const mosaicRentalFee = uint64.fromString(sanitizeInput( - propertiesObject['plugin:catapult'].plugins.mosaic.mosaicRentalFee - )); - - return db.latestBlocksFeeMultiplier(maxDifficultyBlocks || 1).then(feeMultipliers => { - const defaultedFeeMultipliers = feeMultipliers.map(f => (0 === f ? defaultDynamicFeeMultiplier : f)); - const medianNetworkMultiplier = Math.floor(median(defaultedFeeMultipliers)); - const uint64MedianNetworkMultiplier = uint64.fromUint(medianNetworkMultiplier); - - res.send({ - effectiveRootNamespaceRentalFeePerBlock: - uint64.toString(uint64.multiply(rootNamespaceRentalFeePerBlock, uint64MedianNetworkMultiplier)), - effectiveChildNamespaceRentalFee: - uint64.toString(uint64.multiply(childNamespaceRentalFee, uint64MedianNetworkMultiplier)), - effectiveMosaicRentalFee: - uint64.toString(uint64.multiply(mosaicRentalFee, uint64MedianNetworkMultiplier)) - }); - next(); - }); - }).catch(() => { - res.send(errors.createInvalidArgumentError('there was an error reading the network properties file')); - next(); - })); - } -}; diff --git a/rest/src/routes/nodeRoutes.js b/rest/src/routes/nodeRoutes.js deleted file mode 100644 index 27c821e6a..000000000 --- a/rest/src/routes/nodeRoutes.js +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeResultTypes = require('./routeResultTypes'); -const nodeInfoCodec = require('../sockets/nodeInfoCodec'); -const nodePeersCodec = require('../sockets/nodePeersCodec'); -const nodeTimeCodec = require('../sockets/nodeTimeCodec'); -const catapult = require('catapult-sdk'); -const fs = require('fs'); -const path = require('path'); - -const packetHeader = catapult.packet.header; -const { PacketType } = catapult.packet; -const { BinaryParser } = catapult.parser; - -// ATM, both rest and rest sdk share the same version. In the future, -// we will have an open api and sdk dependencies with their given versions. -const restVersion = fs - .readFileSync(path.resolve(__dirname, '../../../version.txt'), 'UTF-8') - .trim(); -const sdkVersion = restVersion; - -const buildResponse = (packet, codec, resultType) => { - const binaryParser = new BinaryParser(); - binaryParser.push(packet.payload); - return { - payload: codec.deserialize(binaryParser), - type: resultType, - formatter: 'ws' - }; -}; - -module.exports = { - register: (server, db, services) => { - const { connections } = services; - const { timeout } = services.config.apiNode; - - server.get('/node/health', (req, res, next) => { - const parseNodeInfoPacket = packet => { - const binaryParser = new BinaryParser(); - binaryParser.push(packet.payload); - return nodeInfoCodec.deserialize(binaryParser); - }; - - const ServiceStatus = Object.freeze({ - up: 'up', - down: 'down' - }); - - // Check database status - const dbStatusPromise = new Promise((resolve, reject) => - (db.database.serverConfig.isConnected() ? resolve() : reject())); - - // Check apiNode status - const packetBuffer = packetHeader.createBuffer( - PacketType.nodeDiscoveryPullPing, - packetHeader.size - ); - const apiNodeStatusPromise = services.connections - .singleUse() - .then(connection => - connection.pushPull(packetBuffer, services.config.apiNode.timeout)) - .then(packet => parseNodeInfoPacket(packet)); - - return Promise.allSettled([dbStatusPromise, apiNodeStatusPromise]).then( - results => { - const statusCode = results.some( - result => 'fulfilled' !== result.status - ) - ? 503 - : 200; - const checkResult = result => - ('fulfilled' === result.status - ? ServiceStatus.up - : ServiceStatus.down); - - res.status(statusCode); - res.send({ - payload: { - status: { - apiNode: checkResult(results[1]), - db: checkResult(results[0]) - } - }, - type: routeResultTypes.nodeHealth - }); - next(); - } - ); - }); - - server.get('/node/info', (req, res, next) => { - const packetBuffer = packetHeader.createBuffer( - PacketType.nodeDiscoveryPullPing, - packetHeader.size - ); - return connections - .singleUse() - .then(connection => connection.pushPull(packetBuffer, timeout)) - .then(packet => { - const response = buildResponse(packet, nodeInfoCodec, routeResultTypes.nodeInfo); - response.payload.nodePublicKey = services.config.apiNode.nodePublicKey; - res.send( - response - ); - next(); - }); - }); - - server.get('/node/peers', (req, res, next) => { - const packetBuffer = packetHeader.createBuffer( - PacketType.nodeDiscoveryPullPeers, - packetHeader.size - ); - return connections - .singleUse() - .then(connection => connection.pushPull(packetBuffer, timeout)) - .then(packet => { - res.send( - buildResponse(packet, nodePeersCodec, routeResultTypes.nodeInfo) - ); - next(); - }); - }); - - server.get('/node/server', (req, res, next) => { - const { deployment } = services.config; - res.send({ - payload: { - serverInfo: { - restVersion, - sdkVersion, - deployment: { - deploymentTool: deployment && deployment.deploymentTool ? deployment.deploymentTool : 'N/A', - deploymentToolVersion: deployment && deployment.deploymentToolVersion - ? deployment.deploymentToolVersion : 'N/A', - lastUpdatedDate: deployment && deployment.lastUpdatedDate ? deployment.lastUpdatedDate : 'N/A' - } - } - }, - type: routeResultTypes.serverInfo - }); - return next(); - }); - - server.get('/node/storage', (req, res, next) => - db.storageInfo().then(storageInfo => { - res.send({ payload: storageInfo, type: routeResultTypes.storageInfo }); - next(); - })); - - server.get('/node/time', (req, res, next) => { - const packetBuffer = packetHeader.createBuffer( - PacketType.timeSyncNodeTime, - packetHeader.size - ); - return connections - .singleUse() - .then(connection => connection.pushPull(packetBuffer, timeout)) - .then(packet => { - res.send( - buildResponse(packet, nodeTimeCodec, routeResultTypes.nodeTime) - ); - next(); - }); - }); - - server.get('/node/unlockedaccount', (req, res, next) => { - const { convert } = catapult.utils; - const headerBuffer = packetHeader.createBuffer( - PacketType.unlockedAccount, - packetHeader.size - ); - const packetBuffer = headerBuffer; - return connections - .singleUse() - .then(connection => connection.pushPull(packetBuffer, timeout)) - .then(packet => { - const unlockedKeys = convert - .uint8ToHex(packet.payload) - .match(/.{1,64}/g); - res.send({ unlockedAccount: !unlockedKeys ? [] : unlockedKeys }); - next(); - }); - }); - } -}; diff --git a/rest/src/routes/routeResultTypes.js b/rest/src/routes/routeResultTypes.js deleted file mode 100644 index fef02344f..000000000 --- a/rest/src/routes/routeResultTypes.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -module.exports = { - // with meta data - account: 'accountWithMetadata', - block: 'blockHeaderWithMetadata', - transaction: 'transactionWithMetadata', - - // other - chainInfo: 'chainInfo', - merkleProofInfo: 'merkleProofInfo', - finalizationProof: 'finalizationProof', - metadata: 'metadata', - stateTree: 'stateTree', - addressResolutionStatement: 'addressResolutionStatement', - mosaicResolutionStatement: 'mosaicResolutionStatement', - transactionStatement: 'transactionStatement', - transactionStatus: 'transactionStatus', - nodeInfo: 'nodeInfo', - nodeTime: 'nodeTime', - nodeHealth: 'nodeHealth', - mosaicRestrictions: 'mosaicRestrictions', - - // diagnostic - serverInfo: 'serverInfo', - storageInfo: 'storageInfo' -}; diff --git a/rest/src/routes/routeUtils.js b/rest/src/routes/routeUtils.js deleted file mode 100644 index dd454d751..000000000 --- a/rest/src/routes/routeUtils.js +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const dbFacade = require('./dbFacade'); -const routeResultTypes = require('./routeResultTypes'); -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); - -const { address } = catapult.model; -const { buildAuditPath, indexOfLeafWithHash } = catapult.crypto.merkle; -const { convert, uint64 } = catapult.utils; -const packetHeader = catapult.packet.header; -const constants = { - sizes: { - hexPublicKey: 64, - addressEncoded: 39, - addressDecoded: 24, - hash256: 32, - hash512: 64 - } -}; - -const isObjectId = str => 24 === str.length && convert.isHexString(str); - -const namedParserMap = { - objectId: str => { - if (!isObjectId(str)) - throw Error('must be 12-byte hex string'); - - return str; - }, - uint: str => { - const result = convert.tryParseUint(str); - if (undefined === result) - throw Error('must be non-negative number'); - - return result; - }, - uint64: str => uint64.fromString(str), - uint64hex: str => uint64.fromHex(str), - address: str => { - if (constants.sizes.addressEncoded === str.length) - return address.stringToAddress(str); - // if (constants.sizes.addressDecoded * 2 === str.length) - // return convert.hexToUint8(str); - throw Error(`invalid length of address '${str.length}'`); - }, - publicKey: str => { - if (constants.sizes.hexPublicKey === str.length) - return convert.hexToUint8(str); - - throw Error(`invalid length of publicKey '${str.length}'`); - }, - accountId: str => { - if (constants.sizes.hexPublicKey === str.length) - return ['publicKey', convert.hexToUint8(str)]; - if (constants.sizes.addressEncoded === str.length) - return ['address', address.stringToAddress(str)]; - // if (constants.sizes.addressDecoded * 2 === str.length) - // return ['address', convert.hexToUint8(str)]; - - throw Error(`invalid length of account id '${str.length}'`); - }, - hash256: str => { - if (2 * constants.sizes.hash256 === str.length) - return convert.hexToUint8(str); - - throw Error(`invalid length of hash256 '${str.length}'`); - }, - hash512: str => { - if (2 * constants.sizes.hash512 === str.length) - return convert.hexToUint8(str); - - throw Error(`invalid length of hash512 '${str.length}'`); - }, - boolean: str => { - if (('true' !== str) && ('false' !== str)) - throw Error('must be boolean value \'true\' or \'false\''); - - return 'true' === str; - } -}; - -const getBoundedPageSize = (pageSize, optionsPageSize) => - Math.max(optionsPageSize.min, Math.min(optionsPageSize.max, pageSize || optionsPageSize.default)); - -const isPage = page => undefined !== page.data && undefined !== page.pagination.pageNumber && undefined !== page.pagination.pageSize; - -const routeUtils = { - - /** - * Named parsers if it needs to be called directly. - */ - namedParserMap, - /** - * Parses an argument and throws an invalid argument error if it is invalid. - * @param {object} args Container containing the argument to parse. - * @param {string} key Name of the argument to parse. - * @param {Function|string} parser Parser to use or the name of a named parser. - * @returns {object} Parsed value. - */ - parseArgument: (args, key, parser) => { - try { - return ('string' === typeof parser ? namedParserMap[parser] : parser)(args[key]); - } catch (err) { - throw errors.createInvalidArgumentError(`${key} has an invalid format`, err); - } - }, - - /** - * Parses an argument as an array and throws an invalid argument error if any element is invalid. - * @param {object} args Container containing the argument to parse. - * @param {string} key Name of the argument to parse. - * @param {Function|string} parser Parser to use or the name of a named parser. - * @returns {object} Array with parsed values. - */ - parseArgumentAsArray: (args, key, parser) => { - const realParser = 'string' === typeof parser ? namedParserMap[parser] : parser; - let providedArgs = args[key]; - if (!Array.isArray(providedArgs)) - providedArgs = [providedArgs]; - - try { - return providedArgs.map(realParser); - } catch (err) { - throw errors.createInvalidArgumentError(`element in array ${key} has an invalid format`, err); - } - }, - - /** - * Parses pagination arguments and throws an invalid argument error if any is invalid. - * @param {object} args Arguments to parse. - * @param {object} optionsPageSize Page size options. - * @param {object} offsetParsers Sort fields with the related offset parser this endpoint allows, will match provided `sortField` and - * throw if invalid. Must have at least one entry, and `id` is treated as default if no `sortField` is provided. - * @returns {object} Parsed pagination options. - */ - parsePaginationArguments: (args, optionsPageSize, offsetParsers) => { - const allowedSortFields = Object.keys(offsetParsers); - if (args.orderBy && !allowedSortFields.includes(args.orderBy)) - throw errors.createInvalidArgumentError(`sorting by ${args.orderBy} is not allowed`); - - const parsedArgs = { - sortField: allowedSortFields.includes(args.orderBy) ? args.orderBy : 'id', - sortDirection: 'desc' === args.order ? -1 : 1 - }; - - if (args.pageSize) { - const numericPageSize = convert.tryParseUint(args.pageSize); - if (undefined === numericPageSize) - throw errors.createInvalidArgumentError('pageSize is not a valid unsigned integer'); - - parsedArgs.pageSize = getBoundedPageSize(numericPageSize, optionsPageSize); - } else { - parsedArgs.pageSize = optionsPageSize.default; - } - - if (args.pageNumber) { - const numericPageNumber = convert.tryParseUint(args.pageNumber); - if (undefined === numericPageNumber) - throw errors.createInvalidArgumentError('pageNumber is not a valid unsigned integer'); - - parsedArgs.pageNumber = numericPageNumber; - } - parsedArgs.pageNumber = 0 < parsedArgs.pageNumber ? parsedArgs.pageNumber : 1; - - if (args.offset) { - parsedArgs.offset = routeUtils.parseArgument(args, 'offset', offsetParsers[parsedArgs.sortField]); - parsedArgs.offsetType = offsetParsers[parsedArgs.sortField]; - } - - return parsedArgs; - }, - - /** - * Creates a sender for forwarding one or more objects of a given type. - * @param {module:routes/routeResultTypes} type Object type. - * @returns {object} Sender. - */ - createSender: type => ({ - /** - * Creates an array handler that forwards an array. - * @param {object} id Array identifier. - * @param {object} res Restify response object. - * @param {Function} next Restify next callback handler. - * @returns {Function} An appropriate array handler. - */ - sendArray(id, res, next) { - return array => { - if (!Array.isArray(array)) - res.send(errors.createInternalError(`error retrieving data for id: '${id}'`)); - else - res.send({ payload: array, type }); - - next(); - }; - }, - - /** - * Creates an object handler that either forwards an object corresponding to an identifier - * or sends a not found error if no such object exists. - * @param {object} id Object identifier. - * @param {object} res Restify response object. - * @param {Function} next Restify next callback handler. - * @returns {Function} An appropriate object handler. - */ - sendOne(id, res, next) { - const sendOneObject = object => { - if (!object) - res.send(errors.createNotFoundError(id)); - else - res.send({ payload: object, type }); - }; - - return object => { - if (Array.isArray(object)) { - if (2 <= object.length) - res.send(errors.createInternalError(`error retrieving data for id: '${id}' (length ${object.length})`)); - else - sendOneObject(object.length && object[0]); - } else { - sendOneObject(object); - } - - next(); - }; - }, - - /** - * Creates a page handler that forwards a paginated result. - * @param {object} res Restify response object. - * @param {Function} next Restify next callback handler. - * @returns {Function} An appropriate object handler. - */ - sendPage(res, next) { - return page => { - if (!isPage(page)) - res.send(errors.createInternalError('error retrieving data')); - else - res.send({ payload: page, type, structure: 'page' }); - next(); - }; - }, - - /** - * Creates a text handler that forwards a plain text result. - * @param {object} res Restify response object. - * @param {Function} next Restify next callback handler. - * @returns {Function} An appropriate object handler. - */ - sendPlainText(res, next) { - return data => { - if (!data) - res.send(errors.createInternalError('error retrieving plain text')); - else - res.setHeader('content-type', 'text/plain'); - res.send(data); - next(); - }; - } - }), - - /** - * Adds GET and POST routes for looking up documents of a single type. - * @param {object} server Server on which to register the routes. - * @param {object} sender Sender to use for sending the results. - * @param {object} routeInfo Information about the routes. - * @param {Function} documentRetriever Lookup function for retrieving the documents. - * @param {Function|string} parser Parser to use or the name of a named parser. - */ - addGetPostDocumentRoutes: (server, sender, routeInfo, documentRetriever, parser) => { - const routes = { - get: `${routeInfo.base}/:${routeInfo.singular}`, - post: `${routeInfo.base}` - }; - if (routeInfo.postfixes) { - routes.get += `/${routeInfo.postfixes.singular}`; - routes.post += `/${routeInfo.postfixes.plural}`; - } - - server.get(routes.get, (req, res, next) => { - const key = routeUtils.parseArgument(req.params, routeInfo.singular, parser); - return documentRetriever([key]).then(sender.sendOne(req.params[routeInfo.singular], res, next)); - }); - - server.post(routes.post, (req, res, next) => { - const keys = routeUtils.parseArgumentAsArray(req.params, routeInfo.plural, parser); - return documentRetriever(keys).then(sender.sendArray(req.params[routeInfo.plural], res, next)); - }); - }, - - /** - * Adds PUT route for sending a packet to an api server. - * @param {object} server Server on which to register the routes. - * @param {object} connections Api server connection pool. - * @param {object} routeInfo Information about the route. - * @param {Function} parser Parser to use to parse the route parameters into a packet payload. - */ - addPutPacketRoute: (server, connections, routeInfo, parser) => { - const createPacketFromBuffer = (data, packetType) => { - const length = packetHeader.size + data.length; - const header = packetHeader.createBuffer(packetType, length); - const buffers = [header, Buffer.from(data)]; - return Buffer.concat(buffers, length); - }; - - server.put(routeInfo.routeName, (req, res, next) => { - const packetBuffer = createPacketFromBuffer(parser(req.params), routeInfo.packetType); - return connections.lease() - .then(connection => connection.send(packetBuffer)) - .then(() => { - res.send(202, { message: `packet ${routeInfo.packetType} was pushed to the network via ${routeInfo.routeName}` }); - next(); - }); - }); - }, - - /** - * Returns function for processing merkle tree path requests. - * @param {module:db/CatapultDb} db Catapult database. - * @param {string} blockMetaCountField Field name for block meta count. - * @param {string} blockMetaTreeField Field name for block meta merkle tree. - * @returns {Function} Restify response function to process merkle path requests. - */ - blockRouteMerkleProcessor: (db, blockMetaCountField, blockMetaTreeField) => (req, res, next) => { - const height = routeUtils.parseArgument(req.params, 'height', 'uint64'); - const hash = routeUtils.parseArgument(req.params, 'hash', 'hash256'); - - return dbFacade.runHeightDependentOperation(db, height, () => db.blockWithMerkleTreeAtHeight(height, blockMetaTreeField)) - .then(result => { - if (!result.isRequestValid) { - res.send(errors.createNotFoundError(uint64.toString(height))); - return next(); - } - - const block = result.payload; - if (!block.meta[blockMetaCountField]) { - res.send(errors.createInvalidArgumentError( - `hash '${req.params.hash}' not included in block height '${uint64.toString(height)}'` - )); - return next(); - } - - const merkleTree = { - count: block.meta[blockMetaCountField], - nodes: block.meta[blockMetaTreeField].map(merkleHash => merkleHash.buffer) - }; - - if (0 > indexOfLeafWithHash(hash, merkleTree)) { - res.send(errors.createInvalidArgumentError( - `hash '${req.params.hash}' not included in block height '${uint64.toString(height)}'` - )); - return next(); - } - - const merklePath = buildAuditPath(hash, merkleTree); - - res.send({ - payload: { merklePath }, - type: routeResultTypes.merkleProofInfo - }); - - return next(); - }); - }, - - /** - * Returns account public key from account address . - * @param {module:db/CatapultDb} db Catapult database. - * @param {Uint8Array} accountAddress Account address. - * @returns {Promise} Account public key. - */ - addressToPublicKey: (db, accountAddress) => db.addressToPublicKey(accountAddress) - .then(result => { - if (!result) - return Promise.reject(Error('account not found')); - - return result.account.publicKey.buffer; - }) -}; - -module.exports = routeUtils; diff --git a/rest/src/routes/transactionRoutes.js b/rest/src/routes/transactionRoutes.js deleted file mode 100644 index b2951bca7..000000000 --- a/rest/src/routes/transactionRoutes.js +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeResultTypes = require('./routeResultTypes'); -const routeUtils = require('./routeUtils'); -const errors = require('../server/errors'); -const catapult = require('catapult-sdk'); -const { NotFoundError, InvalidArgumentError } = require('restify-errors'); - -const { convert } = catapult.utils; -const { PacketType } = catapult.packet; - -const constants = { - sizes: { - hash: 64, - objectId: 24 - } -}; - -const isValidTransactionGroup = group => ['confirmed', 'unconfirmed', 'partial'].includes(group); - -module.exports = { - register: (server, db, services) => { - const sender = routeUtils.createSender(routeResultTypes.transaction); - - routeUtils.addPutPacketRoute( - server, - services.connections, - { routeName: '/transactions', packetType: PacketType.pushTransactions }, - params => routeUtils.parseArgument(params, 'payload', convert.hexToUint8) - ); - - server.get('/transactions/:group', (req, res, next) => { - const { params } = req; - - if (!isValidTransactionGroup(params.group)) - return next(new NotFoundError()); - - if (params.address && (params.signerPublicKey || params.recipientAddress)) { - return next(new InvalidArgumentError( - 'can\'t filter by address if signerPublicKey or recipientAddress are already provided' - )); - } - - if ((params.fromTransferAmount || params.toTransferAmount) && !params.transferMosaicId) - return next(new InvalidArgumentError('can\'t filter by transfer amount if `transferMosaicId` is not provided')); - - const filters = { - height: params.height ? routeUtils.parseArgument(params, 'height', 'uint64') : undefined, - fromHeight: params.fromHeight ? routeUtils.parseArgument(params, 'fromHeight', 'uint64') : undefined, - toHeight: params.toHeight ? routeUtils.parseArgument(params, 'toHeight', 'uint64') : undefined, - address: params.address ? routeUtils.parseArgument(params, 'address', 'address') : undefined, - signerPublicKey: params.signerPublicKey ? routeUtils.parseArgument(params, 'signerPublicKey', 'publicKey') : undefined, - recipientAddress: params.recipientAddress ? routeUtils.parseArgument(params, 'recipientAddress', 'address') : undefined, - transactionTypes: params.type ? routeUtils.parseArgumentAsArray(params, 'type', 'uint') : undefined, - embedded: params.embedded ? routeUtils.parseArgument(params, 'embedded', 'boolean') : undefined, - /** transfer transaction specific filters */ - transferMosaicId: params.transferMosaicId ? routeUtils.parseArgument(params, 'transferMosaicId', 'uint64hex') : undefined, - fromTransferAmount: params.fromTransferAmount - ? routeUtils.parseArgument(params, 'fromTransferAmount', 'uint64') : undefined, - toTransferAmount: params.toTransferAmount ? routeUtils.parseArgument(params, 'toTransferAmount', 'uint64') : undefined - }; - const options = routeUtils.parsePaginationArguments(params, services.config.pageSize, { id: 'objectId' }); - return db.transactions(params.group, filters, options) - .then(result => routeUtils.createSender(routeResultTypes.transaction).sendPage(res, next)(result)); - }); - - server.get('/transactions/:group/:transactionId', (req, res, next) => { - const { params } = req; - - if (!isValidTransactionGroup(params.group)) - return next(new NotFoundError()); - - let paramType = constants.sizes.objectId === params.transactionId.length ? 'id' : undefined; - paramType = constants.sizes.hash === params.transactionId.length ? 'hash' : paramType; - if (!paramType) - throw Error(`invalid length of transaction id '${params.transactionId}'`); - - const transactionId = routeUtils.parseArgument(params, 'transactionId', 'id' === paramType ? 'objectId' : 'hash256'); - - const dbTransactionsRetriever = 'id' === paramType ? 'transactionsByIds' : 'transactionsByHashes'; - return db[dbTransactionsRetriever](params.group, [transactionId]).then(sender.sendOne(params.transactionId, res, next)); - }); - - server.post('/transactions/:group', (req, res, next) => { - const { params } = req; - - if (!isValidTransactionGroup(params.group)) - return next(new NotFoundError()); - - if ((req.params.transactionIds && req.params.hashes) || (!params.transactionIds && !params.hashes)) - throw errors.createInvalidArgumentError('either ids or hashes must be provided'); - - // normalize ids arg to be either in the transcationIds object or hashes (this is expected to change in the near future) - if (params.transactionIds && constants.sizes.hash === params.transactionIds[0].length) { - params.hashes = params.transactionIds; - delete params.transactionIds; - } - - const transactionIds = params.transactionIds - ? routeUtils.parseArgumentAsArray(params, 'transactionIds', 'objectId') - : routeUtils.parseArgumentAsArray(params, 'hashes', 'hash256'); - - const dbTransactionsRetriever = params.transactionIds ? 'transactionsByIds' : 'transactionsByHashes'; - return db[dbTransactionsRetriever](params.group, transactionIds) - .then(sender.sendArray(params.transactionIds || params.hashes, res, next)); - }); - } -}; diff --git a/rest/src/routes/transactionStatusRoutes.js b/rest/src/routes/transactionStatusRoutes.js deleted file mode 100644 index 29a6b3f4a..000000000 --- a/rest/src/routes/transactionStatusRoutes.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const dbFacade = require('./dbFacade'); -const routeResultTypes = require('./routeResultTypes'); -const routeUtils = require('./routeUtils'); -const catapult = require('catapult-sdk'); - -const { convert } = catapult.utils; -const { constants } = catapult; - -module.exports = { - register: (server, db, services) => { - routeUtils.addGetPostDocumentRoutes( - server, - routeUtils.createSender(routeResultTypes.transactionStatus), - { base: '/transactionStatus', singular: 'hash', plural: 'hashes' }, - params => dbFacade.transactionStatusesByHashes(db, params, services.config.transactionStates), - hash => { - if (2 * constants.sizes.hash256 === hash.length) - return convert.hexToUint8(hash); - - throw Error(`invalid length of hash '${hash.length}'`); - } - ); - } -}; diff --git a/rest/src/routes/wsRoutes.js b/rest/src/routes/wsRoutes.js deleted file mode 100644 index bf50a4f4e..000000000 --- a/rest/src/routes/wsRoutes.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -module.exports = { - register: (server, db, services) => { - server.ws('/ws', { - newChannel: (channel, sender) => { - services.zmqService.on(channel, message => sender.send(message)); - services.zmqService.on(`${channel}.close`, () => sender.close()); - }, - removeChannel: channel => services.zmqService.removeAllListeners(channel) - }); - } -}; diff --git a/rest/src/server/SubscriptionManager.js b/rest/src/server/SubscriptionManager.js deleted file mode 100644 index d689cfd8e..000000000 --- a/rest/src/server/SubscriptionManager.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const winston = require('winston'); - -/** - * Manages client subscriptions. - */ -class SubscriptionManager { - /** - * Creates a subscription manager. - * @param {object} subscriptionCallbacks Callbacks to invoke in response to subscription changes. - */ - constructor(subscriptionCallbacks) { - this.subscriptions = {}; - this.callbacks = Object.assign({ newClient: () => {} }, subscriptionCallbacks); - } - - /** - * Subscribes a client to a channel. - * @param {string} channel Channel to subscribe. - * @param {object} client Client. - */ - add(channel, client) { - if (!(channel in this.subscriptions)) { - this.subscriptions[channel] = new Set(); - try { - this.callbacks.newChannel(channel, this.subscriptions[channel]); - } catch (err) { - delete this.subscriptions[channel]; - throw err; - } - } - - if (this.subscriptions[channel].has(client)) - return; - - this.subscriptions[channel].add(client); - this.callbacks.newClient(channel, client); - } - - /** - * Unsubscribes a client from a channel. - * @param {string} channel Channel to unsubscribe. - * @param {object} client Client. - */ - delete(channel, client) { - const subscriptions = this.subscriptions[channel]; - if (!subscriptions) - return; - - subscriptions.delete(client); - if (!subscriptions.size) { - delete this.subscriptions[channel]; - winston.debug(`all subscriptions to channel '${channel}' have been removed`); - this.callbacks.removeChannel(channel); - } - } - - /** - * Gets all active subscriptions for a client. - * @param {object} client Client. - * @returns {array} Client's subscribed channels. - */ - clientSubscriptions(client) { - return Object.keys(this.subscriptions).filter(channel => this.subscriptions[channel].has(client)); - } - - /** - * Unsubscribes a client from all channels. - * @param {object} client Client. - */ - deleteClient(client) { - Object.keys(this.subscriptions).forEach(channel => { - this.delete(channel, client); - }); - } -} - -module.exports = SubscriptionManager; diff --git a/rest/src/server/bootstrapper.js b/rest/src/server/bootstrapper.js deleted file mode 100644 index 9edce4e55..000000000 --- a/rest/src/server/bootstrapper.js +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const SubscriptionManager = require('./SubscriptionManager'); -const errors = require('./errors'); -const websocketMessageHandler = require('./websocketMessageHandler'); -const websocketUtils = require('./websocketUtils'); -const restify = require('restify'); -const restifyErrors = require('restify-errors'); -const winston = require('winston'); -const WebSocket = require('ws'); -const fs = require('fs'); - -const isPromise = object => object && object.catch; - -const toRestError = err => { - const restError = errors.toRestError(err); - winston.error(`caught error ${restError.statusCode}`, restError); - return restError; -}; - -const createCrossDomainHeaderAdder = crossDomainConfig => (req, res) => { - if (!req.headers.origin || !crossDomainConfig) - return; - - const crossDomainResponseHeaders = {}; - if (crossDomainConfig.allowedMethods.includes(req.method)) - crossDomainResponseHeaders['Access-Control-Allow-Methods'] = crossDomainConfig.allowedMethods.join(','); - - if (!crossDomainConfig.allowedHosts.includes('*')) { - if (crossDomainConfig.allowedHosts.includes(req.headers.origin)) - crossDomainResponseHeaders['Access-Control-Allow-Origin'] = req.headers.origin; - } else { - crossDomainResponseHeaders['Access-Control-Allow-Origin'] = '*'; - } - - crossDomainResponseHeaders['Access-Control-Allow-Headers'] = 'Content-Type'; - - if (3 <= Object.keys(crossDomainResponseHeaders).length) { - if ('*' !== crossDomainResponseHeaders['Access-Control-Allow-Origin']) - crossDomainResponseHeaders.Vary = 'Origin'; - - Object.keys(crossDomainResponseHeaders).forEach(header => res.header(header, crossDomainResponseHeaders[header])); - } -}; - -const catapultRestifyPlugins = { - crossDomain: addCrossDomainHeaders => (req, res, next) => { - addCrossDomainHeaders(req, res); - next(); - }, - body: () => (req, res, next) => { - // reject any GET or OPTIONS request with a body - const mediaType = req.contentType().toLowerCase(); - if (['GET', 'OPTIONS'].includes(req.method)) { - if (!req.contentLength()) - next(); - else - next(new restifyErrors.UnsupportedMediaTypeError(mediaType)); - - return; - } - - // for other HTTP methods reject mismatched media types even if body is empty - if ('application/json' !== mediaType) { - next(new restifyErrors.UnsupportedMediaTypeError(mediaType)); - return; - } - - next(); - } -}; - -const readSSLFileSync = (path, fileType, pathProperty) => { - if (!path) { - throw new Error( - `No SSL ${fileType} found, '${pathProperty}' property in the configuration must be provided.` - ); - } - try { - return fs.readFileSync(path); - } catch (err) { - if ('ENOENT' === err.code) { - throw new Error( - `SSL ${fileType} file cannot be found at the path: ${path}` - ); - } else { - throw err; - } - } -}; - -module.exports = { - createCrossDomainHeaderAdder, - - /** - * Creates a REST api server. - * @param {object} config Application configuration (see rest.json). - * @param {object} formatters Formatters to use for formatting responses. - * @param {object} throttlingConfig Throttling configuration parameters, if not provided throttling won't be enabled. - * @returns {object} Server. - */ - createServer: (config, formatters, throttlingConfig) => { - if (!config) - throw new Error('Config must be provided!'); - - if (!config.protocol) { - winston.warn( - 'Protocol(HTTPS|HTTP) is not configured explicitly in the configuration, defaulting to HTTPS.' - ); - } - - const protocol = config.protocol || 'HTTPS'; - winston.info(`Using protocol: ${protocol}`); - - const serverOptions = { - name: '', // disable server header in response - formatters: { - 'application/json': formatters.json - }, - ...('HTTPS' === protocol - ? { - key: readSSLFileSync(config.sslKeyPath, 'Key', 'sslKeyPath'), - certificate: readSSLFileSync( - config.sslCertificatePath, - 'Certificate', - 'sslCertificatePath' - ) - } - : {}) - }; - - // create the server using a custom formatter - const server = restify.createServer(serverOptions); - - // only allow application/json - server.pre(catapultRestifyPlugins.body()); - - // config.crossDomain: Configuration related to access control, contains allowed host and HTTP methods. - if (!config.crossDomain) - winston.warn('CORS was not enabled - configuration incomplete'); - - const addCrossDomainHeaders = createCrossDomainHeaderAdder( - config.crossDomain || {} - ); - - server.use(catapultRestifyPlugins.crossDomain(addCrossDomainHeaders)); - server.use(restify.plugins.acceptParser('application/json')); - server.use(restify.plugins.queryParser({ mapParams: true, parseArrays: false })); - server.use(restify.plugins.jsonBodyParser({ mapParams: true })); - - if (throttlingConfig) { - if (throttlingConfig.burst && throttlingConfig.rate) { - server.use(restify.plugins.throttle({ - burst: throttlingConfig.burst, - rate: throttlingConfig.rate, - ip: true - })); - } else { - winston.warn('throttling was not enabled - configuration is invalid or incomplete'); - } - } - - // make the server promise aware (only a subset of HTTP methods are supported) - const routeDescriptors = []; - const promiseAwareServer = { - listen: port => { - // sort routes by route name in descending order (catapult is only using string routes) in order to ensure that - // exact match routes (e.g. /foo/fixed) take precedence over wildcard routes (e.g. /foo/:variable) - routeDescriptors.sort((lhs, rhs) => { - if (lhs.route === rhs.route) - return 0; - - return lhs.route < rhs.route ? 1 : -1; - }); - routeDescriptors.forEach(descriptor => { - server[descriptor.method](descriptor.route, descriptor.handler); - }); - - return server.listen(port); - } - }; - - ['get', 'put', 'post'].forEach(method => { - promiseAwareServer[method] = (route, handler) => { - const promiseAwareHandler = (req, res, next) => { - try { - const result = handler(req, res, next); - if (!isPromise(result)) - return; - - result.catch(err => { - next(toRestError(err)); - }); - } catch (err) { - next(toRestError(err)); - } - }; - - routeDescriptors.push({ method, route, handler: promiseAwareHandler }); - }; - }); - - server.on('MethodNotAllowed', (req, res) => { - if ('OPTIONS' === req.method) { - // notice that headers need to be added explicitly because catapultRestifyPlugins.crossDomain is not called after errors - addCrossDomainHeaders(req, res); - return res.send(204); - } - - // fallback to default behavior - return res.send(new restifyErrors.MethodNotAllowedError(`${req.method} is not allowed`)); - }); - - // handle upgrade events (for websocket support) - const wss = new WebSocket.Server({ noServer: true, clientTracking: false }); - - server.on('upgrade', (req, socket, head) => { - wss.handleUpgrade(req, socket, head, client => { - wss.emit(`connection${req.url}`, client); - }); - }); - - const clientGroups = []; - promiseAwareServer.ws = (route, callbacks) => { - const subscriptionManager = new SubscriptionManager(Object.assign({}, callbacks, { - newChannel: (channel, subscribers) => - callbacks.newChannel(channel, websocketUtils.createMultisender(channel, subscribers, formatters.ws)) - })); - - const clients = new Set(); - clientGroups.push({ clients, subscriptionManager }); - - wss.on(`connection${route}`, client => { - const messageHandler = messageJson => websocketMessageHandler.handleMessage(client, messageJson, subscriptionManager); - websocketUtils.handshake(client, messageHandler); - - winston.verbose(`websocket ${client.uid}: created ${route} websocket connection`); - clients.add(client); - - client.on('close', () => { - subscriptionManager.deleteClient(client); - clients.delete(client); - winston.verbose(`websocket ${client.uid}: disconnected ${route} websocket connection`); - }); - }); - }; - - promiseAwareServer.close = () => { - // close all connected websockets - clientGroups.forEach(clientGroup => clientGroup.clients.forEach(client => { - client.terminate(); - })); - - // close the servers - wss.close(); - server.close(); - }; - - return promiseAwareServer; - } -}; diff --git a/rest/src/server/errors.js b/rest/src/server/errors.js deleted file mode 100644 index c974a1d5f..000000000 --- a/rest/src/server/errors.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const restifyErrors = require('restify-errors'); - -module.exports = { - /** - * Converts an arbitrary error to a REST error. - * @param {Error} err Source error. - * @returns {Error} An appropriate REST error. - */ - toRestError: err => (err.statusCode - ? err - : new restifyErrors.InternalError(err, err.message || 'unexpected error')), - - /** - * Creates a not found error. - * @param {object} id Id of the resource that couldn't be found. - * @returns {Error} An appropriate REST error. - */ - createNotFoundError: id => new restifyErrors.ResourceNotFoundError(`no resource exists with id '${id}'`), - - /** - * Creates an invalid argument error. - * @param {string} message Error message. - * @param {Error} err Optional invalid argument cause. - * @returns {Error} An appropriate REST error. - */ - createInvalidArgumentError: (message, err) => (err - ? new restifyErrors.InvalidArgumentError(err, message) - : new restifyErrors.InvalidArgumentError(message)), - - /** - * Creates a service unavailable error. - * @param {string} message Error message. - * @returns {Error} An appropriate REST error. - */ - createServiceUnavailableError: message => new restifyErrors.ServiceUnavailableError(message), - - /** - * Creates an internal error. - * @param {string} message Error message. - * @returns {Error} An appropriate REST error. - */ - createInternalError: message => new restifyErrors.InternalError(message) -}; diff --git a/rest/src/server/formatters.js b/rest/src/server/formatters.js deleted file mode 100644 index 5c521d1bb..000000000 --- a/rest/src/server/formatters.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); - -const { formatArray, formatPage } = catapult.utils.formattingUtils; - -const isCatapultObject = body => body && body.payload && body.type; - -const formatBody = (modelFormatter, body) => { - const formatCatapultObject = (payload, type, structure, wsTopic) => { - if (Array.isArray(payload)) - return formatArray(modelFormatter[type], payload); - - if ('page' === structure) - return formatPage(modelFormatter[type], payload); - - if (wsTopic) { - return { - topic: wsTopic, - data: modelFormatter[type].format(payload) - }; - } - - return modelFormatter[type].format(payload); - }; - - let view = body; - let statusCode; - if (body instanceof Error) { - // snoop for RestError or HttpError, but don't rely on instanceof - statusCode = body.statusCode || 500; - view = body.body ? body.body : { message: body.message }; - } else if (isCatapultObject(body)) { - view = formatCatapultObject(body.payload, body.type, body.structure, body.topic); - } - - return { - statusCode, - json: JSON.stringify(view) - }; -}; - -module.exports = { - /** - * Creates server formatters around a model formatter. - * @param {array} modelFormatters Model formatters. - * @returns {object} Server formatters. - */ - create: modelFormatters => ({ - /** - * Restify compatible formatter for JSON responses. - * @param {object} req Request. - * @param {object} res Response. - * @param {object} body Body. - * @returns {object} Result of the callback. - */ - json: (req, res, body) => { - // implementation based on https://github.com/restify/node-restify/blob/4.x/lib/formatters/json.js - const formatter = (body && body.formatter !== undefined) ? modelFormatters[body.formatter] : modelFormatters.json; - if (body) - delete body.formatter; - const view = formatBody(formatter, body); - if (view.statusCode) - res.statusCode = view.statusCode; - - res.setHeader('Content-Length', Buffer.byteLength(view.json)); - return view.json; - }, - - /** - * Websocket formatter. - * @param {object} body Body. - * @returns {object} Formatted body. - */ - ws: body => (isCatapultObject(body) && 'raw' === body.type ? body.payload : formatBody(modelFormatters.ws, body).json) - }) -}; diff --git a/rest/src/server/messageFormattingRules.js b/rest/src/server/messageFormattingRules.js deleted file mode 100644 index 4c5a03672..000000000 --- a/rest/src/server/messageFormattingRules.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { bufferToUnresolvedAddress } = require('../db/dbUtils'); -const catapult = require('catapult-sdk'); - -const { ModelType, status } = catapult.model; -const { convert, uint64 } = catapult.utils; - -module.exports = { - [ModelType.none]: value => value, - [ModelType.binary]: value => convert.uint8ToHex(value), - [ModelType.statusCode]: status.toString, - [ModelType.string]: value => value.toString(), - [ModelType.uint8]: value => value, - [ModelType.uint16]: value => value, - [ModelType.uint32]: value => value, - [ModelType.uint64]: value => uint64.toString(value), - [ModelType.uint64HexIdentifier]: value => uint64.toHex(value), - [ModelType.int]: value => value, - [ModelType.boolean]: value => value, - [ModelType.encodedAddress]: value => bufferToUnresolvedAddress(value) -}; diff --git a/rest/src/server/websocketMessageHandler.js b/rest/src/server/websocketMessageHandler.js deleted file mode 100644 index 09bff0fec..000000000 --- a/rest/src/server/websocketMessageHandler.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const parseSubscriptionRequest = request => { - const requireString = (bag, propertyName) => { - const str = bag[propertyName]; - if ('string' !== typeof str) - return { error: `client subscription request (${propertyName}) must be string` }; - - return str; - }; - - if (request.subscribe && request.unsubscribe) - return { error: 'client data cannot specify both subscribe and unsubscribe' }; - - if (request.unsubscribe) - return { channel: requireString(request, 'unsubscribe'), action: 'delete' }; - - return { channel: requireString(request, 'subscribe'), action: 'add' }; -}; - -module.exports = { - /** - * Handles a websocket message. - * @param {object} client Client that sent the message. - * @param {string} messageJson JSON message. - * @param {object} subscriptionManager Subscription manager. - * @returns {array} Error information or undefined if no error occurred. - */ - handleMessage: (client, messageJson, subscriptionManager) => { - let request; - try { - request = JSON.parse(messageJson); - } catch (err) { - return [`parse error for data ${messageJson}`, err]; - } - - // check if uid matches assigned one - if (request.uid !== client.uid) - return [`client data does not have proper uid: ${messageJson}`]; - - const subscriptionRequest = parseSubscriptionRequest(request); - const parseErrorMessage = subscriptionRequest.error || subscriptionRequest.channel.error; - if (parseErrorMessage) - return [parseErrorMessage]; - - try { - subscriptionManager[subscriptionRequest.action](subscriptionRequest.channel, client); - } catch (err) { - return [`subscribe error for data ${messageJson}`, err]; - } - - return undefined; - } -}; diff --git a/rest/src/server/websocketUtils.js b/rest/src/server/websocketUtils.js deleted file mode 100644 index fe7f3a9f2..000000000 --- a/rest/src/server/websocketUtils.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); -const winston = require('winston'); -const crypto = require('crypto'); - -const { base32 } = catapult.utils; - -module.exports = { - /** - * Creates an aggregate subscriber composed of all websocket subscribers to a single topic. - * @param {string} topic Subscribed topic from which the data was received. - * @param {array} subscribers Websocket subscribers. - * @param {function} formatter Formatter for formatting data before sending. - * @returns {function} Aggregate subscriber. - */ - createMultisender: (topic, subscribers, formatter) => ({ - /** - * Sends data to all subscribers. - * @param {object} data Unformatted data. - */ - send: data => { - data.topic = topic; - const view = formatter(data); - subscribers.forEach(client => { - winston.debug(`websocket ${client.uid}: multisender.send sending data to client`); - client.send(view, err => { - if (err) { - winston.error(`websocket ${client.uid}: error sending data to websocket`, err); - if (err.message) - client.close(1013, err.message.substring(0, 123)); - else - client.close(); - } - }); - }); - }, - - /** - * Closes all subscribers. - * This function is intended to be invoked when there is a generic channel error. - */ - close: () => { - subscribers.forEach(client => { - client.close(); - }); - } - }), - - /** - * Performs an initial handshake with a new websocket client and registers listeners. - * @param {WebSocket} client Websocket client. - * @param {function} messageHandler Custom message handler. - */ - handshake(client, messageHandler) { - client.uid = base32.encode(crypto.randomBytes(20)); - - const closeWithError = (message, err) => { - winston.error(`websocket ${client.uid}: ${message}`, err); - if (err && err.message) - client.close(1013, err.message.substring(0, 123)); - else - client.close(); - }; - - client.on('error', err => { - closeWithError('error from websocket', err); - }); - - client.on('message', messageJson => { - const errorInformation = messageHandler(messageJson); - if (errorInformation) - closeWithError(...errorInformation); - }); - - client.send(`{"uid": "${client.uid}"}`, err => { - if (err) - closeWithError('error sending data to websocket', err); - }); - } -}; diff --git a/rest/src/sockets/finalizationProofCodec.js b/rest/src/sockets/finalizationProofCodec.js deleted file mode 100644 index cb270e2f7..000000000 --- a/rest/src/sockets/finalizationProofCodec.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module sockets/finalizationProofCodec */ -const catapult = require('catapult-sdk'); - -const { sizes } = catapult.constants; - -const headerSize = 56; - -const finalizationProofCodec = { - /** - * Parses finalization proof. - * @param {object} parser Parser. - * @returns {object} Parsed finalization proof. - */ - deserialize: parser => { - const proof = {}; - - if (0 === parser.numUnprocessedBytes()) - return undefined; - - // parse header (56 bytes) - const size = parser.uint32(); // Full packet size - proof.version = parser.uint32(); - proof.finalizationEpoch = parser.uint32(); - proof.finalizationPoint = parser.uint32(); - proof.height = parser.uint64(); - proof.hash = parser.buffer(sizes.hash256); - - // parse message groups - proof.messageGroups = []; - let sizeLeft = size - headerSize; - while (0 !== sizeLeft) { - const messageGroupSize = parser.uint32(); - const hashCount = parser.uint32(); - const signatureCount = parser.uint32(); - const messageGroup = { - stage: parser.uint32(), - height: parser.uint64(), - hashes: [], - signatures: [] - }; - - for (let i = 0; i < hashCount; i++) - messageGroup.hashes.push(parser.buffer(sizes.hash256)); - for (let i = 0; i < signatureCount; i++) { - const signature = { - root: { - parentPublicKey: parser.buffer(sizes.signerPublicKey), - signature: parser.buffer(sizes.signature) - }, - bottom: { - parentPublicKey: parser.buffer(sizes.signerPublicKey), - signature: parser.buffer(sizes.signature) - } - }; - - messageGroup.signatures.push(signature); - } - proof.messageGroups.push(messageGroup); - sizeLeft -= messageGroupSize; - } - - return proof; - } -}; - -module.exports = finalizationProofCodec; diff --git a/rest/src/sockets/nodeInfoCodec.js b/rest/src/sockets/nodeInfoCodec.js deleted file mode 100644 index bffe7dba4..000000000 --- a/rest/src/sockets/nodeInfoCodec.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module sockets/nodeInfoCodec */ -const catapult = require('catapult-sdk'); - -const { sizes } = catapult.constants; - -const nodeInfoCodec = { - /** - * Parses a node info. - * @param {object} parser Parser. - * @returns {object} Parsed node info. - */ - deserialize: parser => { - const nodeInfo = {}; - parser.uint32(); // Node size - nodeInfo.version = parser.uint32(); - nodeInfo.publicKey = parser.buffer(sizes.signerPublicKey); - nodeInfo.networkGenerationHashSeed = parser.buffer(sizes.hash256); - nodeInfo.roles = parser.uint32(); - nodeInfo.port = parser.uint16(); - nodeInfo.networkIdentifier = parser.uint8(); - const hostSize = parser.uint8(); - const friendlyNameSize = parser.uint8(); - nodeInfo.host = 0 === hostSize ? Buffer.alloc(0) : parser.buffer(hostSize); - nodeInfo.friendlyName = 0 === friendlyNameSize ? Buffer.alloc(0) : parser.buffer(friendlyNameSize); - return nodeInfo; - } -}; - -module.exports = nodeInfoCodec; diff --git a/rest/src/sockets/nodePeersCodec.js b/rest/src/sockets/nodePeersCodec.js deleted file mode 100644 index 047d41d6a..000000000 --- a/rest/src/sockets/nodePeersCodec.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module sockets/nodePeersCodec */ -const nodeInfoCodec = require('./nodeInfoCodec'); - -const nodePeersCodec = { - /** - * Parses node peers, composed of multiple nodes info - * @param {object} parser Parser. - * @returns {object} Parsed node peers. - */ - deserialize: parser => { - const nodePeers = []; - while (0 !== parser.buffers.numUnprocessedBytes) - nodePeers.push(nodeInfoCodec.deserialize(parser)); - - return nodePeers; - } -}; - -module.exports = nodePeersCodec; diff --git a/rest/src/sockets/nodeTimeCodec.js b/rest/src/sockets/nodeTimeCodec.js deleted file mode 100644 index 26f5f7846..000000000 --- a/rest/src/sockets/nodeTimeCodec.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module sockets/nodeTimeCodec */ - -const nodeTimeCodec = { - /** - * Parses node communication timestamps. - * @param {object} parser Parser. - * @returns {object} Parsed node info. - */ - deserialize: parser => ({ - communicationTimestamps: { - sendTimestamp: parser.uint64(), - receiveTimestamp: parser.uint64() - } - }) -}; - -module.exports = nodeTimeCodec; diff --git a/rest/src/sockets/stateTreesCodec.js b/rest/src/sockets/stateTreesCodec.js deleted file mode 100644 index f27a0a32e..000000000 --- a/rest/src/sockets/stateTreesCodec.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -/** @module sockets/stateTreesCodec */ - -const catapult = require('catapult-sdk'); - -const { sizes } = catapult.constants; - -const stateTreesCodec = { - /** - * Parses state trees. - * @param {object} parser Parser. - * @returns {object} Parsed state tree. - */ - deserialize: parser => { - const tree = []; - while (parser.numUnprocessedBytes()) - tree.push(parser.buffer(sizes.hash256)); - return { tree }; - } -}; - -module.exports = stateTreesCodec; diff --git a/rest/test/.eslintrc b/rest/test/.eslintrc deleted file mode 100644 index 334364a91..000000000 --- a/rest/test/.eslintrc +++ /dev/null @@ -1,14 +0,0 @@ ---- -env: - mocha: true -rules: - import/no-extraneous-dependencies: - - error - - devDependencies: true - - no-underscore-dangle: - - error - - allow: - - _id # mongodb identifier - - high_ # MongoDb.Timestamp - - low_ # MongoDb.Timestamp diff --git a/rest/test/connection/MessageChannelBuilder_spec.js b/rest/test/connection/MessageChannelBuilder_spec.js deleted file mode 100644 index 53797c715..000000000 --- a/rest/test/connection/MessageChannelBuilder_spec.js +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MessageChannelBuilder = require('../../src/connection/MessageChannelBuilder'); -const { ServerMessageHandler } = require('../../src/connection/serverMessageHandlers'); -const test = require('../testUtils'); -const { expect } = require('chai'); - -describe('message channel builder', () => { - const networkIdentifier = 152; - const addressTemplate = { - encoded: 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA', - decodedHex: '6823BB7C3C089D996585466380EDBDC19D4959184893E38C', - decoded: Buffer.from('6823BB7C3C089D996585466380EDBDC19D4959184893E38C', 'hex'), - aliasDecodedHex: '9960629109A48AFBC0000000000000000000000000000000', - aliasEncodedHex: 'C0FB8AA409916260', - aliasDecoded: Buffer.from('9960629109A48AFBC0000000000000000000000000000000', 'hex') - }; - - const addAddressFilterTests = (markerByte, createFilter) => { - it('rejects marker without topic param', () => { - // Arrange: - const filter = createFilter(new MessageChannelBuilder({}, networkIdentifier)); - - // Act: - expect(() => filter('')).to.throw('address param missing from address subscription'); - }); - - it('accepts marker without topic param with allowOptionalAddress', () => { - // Arrange: - const filter = createFilter(new MessageChannelBuilder({ allowOptionalAddress: true })); - - // Act: - const topic = filter(''); - - // Assert: - expect(topic.length).to.equal(1); - expect(topic[0]).to.equal(markerByte); - }); - - it('accepts marker with topic param', () => { - // Arrange: - const filter = createFilter(new MessageChannelBuilder({}, networkIdentifier)); - - // Act: - const topic = filter(addressTemplate.encoded); - - // Assert: - expect(topic.length).to.equal(test.constants.sizes.addressDecoded + 1); - expect(topic[0]).to.equal(markerByte); - expect(topic.slice(1)).to.deep.equal(addressTemplate.decoded); - }); - - it('accepts marker with topic param encoded alias hex', () => { - // Arrange: - const filter = createFilter(new MessageChannelBuilder({}, networkIdentifier)); - - // Act: - const topic = filter(addressTemplate.aliasEncodedHex); - - // Assert: - expect(topic.length).to.equal(test.constants.sizes.addressDecoded + 1); - expect(topic[0]).to.equal(markerByte); - expect(topic.slice(1)).to.deep.equal(addressTemplate.aliasDecoded); - }); - - it('rejects marker with invalid topic param', () => { - // Arrange: - const filter = createFilter(new MessageChannelBuilder({}, networkIdentifier)); - - // Act: - expect(() => filter('NAAAA')).to.throw('NAAAA does not represent a valid encoded address'); - }); - }; - - describe('default channels', () => { - it('are all present', () => { - // Act: - const channels = new MessageChannelBuilder({}, networkIdentifier).build(); - const defaultChannelNames = Object.keys(channels); - - // Assert: - expect(defaultChannelNames).to.deep.equal([ - 'block', - 'finalizedBlock', - 'confirmedAdded', - 'unconfirmedAdded', - 'unconfirmedRemoved', - 'status' - ]); - }); - - describe('block', () => { - describe('filter', () => { - it('accepts marker without topic param', () => { - // Arrange: - const { filter } = new MessageChannelBuilder({}, networkIdentifier).build().block; - - // Act: - const topic = filter(''); - - // Assert: - expect(topic).to.deep.equal(Buffer.of(0x49, 0x6A, 0xCA, 0x80, 0xE4, 0xD8, 0xF2, 0x9F)); - }); - - it('rejects marker with topic param', () => { - // Arrange: - const { filter } = new MessageChannelBuilder({}, networkIdentifier).build().block; - - // Act: - expect(() => filter(addressTemplate.encoded)).to.throw('unexpected param to block subscription'); - }); - }); - - describe('handler', () => { - it('is set to block type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - expect(messageChannelBuilder.descriptors.block.handler).to.equal(ServerMessageHandler.block); - }); - }); - }); - - describe('confirmedAdded', () => { - describe('filter', () => { addAddressFilterTests(0x61, builder => builder.build().confirmedAdded.filter); }); - describe('handler', () => { - it('is set to transaction type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - expect(messageChannelBuilder.descriptors.confirmedAdded.handler).to.equal(ServerMessageHandler.transaction); - }); - }); - }); - - describe('unconfirmedAdded', () => { - describe('filter', () => { addAddressFilterTests(0x75, builder => builder.build().unconfirmedAdded.filter); }); - describe('handler', () => { - it('is set to transaction type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - expect(messageChannelBuilder.descriptors.unconfirmedAdded.handler).to.equal(ServerMessageHandler.transaction); - }); - }); - }); - - describe('unconfirmedRemoved', () => { - describe('filter', () => { addAddressFilterTests(0x72, builder => builder.build().unconfirmedRemoved.filter); }); - describe('handler', () => { - it('is set to transaction type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - expect(messageChannelBuilder.descriptors.unconfirmedRemoved.handler).to.equal(ServerMessageHandler.transactionHash); - }); - }); - }); - - describe('status', () => { - describe('filter', () => { addAddressFilterTests(0x73, builder => builder.build().status.filter); }); - describe('handler', () => { - it('is set to transaction type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - expect(messageChannelBuilder.descriptors.status.handler).to.equal(ServerMessageHandler.transactionStatus); - }); - }); - }); - }); - - describe('custom channels', () => { - describe('with transaction handler', () => { - const createChannelInfo = builder => { - builder.add('foo', 'z', ServerMessageHandler.transaction); - return builder.build().foo; - }; - describe('filter', () => { addAddressFilterTests(0x7A, builder => createChannelInfo(builder).filter); }); - describe('handler', () => { - it('is set to transaction type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - createChannelInfo(messageChannelBuilder); - expect(messageChannelBuilder.descriptors.foo.handler).to.equal(ServerMessageHandler.transaction); - }); - }); - }); - - describe('with transaction hash handler', () => { - const createChannelInfo = builder => { - builder.add('foo', 'z', ServerMessageHandler.transactionHash); - return builder.build().foo; - }; - describe('filter', () => { addAddressFilterTests(0x7A, builder => createChannelInfo(builder).filter); }); - describe('handler', () => { - it('is set to transaction hash type', () => { - const messageChannelBuilder = new MessageChannelBuilder({}, networkIdentifier); - createChannelInfo(messageChannelBuilder); - expect(messageChannelBuilder.descriptors.foo.handler).to.equal(ServerMessageHandler.transactionHash); - }); - }); - }); - - describe('with custom handler', () => { - const createChannelInfo = builder => { - builder.add('foo', 'z', (codec, emit) => (topic, buffer) => { - // just emit first byte - emit({ first: buffer[0] }); - }); - return builder.build().foo; - }; - describe('filter', () => { addAddressFilterTests(0x7A, builder => createChannelInfo(builder).filter); }); - describe('handler', () => { - it('forwards to emit callback', () => { - // Arrange: - const emitted = []; - const codec = { - collected: [], - deserialize: (parser, options) => { - codec.collected.push({ parser, options }); - return 40; - } - }; - const { handler } = createChannelInfo(new MessageChannelBuilder({}, networkIdentifier)); - - // Act: - const buffer = [55, 77, 33]; - handler(codec, eventData => emitted.push(eventData))(22, buffer, 99); - - // Assert: - // - 22 is a "topic" so it's not forwarded - // - trailing param 99 should be ignored - expect(codec.collected.length).to.equal(0); - - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ first: 55 }); - }); - }); - }); - - it('cannot be added with multi-character marker', () => { - // Arrange: - const builder = new MessageChannelBuilder({}, networkIdentifier); - - // Assert: - expect(() => builder.add('foo', 'zz', ServerMessageHandler.transaction)).to.throw('channel marker must be single character'); - }); - - it('cannot override default channel', () => { - // Arrange: - const builder = new MessageChannelBuilder({}, networkIdentifier); - - // Assert: - expect(() => builder.add('status', 'z', ServerMessageHandler.transaction)).to.throw('channel has already been registered'); - expect(() => builder.add('foo', 'u', ServerMessageHandler.transaction)).to.throw('channel marker has already been registered'); - }); - - it('cannot be registered multiple times', () => { - // Arrange: - const builder = new MessageChannelBuilder({}, networkIdentifier); - builder.add('foo', 'z', ServerMessageHandler.transaction); - - // Assert: - expect(() => builder.add('foo', 'z', ServerMessageHandler.transaction)).to.throw('channel has already been registered'); - expect(() => builder.add('foo', 'y', ServerMessageHandler.transaction)).to.throw('channel has already been registered'); - expect(() => builder.add('bar', 'z', ServerMessageHandler.transaction)).to.throw('channel marker has already been registered'); - }); - }); -}); diff --git a/rest/test/connection/MockSocket.js b/rest/test/connection/MockSocket.js deleted file mode 100644 index 2c6a7a88a..000000000 --- a/rest/test/connection/MockSocket.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -class MockSocket { - constructor() { - this.authorized = false; - this.numWrites = 0; - this.onceEventHandlers = {}; - this.onEventHandlers = {}; - } - - once(event, handler) { - this.onceEventHandlers[event] = handler; - return this; - } - - on(event, handler) { - this.onEventHandlers[event] = handler; - return this; - } - - write() { - this.numWrites++; - } - - fireEvent(event) { - const onceEvent = this.onceEventHandlers[event]; - if (onceEvent) { - delete this.onceEventHandlers[event]; - onceEvent(); - } else if (this.onEventHandlers[event]) { - this.onEventHandlers[event](); - } - } -} - -module.exports = { - MockSocket -}; diff --git a/rest/test/connection/catapultConnection_spec.js b/rest/test/connection/catapultConnection_spec.js deleted file mode 100644 index 2e829d8b5..000000000 --- a/rest/test/connection/catapultConnection_spec.js +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapultConnection = require('../../src/connection/catapultConnection'); -const { expect } = require('chai'); - -describe('catapult connection', () => { - const createTestContext = () => { - let isEnded = false; - const context = { - isEnded: () => isEnded, - onCalls: {}, - onceCalls: {}, - writeCalls: [], - removeCalls: {}, - mockConnection: { - on: (name, handler) => { - context.onCalls[name] = handler; - return context.mockConnection; - }, - once: (name, handler) => { - context.onceCalls[name] = handler; - }, - write: (payload, callback) => { - context.writeCalls.push({ payload, callback }); - }, - removeListener: (name, handler) => { - context.removeCalls[name] = handler; - }, - - emit: name => context.onCalls[name](), - - end: () => { - isEnded = true; - } - } - }; - return context; - }; - - describe('send', () => { - const assertSend = (testName, assertCallback) => { - it(testName, () => { - // Arrange: - const payload = { test: 12345 }; - const context = createTestContext(); - - // Act: - const promise = catapultConnection.wrap(context.mockConnection).send(payload); - - // Assert: - expect(context.onCalls).to.deep.equal({}); - expect(context.onceCalls).to.have.all.keys('close'); - expect(context.writeCalls.length).to.equal(1); - expect(context.writeCalls[0].payload).to.deep.equal(payload); - expect(context.removeCalls).to.deep.equal({}); - - return assertCallback(context, promise); - }); - }; - - assertSend('sending the data resolves the promise', (context, promise) => { - // Act: - context.writeCalls[0].callback(); - - return promise.then(() => { - // Assert: - expect(context.removeCalls).to.have.all.keys('close'); - expect(context.removeCalls.close).to.equal(context.onceCalls.close); - }); - }); - - assertSend('closing connection rejects the promise', (context, promise) => { - // Act: - context.onceCalls.close(); - - return promise - .then(() => { - throw new Error('promise resolved'); - }) - .catch(err => { - // Assert: - expect(err.statusCode).to.equal(503); - expect(err.message).to.equal('connection failed'); - }); - }); - }); - - describe('pushPull', () => { - const assertPushPull = (testName, assertCallback) => { - it(testName, () => { - // Arrange: - const payload = { test: 12345 }; - const context = createTestContext(); - - // Act: - const promise = catapultConnection.wrap(context.mockConnection).pushPull(payload, 1000); - - // Assert: - expect(context.onCalls).to.deep.equal({}); - expect(context.onceCalls).to.have.all.keys('close'); - expect(context.writeCalls.length).to.equal(1); - expect(context.writeCalls[0].payload).to.deep.equal(payload); - expect(context.removeCalls).to.deep.equal({}); - - return assertCallback(context, promise); - }); - }; - - assertPushPull('sending payload returns data', (context, promise) => { - // Act: - context.writeCalls[0].callback(); - - setTimeout(() => { - context.onCalls.data(Buffer.from([24, 0, 0, 0, 188, 2, 0, 0])); - context.onCalls.data(Buffer.from([80, 71, 26, 165, 16, 0, 0, 0, 80, 71, 26, 165, 16, 0, 0, 0])); - }, 10); - - return promise.then(packet => { - // Assert: - expect(packet).to.be.deep.equal({ - type: 700, - size: 24, - payload: Buffer.from([80, 71, 26, 165, 16, 0, 0, 0, 80, 71, 26, 165, 16, 0, 0, 0]) - }); - expect(context.removeCalls).to.have.all.keys('close'); - expect(context.removeCalls.close).to.equal(context.onceCalls.close); - expect(context.isEnded()).to.be.equal(true); - }); - }); - - assertPushPull('closing connection rejects the promise', (context, promise) => { - // Act: - context.onceCalls.close(); - - return promise - .then(() => { - throw new Error('promise resolved'); - }) - .catch(err => { - // Assert: - expect(err.statusCode).to.equal(503); - expect(err.message).to.equal('connection failed'); - }); - }); - - assertPushPull('not receiving the data before timeout rejects the promise', (context, promise) => { - // Act: - context.writeCalls[0].callback(); - - return promise - .then(() => { - throw new Error('promise resolved'); - }) - .catch(err => { - // Assert: - expect(err.statusCode).to.equal(503); - expect(err.message).to.equal('connection failed'); - expect(context.isEnded()).to.be.equal(true); - }); - }); - - assertPushPull( - 'closing connection after receiving the first part of the packet rejects the promise', - (context, promise) => { - // Act: - context.writeCalls[0].callback(); - - setTimeout(() => { - context.onCalls.data(Buffer.from([24, 0, 0, 0, 188, 2, 0, 0])); - context.onceCalls.close(); - }, 10); - - return promise - .then(() => { - throw new Error('promise resolved'); - }) - .catch(err => { - // Assert: - expect(err.statusCode).to.equal(503); - expect(err.message).to.equal('connection failed'); - }); - } - ); - }); -}); diff --git a/rest/test/connection/connectionService_spec.js b/rest/test/connection/connectionService_spec.js deleted file mode 100644 index db2c2c674..000000000 --- a/rest/test/connection/connectionService_spec.js +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockSocket } = require('./MockSocket'); -const { createConnectionService } = require('../../src/connection/connectionService'); -const { expect } = require('chai'); -const sinon = require('sinon'); -const tls = require('tls'); - -describe('connection service', () => { - const sockets = []; - let tlsConnectStub; - const testConfig = { - apiNode: { - host: 'test hostname', - port: 12345, - key: '', - certificate: '', - caCertificate: '' - } - }; - let connectionService; - - beforeEach(() => { - tlsConnectStub = sinon.stub(tls, 'connect').callsFake(() => { - const fakeSocket = new MockSocket(); - sockets.push(fakeSocket); - return fakeSocket; - }); - connectionService = createConnectionService(testConfig); - }); - - afterEach(() => { - tlsConnectStub.restore(); - tlsConnectStub = undefined; - sockets.splice(0, sockets.length); - connectionService = undefined; - }); - - it('authentication success is forwarded', () => { - // Act: - const leasePromise = connectionService.lease().then(connection => { - connection.send(); - - // Assert: - expect(sockets[0].numWrites).to.equal(1); - }); - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return leasePromise; - }); - - it('connection close is forwarded', () => { - // Act: - const leasePromise = connectionService.lease().catch(error => { - // Assert: - expect(error.message).to.equal('connection failed'); - }); - sockets[0].authorized = true; - sockets[0].fireEvent('close'); - - return leasePromise; - }); - - describe('connection lease', () => { - it('connection is cached/reused', () => { - // Act: - const leasePromise = connectionService.lease().then(connection1 => - connectionService.lease().then(connection2 => { - // Assert: - expect(connection2).to.equal(connection1); - })); - - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return leasePromise; - }); - - it('connection will be recreated after close', () => { - const leasePromise = connectionService.lease().then(connection1 => { - sockets[0].fireEvent('close'); - - const leasePromise2 = connectionService.lease().then(connection2 => { - // Assert: - expect(connection2).to.not.equal(connection1); - - connection2.send(); - expect(sockets[0].numWrites).to.equal(0); - expect(sockets[1].numWrites).to.equal(1); - }); - - sockets[1].authorized = true; - sockets[1].fireEvent('secureConnect'); - - return leasePromise2; - }); - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return leasePromise; - }); - - it('error event does not affect connection', () => { - // Act: - const leasePromise = connectionService.lease().then(connection => { - sockets[0].fireEvent('error'); - connection.send(); - expect(sockets[0].numWrites).to.equal(1); - }); - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return leasePromise; - }); - }); - - describe('connection singleUse', () => { - it('connection is not cached/reused', () => { - // Act: - const singleUsePromise = connectionService.singleUse().then(connection1 => { - const singleUsePromise2 = connectionService.singleUse().then(connection2 => { - // Assert: - expect(connection2).to.not.equal(connection1); - }); - sockets[1].authorized = true; - sockets[1].fireEvent('secureConnect'); - - return singleUsePromise2; - }); - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return singleUsePromise; - }); - - it('new connection is created after close', () => { - const singleUsePromise = connectionService.singleUse().then(connection1 => { - sockets[0].fireEvent('close'); - - const singleUsePromise2 = connectionService.singleUse().then(connection2 => { - // Assert: - expect(connection2).to.not.equal(connection1); - - connection2.send(); - expect(sockets[0].numWrites).to.equal(0); - expect(sockets[1].numWrites).to.equal(1); - }); - - sockets[1].authorized = true; - sockets[1].fireEvent('secureConnect'); - - return singleUsePromise2; - }); - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return singleUsePromise; - }); - - it('error event does not affect connection', () => { - // Act: - const singleUsePromise = connectionService.singleUse().then(connection => { - sockets[0].fireEvent('error'); - connection.send(); - expect(sockets[0].numWrites).to.equal(1); - }); - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return singleUsePromise; - }); - }); - - describe('handles first simultaneous connections correctly when authorization is delayed', () => { - it('on successful authorization both parties should lease the same connection', () => { - // Act: - let firstConn; - let secondConn; - const leasePromises = Promise.all([ - connectionService.lease().then(firstConnection => { - firstConn = firstConnection; - }), - connectionService.lease().then(secondConnection => { - secondConn = secondConnection; - }) - ]).then(() => { - // Assert: - expect(secondConn).to.equal(firstConn); - }); - - // unblocks the first promise (simulates delayed acceptance of authorization) - sockets[0].authorized = true; - sockets[0].fireEvent('secureConnect'); - - return leasePromises; - }); - - it('on failed authorization both parties should fail on the same pending authorization promise', () => { - // Act: - const leasePromises = Promise.all([ - connectionService.lease(), - connectionService.lease() - ]).catch(error => { - // Assert: - expect(error.message).to.equal('connection failed'); - }); - - // unblocks the first promise (simulates delayed authorization failure) - sockets[0].fireEvent('close'); - - return leasePromises; - }); - }); -}); diff --git a/rest/test/connection/serverMessageHandlers_spec.js b/rest/test/connection/serverMessageHandlers_spec.js deleted file mode 100644 index d5bb44738..000000000 --- a/rest/test/connection/serverMessageHandlers_spec.js +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { ServerMessageHandler } = require('../../src/connection/serverMessageHandlers'); -const test = require('../testUtils'); -const { expect } = require('chai'); - -describe('server message handlers', () => { - const createMockCodec = value => { - const mock = { - // only some message handlers require codec, objects passed to codec.deserialize() are collected in following array - collected: [], - deserialize: (parser, options) => { - mock.collected.push({ parser, options }); - return value; - } - }; - return mock; - }; - - it('block handler', () => { - // Arrange: - const emitted = []; - const codec = createMockCodec(34); - const blockBuffer = Buffer.of(0xAB, 0xCD, 0xEF); - - // Act: - ServerMessageHandler.block(codec, eventData => emitted.push(eventData))(12, blockBuffer, 56, 78, 99, 88); - - // Assert: - // - 12 is a "topic" so it's not forwarded - // - trailing params (99, 88) should be ignored - expect(codec.collected.length).to.equal(1); - expect(codec.collected[0].parser.buffers.current()).to.equal(blockBuffer); - - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ - type: 'blockHeaderWithMetadata', - payload: { block: 34, meta: { hash: 56, generationHash: 78 } } - }); - }); - - it('finalized block handler', () => { - // Arrange: - const emitted = []; - const codec = createMockCodec(35); - const finalizedBlockBuffer = Buffer.concat([ - Buffer.of(44, 0, 0, 0), // finalization epoch - Buffer.of(55, 0, 0, 0), // finalization point - Buffer.of(66, 0, 0, 0, 0, 0, 0, 0), // height - Buffer.alloc(test.constants.sizes.hash256, 41) // hash - ]); - - // Act: - ServerMessageHandler.finalizedBlock(codec, eventData => emitted.push(eventData))(12, finalizedBlockBuffer, 99, 88); - - // Assert: - // - 12 is a "topic" so it's not forwarded - // - trailing params (99, 88) should be ignored - expect(codec.collected.length).to.equal(0); - - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ - type: 'finalizedBlock', - payload: { - finalizationEpoch: 44, - finalizationPoint: 55, - height: [66, 0], - hash: Buffer.alloc(test.constants.sizes.hash256, 41) - } - }); - }); - - it('transaction handler', () => { - // Arrange: - const emitted = []; - const codec = createMockCodec(33); - const transactionBuffer = Buffer.of(0xEF, 0xCD, 0xAB); - - // Act: - const height = Buffer.of(66, 0, 0, 0, 0, 0, 0, 0); - ServerMessageHandler.transaction(codec, eventData => emitted.push(eventData))(22, transactionBuffer, 44, 55, height, 77, 88, 99); - - // Assert: - // - 22 is a "topic" so it's not forwarded - // - trailing params (77, 88, 99) should be ignored - expect(codec.collected.length).to.equal(1); - expect(codec.collected[0].parser.buffers.current()).to.equal(transactionBuffer); - expect(codec.collected[0].options).to.equal(undefined); - - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ - type: 'transactionWithMetadata', - payload: { - transaction: 33, - meta: { - hash: 44, - merkleComponentHash: 55, - height: [66, 0] - } - } - }); - }); - - it('transaction hash handler', () => { - // Arrange: - const emitted = []; - const codec = createMockCodec(35); - - // Act: - ServerMessageHandler.transactionHash(codec, eventData => emitted.push(eventData))(22, 44, 77, 88, 99); - - // Assert: - // - 22 is a "topic" so it's not forwarded - // - trailing params (77, 88, 99) should be ignored - expect(codec.collected.length).to.equal(0); - - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ type: 'transactionWithMetadata', payload: { meta: { hash: 44 } } }); - }); - - it('transaction status handler', () => { - // Arrange: - const emitted = []; - const codec = createMockCodec(35); - const buffer = Buffer.concat([ - Buffer.alloc(test.constants.sizes.hash256, 41), // hash - Buffer.of(66, 0, 0, 0, 0, 0, 0, 0), // deadline - Buffer.of(55, 0, 0, 0) // status - ]); - - // Act: - ServerMessageHandler.transactionStatus(codec, eventData => emitted.push(eventData))(22, buffer, 99); - - // Assert: - // - 22 is a "topic" so it's not forwarded - // - trailing param 99 should be ignored - expect(codec.collected.length).to.equal(0); - - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ - type: 'transactionStatus', - payload: { - hash: Buffer.alloc(test.constants.sizes.hash256, 41), - code: 55, - deadline: [66, 0] - } - }); - }); -}); diff --git a/rest/test/connection/zmqService_spec.js b/rest/test/connection/zmqService_spec.js deleted file mode 100644 index 193897eaf..000000000 --- a/rest/test/connection/zmqService_spec.js +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MessageChannelBuilder = require('../../src/connection/MessageChannelBuilder'); -const { createZmqConnectionService } = require('../../src/connection/zmqService'); -const test = require('../testUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const zmq = require('zeromq'); - -describe('zmq service', () => { - const cleanupActions = []; - afterEach(() => { - // close zmq sockets used during the previous test - while (0 < cleanupActions.length) { - const action = cleanupActions.pop(); - action(); - } - }); - - const createDefaultZmqConnectionService = () => { - const zmqConfig = { - host: '127.0.0.1', port: '3333', connectTimeout: 10, monitorInterval: 50 - }; - const channelDescriptors = new MessageChannelBuilder().build(); - const service = createZmqConnectionService(zmqConfig, {}, channelDescriptors, test.createMockLogger()); - cleanupActions.push(() => service.close()); - return service; - }; - - const createRandomAddressString = () => catapult.model.address.addressToString(test.random.address()); - - describe('invalid subscription', () => { - const assertInvalidSubscription = (channel, error) => { - // Arrange: notice that these tests should fail before creating a subscriber - const service = createDefaultZmqConnectionService(); - - // Assert: - expect(() => service.on(channel, () => {})).to.throw(error); - - // Sanity: - expect(service.zsocketCount()).to.equal(0); - }; - - it('throws if category has no associated channel descriptor', () => { - // Assert: - assertInvalidSubscription('foo', 'unknown topic category foo'); - }); - - it('throws if category filter cannot be created due to invalid param', () => { - // Assert: - assertInvalidSubscription('block/12345', 'unexpected param to block subscription'); - }); - }); - - describe('valid subscriptions', () => { - it('creates new socket for new topic', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - - // Act: - service.on('block', () => {}); - - // Assert: - expect(service.zsocketCount()).to.equal(1); - expect(service.listenerCount('block')).to.equal(1); - }); - - it('creates socket per topic', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - const address = createRandomAddressString(); - - // Act: - service.on('block', () => {}); - service.on(`confirmedAdded/${address}`, () => {}); - service.on(`unconfirmedAdded/${address}`, () => {}); - - // Assert: - expect(service.zsocketCount()).to.equal(3); - expect(service.listenerCount('block')).to.equal(1); - expect(service.listenerCount(`confirmedAdded/${address}`)).to.equal(1); - expect(service.listenerCount(`unconfirmedAdded/${address}`)).to.equal(1); - }); - - it('reuses socket for existing topic', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - - // Act: - for (let i = 0; 9 > i; ++i) - service.on('block', () => {}); - - // Assert: - expect(service.zsocketCount()).to.equal(1); - expect(service.listenerCount('block')).to.equal(9); - }); - - it('raises channel close event on connection timeout', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - return new Promise(resolve => { - service.on('block.close', () => { - // Assert: socket is already closed when event is raised - expect(service.zsocketCount()).to.equal(0); - - setTimeout(() => { - // - listeners are removed after short delay - expect(service.listenerCount('block')).to.equal(0); - expect(service.listenerCount('block.close')).to.equal(0); - resolve(); - }, 0); - }); - - // Act: - service.on('block', () => {}); - }); - }); - }); - - describe('subscription messages', () => { - const generateBlockBuffers = () => ({ - block: Buffer.concat([ - Buffer.of(0x97, 0x87, 0x45, 0x0E, 0xE1, 0x6C, 0xB6, 0x62), // height 8b - Buffer.of(0x30, 0x3A, 0x46, 0x8B, 0x15, 0x2D, 0x60, 0x54), // timestamp 8b - Buffer.of(0x86, 0x02, 0x75, 0x30, 0xE8, 0x50, 0x78, 0xE8), // difficulty 8b - Buffer.from(test.random.hash()), // previous block hash 32b - Buffer.from(test.random.hash()), // block transactions hash 32b - Buffer.from(test.random.hash()), // receiptsHashBuffer 32b - Buffer.from(test.random.hash()), // stateHashBuffer 32b - test.random.bytes(test.constants.sizes.addressDecoded), // beneficiaryAddress 24b - Buffer.of(0x0A, 0x00, 0x00, 0x00), // fee multiplier 4b - Buffer.of(0x00, 0x00, 0x00, 0x00) // reserved padding 4b - ]), - - entityHash: Buffer.from(test.random.hash()), - generationHash: Buffer.from(test.random.hash()) - }); - - it('forwards messages to subscribed handlers', () => { - // Arrange: - const zmqConfig = { - host: '127.0.0.1', port: '3333', connectTimeout: 1000, monitorInterval: 50 - }; - const codec = { - // - parsing is not being tested so just extract the entire parser contents into a buffer - deserialize: parser => parser.buffer(parser.numUnprocessedBytes()) - }; - const channelDescriptors = new MessageChannelBuilder().build(); - const service = createZmqConnectionService(zmqConfig, codec, channelDescriptors, test.createLogger()); - cleanupActions.push(() => service.close()); - - const blockBuffers = generateBlockBuffers(); - return new Promise((resolve, reject) => { - // Arrange: create a publisher and publish a block - const endpoint = `tcp://${zmqConfig.host}:${zmqConfig.port}`; - const zsocket = zmq.socket('pub'); - cleanupActions.push(() => { - zsocket.disconnect(endpoint); - zsocket.close(); - }); - - zsocket.bind(endpoint, err => { - if (err) { - reject(err); - return; - } - - // Arrange: subscribe to block events (this needs to be done after bind in order to avoid potential races) - service.on('block', message => { - // Assert: the parsed message is consistent with the published block message - expect(message).to.deep.equal({ - type: 'blockHeaderWithMetadata', - payload: { - block: blockBuffers.block, - meta: { hash: blockBuffers.entityHash, generationHash: blockBuffers.generationHash } - } - }); - resolve(); - }); - - // Act: publish a single block (as a multipart message) after completion of bind callback processing - setTimeout(() => { - const marker = Buffer.of(0x49, 0x6A, 0xCA, 0x80, 0xE4, 0xD8, 0xF2, 0x9F); - zsocket.send(marker, zmq.ZMQ_SNDMORE); - zsocket.send(blockBuffers.block, zmq.ZMQ_SNDMORE); - zsocket.send(blockBuffers.entityHash, zmq.ZMQ_SNDMORE); - zsocket.send(blockBuffers.generationHash); - }, 100); - }); - }); - }); - }); - - describe('remove all listeners', () => { - it('removes all subscriptions for topic', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - const address1 = createRandomAddressString(); - const address2 = createRandomAddressString(); - - // - add subscriptions - service.on(`confirmedAdded/${address1}`, () => {}); - service.on('block', () => {}); - service.on(`confirmedAdded/${address1}.close`, () => {}); - service.on(`confirmedAdded/${address1}`, () => {}); - service.on(`confirmedAdded/${address2}`, () => {}); - - // Act: - service.removeAllListeners(`confirmedAdded/${address1}`); - - // Assert: - expect(service.zsocketCount()).to.equal(2); - expect(service.listenerCount('block')).to.equal(1); - expect(service.listenerCount(`confirmedAdded/${address1}`)).to.equal(0); - expect(service.listenerCount(`confirmedAdded/${address1}.close`)).to.equal(0); - expect(service.listenerCount(`confirmedAdded/${address2}`)).to.equal(1); - }); - - it('is idempotent', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - const address = createRandomAddressString(); - - // - add subscriptions - service.on(`confirmedAdded/${address}`, () => {}); - service.on('block', () => {}); - service.on(`confirmedAdded/${address}.close`, () => {}); - service.on(`confirmedAdded/${address}`, () => {}); - - // Act: - for (let i = 0; 9 > i; ++i) - service.removeAllListeners(`confirmedAdded/${address}`); - - // Assert: - expect(service.zsocketCount()).to.equal(1); - expect(service.listenerCount('block')).to.equal(1); - expect(service.listenerCount(`confirmedAdded/${address}`)).to.equal(0); - expect(service.listenerCount(`confirmedAdded/${address}.close`)).to.equal(0); - }); - - it('allows new subscriptions to previously removed topics', () => { - // Arrange: - const service = createDefaultZmqConnectionService(); - const address = createRandomAddressString(); - - // - add subscriptions - service.on(`confirmedAdded/${address}`, () => {}); - service.on('block', () => {}); - service.on(`confirmedAdded/${address}.close`, () => {}); - service.on(`confirmedAdded/${address}`, () => {}); - - // Act: remove listeners and then add one - service.removeAllListeners(`confirmedAdded/${address}`); - service.on(`confirmedAdded/${address}`, () => {}); - - // Assert: - expect(service.zsocketCount()).to.equal(2); - expect(service.listenerCount('block')).to.equal(1); - expect(service.listenerCount(`confirmedAdded/${address}`)).to.equal(1); - expect(service.listenerCount(`confirmedAdded/${address}.close`)).to.equal(0); - }); - }); -}); diff --git a/rest/test/connection/zmqUtils_spec.js b/rest/test/connection/zmqUtils_spec.js deleted file mode 100644 index 5c2e3e5cf..000000000 --- a/rest/test/connection/zmqUtils_spec.js +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const zmqUtils = require('../../src/connection/zmqUtils'); -const test = require('../testUtils'); -const { expect } = require('chai'); - -describe('zmqUtils', () => { - const createMockZsocket = () => { - const zsocket = { - monitorParamGroups: [], - numUnmonitorCalls: 0, - numCloseCalls: 0, - emittedEventNames: [], - eventHandlers: {} - }; - - zsocket.monitor = (interval, numEvents) => { zsocket.monitorParamGroups.push({ interval, numEvents }); }; - zsocket.unmonitor = () => { ++zsocket.numUnmonitorCalls; }; - zsocket.close = () => { ++zsocket.numCloseCalls; }; - - zsocket.emit = eventName => { zsocket.emittedEventNames.push(eventName); }; - - // treat on and once similarly - zsocket.on = (eventName, eventHandler) => { - if (!(eventName in zsocket.eventHandlers)) - zsocket.eventHandlers[eventName] = []; - - zsocket.eventHandlers[eventName].push(eventHandler); - }; - zsocket.once = zsocket.on; - return zsocket; - }; - - describe('prepareZsocket', () => { - const zmqConfig = { connectTimeout: 10000, monitorInterval: 150 }; - - const prepareDefaultZsocket = zsocket => { - zmqUtils.prepareZsocket(zsocket, zmqConfig, test.createMockLogger()); - }; - - const cancelConnectTimer = zsocket => { - zsocket.eventHandlers.connect[1](); // cancel the timer - }; - - const assertZsocketIsOpen = zsocket => { - expect(zsocket.monitorParamGroups).to.deep.equal([{ interval: 150, numEvents: 0 }]); - expect(zsocket.numUnmonitorCalls).to.equal(0); - expect(zsocket.numCloseCalls).to.equal(0); - expect(zsocket.emittedEventNames).to.deep.equal([]); - }; - - const assertZsocketIsClosed = zsocket => { - expect(zsocket.numUnmonitorCalls).to.equal(1); - expect(zsocket.numCloseCalls).to.equal(1); - expect(zsocket.emittedEventNames).to.deep.equal(['zsocket_close']); - }; - - it('enables socket event monitoring', () => { - // Arrange: - const zsocket = createMockZsocket(); - - // Act: - prepareDefaultZsocket(zsocket); - cancelConnectTimer(zsocket); - - // Assert: - assertZsocketIsOpen(zsocket); - }); - - describe('monitor event logging handlers ', () => { - const runMonitorLoggingTest = (options, createLogPromise) => { - // Arrange: - const zsocket = createMockZsocket(); - const logger = test.createMockLogger(); - const monitorEventNames = [ - 'connect', 'connect_delay', 'connect_retry', - 'listen', 'bind_error', - 'accept', 'accept_error', - 'close', 'close_error', - 'disconnect', - 'monitor_error' - ]; - - // Act: - zmqUtils.prepareZsocket(zsocket, Object.assign({ monitorLoggingThrottle: options.throttle }, zmqConfig), logger); - cancelConnectTimer(zsocket); - - // - all events have a (presumably logging) handler registered - const promises = []; - monitorEventNames.forEach((eventName, index) => { - const handler = zsocket.eventHandlers[eventName][0]; - expect(handler, eventName).to.be.a('function'); - - // - invoke the handler - promises.push(createLogPromise(handler)); - - // Assert: the expected number of logs were made synchronously - expect(logger.numLogs, `${eventName} at ${index}`).to.equal((index + 1) * options.numLogsPerInvokeSync); - }); - - return Promise.all(promises).then(() => { - // Assert: the expected number of total logs were made - expect(logger.numLogs).to.equal(monitorEventNames.length * options.numLogsPerInvokeTotal); - - // - there are no side-effects - assertZsocketIsOpen(zsocket); - }); - }; - - it('are registered for all zmq events', () => - // Arrange: - runMonitorLoggingTest({ throttle: 0, numLogsPerInvokeSync: 1, numLogsPerInvokeTotal: 1 }, handler => { - // Act: invoke the handler immediately - handler(); - return Promise.resolve(); - })); - - it('throttle noisy logs', () => - // Arrange: successive logs for same zsocket and event should be throttled - runMonitorLoggingTest({ throttle: 50, numLogsPerInvokeSync: 1, numLogsPerInvokeTotal: 1 }, handler => { - // Act: invoke the handler immediately multiple times - handler(); - handler(); - handler(); - return Promise.resolve(); - })); - - it('allow additional logs outside of throttle period', () => - // Arrange: delayed logs for same zsocket and event should be allowed - runMonitorLoggingTest({ throttle: 50, numLogsPerInvokeSync: 1, numLogsPerInvokeTotal: 2 }, handler => - // Act: invoke the handler immediately - new Promise(resolve => { - handler(); - handler(); - handler(); - - // - invoke the handler after the throttle period - setTimeout(() => { - handler(); - handler(); - handler(); - resolve(); - }, 100); - }))); - }); - - it('customizes close behavior', () => { - // Arrange: - const zsocket = createMockZsocket(); - - // - override emit in order to be able to verify ordering - const emitCaptures = []; - const originalEmit = zsocket.emit; - zsocket.emit = eventName => { - emitCaptures.push({ eventName, numCloseCalls: zsocket.numCloseCalls }); - originalEmit.call(zsocket, eventName); - }; - - prepareDefaultZsocket(zsocket); - cancelConnectTimer(zsocket); - - // Act: - zsocket.close(); - - // Assert: - assertZsocketIsClosed(zsocket); - - // - close event was raised after socket was closed - expect(emitCaptures).to.deep.equal([{ eventName: 'zsocket_close', numCloseCalls: 1 }]); - }); - - it('closes socket on error', () => { - // Arrange: - const zsocket = createMockZsocket(); - prepareDefaultZsocket(zsocket); - cancelConnectTimer(zsocket); - - // Act: - zsocket.eventHandlers.error[0](new Error()); - - // Assert: - assertZsocketIsClosed(zsocket); - }); - - it('closes socket on connect timeout', () => { - // Arrange: - const zsocket = createMockZsocket(); - zmqUtils.prepareZsocket(zsocket, { connectTimeout: 0, monitorInterval: 150 }, test.createMockLogger()); - - // Act: wait for the timeout - return new Promise(resolve => { - setTimeout(() => { - // Assert: - assertZsocketIsClosed(zsocket); - resolve(); - }, 1); - }); - }); - - it('only calls close once when explicit close is followed by timeout', () => { - // Arrange: - const zsocket = createMockZsocket(); - zmqUtils.prepareZsocket(zsocket, { connectTimeout: 0, monitorInterval: 150 }, test.createMockLogger()); - - // Act: explicitly close the socket - zsocket.close(); - - // - let the timer fire and attempt to close the socket again - return new Promise(resolve => { - setTimeout(() => { - // Assert: close was only called once on the underlying socket - assertZsocketIsClosed(zsocket); - resolve(); - }, 1); - }); - }); - - it('clears connect timer on successful connect', () => { - // Arrange: - const zsocket = createMockZsocket(); - zmqUtils.prepareZsocket(zsocket, { connectTimeout: 0, monitorInterval: 150 }, test.createMockLogger()); - - // Act: simulate a connect - cancelConnectTimer(zsocket); - - // - give the timer a chance to fire (it will not because it is cancelled) - return new Promise(resolve => { - setTimeout(() => { - // Assert: close was not called because the timer was cancelled - assertZsocketIsOpen(zsocket); - resolve(); - }, 1); - }); - }); - }); - - describe('createMultisocketEmitter', () => { - const createMockZsocketWithCapture = context => { - context.zsockets = {}; - return (key, eventEmitter) => { - context.eventEmitter = eventEmitter; - context.zsockets[key] = createMockZsocket(); - return context.zsockets[key]; - }; - }; - - it('initially has no sockets', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(() => {}); - - // Act + Assert: - expect(emitter.zsocketCount()).to.equal(0); - }); - - describe('on', () => { - it('creates socket when new channel is subscribed', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - - // Act: - emitter.on('block', () => {}); - - // Assert: - expect(emitter.zsocketCount()).to.equal(1); - expect(emitter.listenerCount('block')).to.equal(1); - - // Sanity: no other listeners are set up - expect(emitter.listenerCount('block.close')).to.equal(0); - expect(emitter.listenerCount('confirmedAdded')).to.equal(0); - }); - - it('creates socket per channel', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - - // Act: - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('partialAdded', () => {}); - - // Assert: - expect(emitter.zsocketCount()).to.equal(3); - expect(emitter.listenerCount('block')).to.equal(1); - expect(emitter.listenerCount('confirmedAdded')).to.equal(1); - expect(emitter.listenerCount('partialAdded')).to.equal(1); - }); - - it('reuses socket when existing channel is subscribed', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - - // Act: - emitter.on('block', () => {}); - emitter.on('block', () => {}); - emitter.on('block', () => {}); - - // Assert: - expect(emitter.zsocketCount()).to.equal(1); - expect(emitter.listenerCount('block')).to.equal(3); - }); - - it('bypasses socket creation when supported subevent is subscribed', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - - // Act: - emitter.on('block.close', () => {}); - - // Assert: - expect(emitter.zsocketCount()).to.equal(0); - expect(emitter.listenerCount('block.close')).to.equal(1); - }); - - it('fails when unsupported subevent is subscribed', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - - // Act + Assert: - expect(() => emitter.on('block.foo', () => {}).to.throw('block.foo indicates an unsupported subevent')); - }); - - const assertOnlySubscribedHandlersAreInvoked = (eventName1, eventName2, numExpectedSockets) => { - // Arrange: - const context = {}; - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocketWithCapture(context)); - const captures = {}; - - // - set up five subscriptions to two different channels - emitter.on(eventName1, value => { captures.a = value; }); - emitter.on(eventName2, value => { captures.b = value; }); - emitter.on(eventName1, value => { captures.c = value; }); - emitter.on(eventName2, value => { captures.d = value; }); - emitter.on(eventName1, value => { captures.e = value; }); - - // Act: emit events - context.eventEmitter.emit(eventName1, 1); - context.eventEmitter.emit(eventName2, 2); - - // Assert: - expect(emitter.zsocketCount()).to.equal(numExpectedSockets); - expect(emitter.listenerCount(eventName1)).to.equal(3); - expect(emitter.listenerCount(eventName2)).to.equal(2); - - expect(captures).to.deep.equal({ - a: 1, b: 2, c: 1, d: 2, e: 1 - }); - }; - - it('invokes handler only for subscribed channel', () => { - // Assert: - assertOnlySubscribedHandlersAreInvoked('block', 'confirmedAdded', 2); - }); - - it('invokes handler only for subscribed channel or subevent', () => { - // Assert: - assertOnlySubscribedHandlersAreInvoked('block', 'block.close', 1); - }); - - it('registers handler for propagating channel close event', () => { - // Arrange: - const context = {}; - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocketWithCapture(context)); - - // - set up subscriptions to two channels and one subevent - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - - // - register close events - const captures = {}; - emitter.on('block.close', () => { captures.block = true; }); - emitter.on('confirmedAdded.close', () => { captures.confirmedAdded = true; }); - - // Act: simulate close of block zsocket - context.zsockets.block.eventHandlers.zsocket_close[0](); - - // Assert: channel close event should have been raised for block channel only - expect(captures).to.deep.equal({ block: true }); - - // - close has also removed related socket reference and listeners - expect(emitter.zsocketCount()).to.equal(1); - expect(emitter.listenerCount('block')).to.equal(0); - expect(emitter.listenerCount('block.close')).to.equal(0); - expect(emitter.listenerCount('confirmedAdded')).to.equal(2); - - // - close has not closed the socket because it is assumed to have been closed prior to the event - expect(context.zsockets.block.numCloseCalls).to.equal(0); - expect(context.zsockets.confirmedAdded.numCloseCalls).to.equal(0); - }); - }); - - describe('removeAllListeners', () => { - it('has no effect when no matching subscribers are present', () => { - // Arrange: - const context = {}; - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocketWithCapture(context)); - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - - // Act: - emitter.removeAllListeners('unconfirmedAdded'); - - // Assert: - expect(emitter.zsocketCount()).to.equal(2); - expect(emitter.listenerCount('block')).to.equal(2); - expect(emitter.listenerCount('confirmedAdded')).to.equal(2); - - expect(context.zsockets.block.numCloseCalls).to.equal(0); - expect(context.zsockets.confirmedAdded.numCloseCalls).to.equal(0); - }); - - it('removes all matching channel subscribers', () => { - // Arrange: - const context = {}; - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocketWithCapture(context)); - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - - // Act: - emitter.removeAllListeners('block'); - - // Assert: - expect(emitter.zsocketCount()).to.equal(1); - expect(emitter.listenerCount('block')).to.equal(0); - expect(emitter.listenerCount('confirmedAdded')).to.equal(2); - - expect(context.zsockets.block.numCloseCalls).to.equal(1); - expect(context.zsockets.confirmedAdded.numCloseCalls).to.equal(0); - }); - - it('removes all matching and subevent subscribers', () => { - // Arrange: - const context = {}; - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocketWithCapture(context)); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - - // Act: - emitter.removeAllListeners('block'); - - // Assert: - expect(emitter.zsocketCount()).to.equal(1); - expect(emitter.listenerCount('block')).to.equal(0); - expect(emitter.listenerCount('block.close')).to.equal(0); - expect(emitter.listenerCount('confirmedAdded')).to.equal(2); - - expect(context.zsockets.block.numCloseCalls).to.equal(1); - expect(context.zsockets.confirmedAdded.numCloseCalls).to.equal(0); - }); - - it('fails when attempting to remove listeners for any subevent', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - - // Act + Assert: removal attempts for both supported and unsupported subevents should fail because there is no reason - // to remove subevent subscriptions while remaining subscribed to the associated channel - expect(() => emitter.removeAllListeners('block.close').to.throw('block.close must be a channel')); - expect(() => emitter.removeAllListeners('block.foo').to.throw('block.foo must be a channel')); - }); - - it('allows new subscriptions for removed channels', () => { - // Arrange: - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocket); - emitter.on('block', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - - // Act: - emitter.removeAllListeners('block'); - emitter.on('block', () => {}); - - // Assert: - expect(emitter.zsocketCount()).to.equal(2); - expect(emitter.listenerCount('block')).to.equal(1); - expect(emitter.listenerCount('block.close')).to.equal(0); - expect(emitter.listenerCount('confirmedAdded')).to.equal(2); - }); - }); - - describe('close', () => { - it('removes all channel and subevent subscribers', () => { - // Arrange: - const context = {}; - const emitter = zmqUtils.createMultisocketEmitter(createMockZsocketWithCapture(context)); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - emitter.on('block', () => {}); - emitter.on('block.close', () => {}); - emitter.on('confirmedAdded', () => {}); - - // Act: - emitter.close(); - - // Assert: - expect(emitter.zsocketCount()).to.equal(0); - expect(emitter.listenerCount('block')).to.equal(0); - expect(emitter.listenerCount('block.close')).to.equal(0); - expect(emitter.listenerCount('confirmedAdded')).to.equal(0); - - expect(context.zsockets.block.numCloseCalls).to.equal(1); - expect(context.zsockets.confirmedAdded.numCloseCalls).to.equal(1); - }); - }); - }); -}); diff --git a/rest/test/db/CatapultDb_spec.js b/rest/test/db/CatapultDb_spec.js deleted file mode 100644 index 10a2f3821..000000000 --- a/rest/test/db/CatapultDb_spec.js +++ /dev/null @@ -1,2703 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const test = require('./utils/dbTestUtils'); -const testDbOptions = require('./utils/testDbOptions'); -const CatapultDb = require('../../src/db/CatapultDb'); -const { uniqueLongList } = require('../../src/db/dbUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { address, EntityType } = catapult.model; - -const { Long, Binary } = MongoDb; -const Testnet_Network = testDbOptions.networkId; -const Default_Height = 34567; - -const DefaultPagingOptions = { - pageSizeMin: 10, - pageSizeMax: 100, - pageSizeDefault: 20 -}; - -const TransactionGroups = { - confirmed: 'confirmed', - unconfirmed: 'unconfirmed', - partial: 'partial' -}; - -describe('catapult db', () => { - const deleteIds = dbEntities => { - test.collection.names.forEach(collectionName => { - const seed = test.collection.findInEntities(dbEntities, collectionName); - test.db.sanitizeDbEntities(collectionName, seed); - }); - }; - - const renameId = dbObject => { - if (dbObject) { - dbObject.id = dbObject._id; - delete dbObject._id; - } - - return dbObject; - }; - - const keyToAddress = key => Buffer.from(address.publicKeyToAddress(key, Testnet_Network)); - - const runDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => { - // Arrange: - const db = new CatapultDb(Object.assign({ networkId: Testnet_Network }, DefaultPagingOptions)); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test', testDbOptions.connectionPoolSize) - .then(() => test.db.populateDatabase(db, dbEntities)) - .then(() => deleteIds(dbEntities)) - .then(() => issueDbCommand(db)) - .then(assertDbCommandResult) - .then(() => db.close()); - }; - - const assertEqualDocuments = (expectedDocuments, actualDocuments) => { - const stripPrivateInformation = transactions => transactions.map(transaction => { - // addresses metadata is not exposed outside of the database class - const modifiedTransaction = Object.assign({}, transaction); - delete modifiedTransaction.meta.addresses; - return modifiedTransaction; - }); - - const getAttributes = documents => { - const documentToIdString = document => (document ? document.id.toString() : undefined); - const subTxIds = documents.map(document => (document.transaction.transactions || []).map(documentToIdString)); - return { - numDocuments: documents.length, - ids: documents.map(documentToIdString), - numSubTxes: subTxIds.reduce((sum, ids) => sum + ids.length, 0), - subTxIds - }; - }; - - // clean transaction data - const sanitizedExpectedDocuments = expectedDocuments[0] && expectedDocuments[0].transaction - ? stripPrivateInformation(expectedDocuments) - : expectedDocuments; - - const expectedAttributes = getAttributes(sanitizedExpectedDocuments); - const actualAttributes = getAttributes(actualDocuments); - - // Assert: - expect(actualAttributes.numDocuments, 'wrong number of documents').to.equal(expectedAttributes.numDocuments); - expect(actualAttributes.ids, 'wrong ids').to.deep.equal(expectedAttributes.ids); - expect(actualAttributes.numSubTxes, 'wrong number of sub documents').to.equal(expectedAttributes.numSubTxes); - expect(actualAttributes.subTxIds, 'wrong sub document ids').to.deep.equal(expectedAttributes.subTxIds); - expect(actualDocuments).to.deep.equal(expectedDocuments); - }; - - describe('basic', () => { - it('cannot create db without network id', () => { - // Act + Assert: - expect(() => new CatapultDb({})).to.throw('network id is required'); - }); - - it('can close unconnected db', () => { - // Arrange: - const db = new CatapultDb({ networkId: Testnet_Network }); - - // Act + Assert: no exception - expect(() => db.close()).to.not.throw(); - }); - }); - - describe('storage info', () => { - it('can retrieve storage info', () => { - const Rounds = 2; - - // Arrange: - return runDbTest( - { - block: test.db.createDbBlock(Default_Height), - transactions: test.db.createDbTransactions(Rounds, test.random.publicKey(), test.random.address()) - }, - db => db.storageInfo(), - storageInfo => expect(storageInfo).to.deep.equal({ numBlocks: 1, numTransactions: Rounds * 8, numAccounts: 0 }) - ); - }); - }); - - describe('chain info', () => { - it('can retrieve chain info', () => - // Assert: - runDbTest( - { chainStatistic: test.db.createChainStatistic(1357, 2468, 3579) }, - db => db.chainStatisticCurrent(), - chainStatistic => expect(chainStatistic).to.deep.equal(test.db.createChainStatistic(1357, 2468, 3579).current) - )); - }); - - describe('latest finalized block', () => { - const createFinalizationBlock = height => ({ - block: { - height: Long.fromNumber(height), - hash: new Binary(test.random.hash()), - finalizationEpoch: 777, - finalizationPoint: 888 - } - }); - - it('can retrieve latest finalized block info', () => { - const finalizedBlocks = [ - createFinalizationBlock(5), - createFinalizationBlock(8), - createFinalizationBlock(2) - ]; - return runDbTest( - { finalizedBlocks }, - db => db.latestFinalizedBlock(), - latestfinalizedBlock => expect(latestfinalizedBlock).to.deep.equal(finalizedBlocks[1]) - ); - }); - }); - - const stripBlockFields = (block, fields) => { - // block merkle trees are not exposed outside of the database class unless explicitly requested - const modifiedBlock = Object.assign({}, block); - fields.forEach(field => delete modifiedBlock.meta[field]); - return modifiedBlock; - }; - - const stripExtraneousBlockInformation = block => stripBlockFields(block, ['transactionMerkleTree', 'statementMerkleTree']); - - describe('blocks', () => { - const account1 = { - publicKey: test.random.publicKey(), - address: test.random.address() - }; - const account2 = { - publicKey: test.random.publicKey(), - address: test.random.address() - }; - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: '_id', - sortDirection: -1 - }; - - const { createObjectId } = test.db; - - const createBlock = (objectId, height, signerPublicKey, beneficiaryAddress) => ({ - _id: createObjectId(objectId), - meta: {}, - block: { - height, - signerPublicKey: signerPublicKey ? Buffer.from(signerPublicKey) : undefined, - beneficiaryAddress: beneficiaryAddress ? Buffer.from(beneficiaryAddress) : undefined - } - }); - - const runTestAndVerifyIds = (dbBlocks, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runDbTest( - { blocks: dbBlocks }, - dbQuery, - blocksPage => { - const returnedIds = blocksPage.data.map(t => t.id); - expect(blocksPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbBlocks = [ - createBlock(10, 100, account1.publicKey, account2.address) - ]; - - // Act + Assert: - return runDbTest( - { blocks: dbBlocks }, - db => db.blocks(undefined, undefined, paginationOptions), - page => { - const expected_keys = ['id', 'meta', 'block']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns correct blocks when no filters are provided', () => { - // Arrange: - const dbBlocks = [ - createBlock(10, 1), - createBlock(20, 1, account1.publicKey), - createBlock(30, 1, account1.publicKey, account2.address) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbBlocks, db => db.blocks(undefined, undefined, paginationOptions), [10, 20, 30]); - }); - - it('all the provided filters are taken into account', () => { - // Arrange: - const dbBlocks = [ - createBlock(10, 1), - createBlock(20, 1, account1.publicKey), - createBlock(30, 1, account1.publicKey, account2.address) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbBlocks, db => db.blocks(account1.publicKey, account2.address, paginationOptions), [30]); - }); - - describe('respects offset', () => { - // Arrange: - const dbBlocks = () => [ - createBlock(10, 20), - createBlock(20, 30), - createBlock(30, 10) - ]; - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbBlocks(), db => db.blocks(undefined, undefined, options), [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbBlocks(), db => db.blocks(undefined, undefined, options), [10]); - }); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbBlocks = () => [ - createBlock(10, 20), - createBlock(20, 30), - createBlock(30, 10) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runDbTest( - { blocks: dbBlocks() }, - db => db.blocks(undefined, undefined, options), - blocksPage => { - expect(blocksPage.data[0].id).to.deep.equal(createObjectId(10)); - expect(blocksPage.data[1].id).to.deep.equal(createObjectId(20)); - expect(blocksPage.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runDbTest( - { blocks: dbBlocks() }, - db => db.blocks(undefined, undefined, options), - blocksPage => { - expect(blocksPage.data[0].id).to.deep.equal(createObjectId(30)); - expect(blocksPage.data[1].id).to.deep.equal(createObjectId(20)); - expect(blocksPage.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'height', - sortDirection: 1 - }; - - // Act + Assert: - return runDbTest( - { blocks: dbBlocks() }, - db => db.blocks(undefined, undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('block.height'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('correctly applies each filter:', () => { - it('signerPublicKey', () => { - // Arrange: - const dbBlocks = [ - createBlock(10, 1, account1.publicKey), - createBlock(20, 1, account2.publicKey) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbBlocks, db => db.blocks(account1.publicKey, undefined, paginationOptions), [10]); - }); - - it('beneficiaryAddress', () => { - // Arrange: - const dbBlocks = [ - createBlock(10, 1, account1.publicKey, account1.address), - createBlock(20, 1, account1.publicKey, account2.address) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbBlocks, db => db.blocks(undefined, account1.address, paginationOptions), [10]); - }); - }); - }); - const runBlockAtHeightDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => { - const db = new CatapultDb(Object.assign({ networkId: Testnet_Network }, DefaultPagingOptions)); - return db.connect(testDbOptions.url, 'test', testDbOptions.connectionPoolSize) - .then(() => test.db.populateDatabase(db, dbEntities)) - .then(() => issueDbCommand(db)) - .then(assertDbCommandResult) - .then(() => db.close()); - }; - describe('block at height', () => { - it('undefined is returned for block at unknown height', () => - // Assert: - runDbTest( - { block: test.db.createDbBlock(Default_Height) }, - db => db.blockAtHeight(Long.fromNumber(Default_Height + 1)), - block => expect(block).to.equal(undefined) - )); - - // use blockAtHeight tests as a proxy for testing support of different numeric types (Number, uint64, Long) - - const assertCanRetrieveSimpleBlock = height => { - // Arrange: - const seedBlock = test.db.createDbBlock(Default_Height); - - // Assert: - return runBlockAtHeightDbTest( - { blocks: seedBlock }, - db => db.blockAtHeight(height), - block => expect(block).to.deep.equal(stripExtraneousBlockInformation(renameId(seedBlock))) - ); - }; - - it('can retrieve block without transactions at height (Number)', () => assertCanRetrieveSimpleBlock(Default_Height)); - it('can retrieve block without transactions at height (uint64)', () => assertCanRetrieveSimpleBlock([Default_Height, 0])); - it('can retrieve block without transactions at height (Long)', () => assertCanRetrieveSimpleBlock(Long.fromNumber(Default_Height))); - - it('can retrieve block with transactions at height', () => { - // Arrange: - const seedBlock = test.db.createDbBlock(Default_Height); - const blockTransactions = test.db.createDbTransactions(2, test.random.publicKey(), test.random.address()); - - // Assert: - return runBlockAtHeightDbTest( - { blocks: seedBlock, transactions: blockTransactions }, - db => db.blockAtHeight(Long.fromNumber(Default_Height)), - block => expect(block).to.deep.equal(stripExtraneousBlockInformation(renameId(seedBlock))) - ); - }); - }); - - describe('blocks at heights', () => { - it('can retrieve empty blocks when no heights', () => { - // Arrange: - const seedBlock1 = test.db.createDbBlock(Default_Height); - const blockTransactions = test.db.createDbTransactions(2, test.random.publicKey(), test.random.address()); - - // Assert: - return runBlockAtHeightDbTest( - { blocks: [seedBlock1], transactions: blockTransactions }, - db => db.blocksAtHeights( - [] - ), - blocks => expect(blocks).to.deep.equal( - [] - ) - ); - }); - - it('can retrieve blocks with transactions at heights', () => { - // Arrange: - const seedBlock1 = test.db.createDbBlock(Default_Height); - const seedBlock2 = test.db.createDbBlock(Default_Height + 1); - const seedBlock3 = test.db.createDbBlock(Default_Height + 2); - const blockTransactions = test.db.createDbTransactions(2, test.random.publicKey(), test.random.address()); - - // Assert: - return runBlockAtHeightDbTest( - { blocks: [seedBlock1, seedBlock2, seedBlock3], transactions: blockTransactions }, - db => db.blocksAtHeights( - [Long.fromNumber(Default_Height), Long.fromNumber(Default_Height + 1)] - ), - blocks => expect(blocks).to.deep.equal( - [stripExtraneousBlockInformation(renameId(seedBlock1)), stripExtraneousBlockInformation(renameId(seedBlock2))] - ) - ); - }); - - it('can retrieve blocks with transactions at heights with projection', () => { - // Arrange: - const seedBlock1 = test.db.createDbBlock(Default_Height); - const seedBlock2 = test.db.createDbBlock(Default_Height + 1); - const seedBlock3 = test.db.createDbBlock(Default_Height + 2); - const blockTransactions = test.db.createDbTransactions(2, test.random.publicKey(), test.random.address()); - - // Assert: - const projectBlock = block => ({ - id: block._id, - block: { - height: block.block.height, - timestamp: block.block.timestamp, - feeMultiplier: block.block.feeMultiplier - } - }); - return runBlockAtHeightDbTest( - { blocks: [seedBlock1, seedBlock2, seedBlock3], transactions: blockTransactions }, - db => db.blocksAtHeights( - [Long.fromNumber(Default_Height), Long.fromNumber(Default_Height + 1)], - { 'block.timestamp': 1, 'block.height': 1, 'block.feeMultiplier': 1 } - ), - blocks => expect(blocks).to.deep.equal( - [projectBlock(seedBlock1), projectBlock(seedBlock2)] - ) - ); - }); - }); - - describe('block at height with statement merkle tree', () => { - it('undefined is returned for block at unknown height', () => - // Assert: - runDbTest( - { block: test.db.createDbBlock(Default_Height) }, - db => db.blockWithMerkleTreeAtHeight(Long.fromNumber(Default_Height + 1), 'statementMerkleTree'), - block => expect(block).to.equal(undefined) - )); - - // use blockAtHeight tests as a proxy for testing support of different numeric types (Number, uint64, Long) - - const assertCanRetrieveSimpleBlock = height => { - // Arrange: - const seedBlock = test.db.createDbBlock(Default_Height); - - // Assert: - return runDbTest( - { block: seedBlock }, - db => db.blockWithMerkleTreeAtHeight(height, 'statementMerkleTree'), - block => expect(block).to.deep.equal(stripBlockFields(seedBlock, ['transactionMerkleTree'])) - ); - }; - - it('can retrieve block with statement merkle tree at height (Number)', () => assertCanRetrieveSimpleBlock(Default_Height)); - it('can retrieve block with statement merkle tree at height (uint64)', () => assertCanRetrieveSimpleBlock([Default_Height, 0])); - it('can retrieve block with statement merkle tree at height (Long)', () => - assertCanRetrieveSimpleBlock(Long.fromNumber(Default_Height))); - - it('can retrieve block with statement merkle tree at height', () => { - // Arrange: - const seedBlock = test.db.createDbBlock(Default_Height); - const blockTransactions = test.db.createDbTransactions(2, test.random.publicKey(), test.random.address()); - - // Assert: - return runDbTest( - { block: seedBlock, transactions: blockTransactions }, - db => db.blockWithMerkleTreeAtHeight(Long.fromNumber(Default_Height), 'statementMerkleTree'), - block => expect(block).to.deep.equal(stripBlockFields(seedBlock, ['transactionMerkleTree'])) - ); - }); - }); - - describe('block at height with transaction merkle tree', () => { - it('undefined is returned for block at unknown height', () => - // Assert: - runDbTest( - { block: test.db.createDbBlock(Default_Height) }, - db => db.blockWithMerkleTreeAtHeight(Long.fromNumber(Default_Height + 1), 'transactionMerkleTree'), - block => expect(block).to.equal(undefined) - )); - - // use blockAtHeight tests as a proxy for testing support of different numeric types (Number, uint64, Long) - - const assertCanRetrieveSimpleBlock = height => { - // Arrange: - const seedBlock = test.db.createDbBlock(Default_Height); - - // Assert: - return runDbTest( - { block: seedBlock }, - db => db.blockWithMerkleTreeAtHeight(height, 'transactionMerkleTree'), - block => expect(block).to.deep.equal(stripBlockFields(seedBlock, ['statementMerkleTree'])) - ); - }; - - it('can retrieve block with transaction merkle tree at height (Number)', () => assertCanRetrieveSimpleBlock(Default_Height)); - it('can retrieve block with transaction merkle tree at height (uint64)', () => assertCanRetrieveSimpleBlock([Default_Height, 0])); - it('can retrieve block with transaction merkle tree at height (Long)', () => - assertCanRetrieveSimpleBlock(Long.fromNumber(Default_Height))); - - it('can retrieve block with transaction merkle tree at height', () => { - // Arrange: - const seedBlock = test.db.createDbBlock(Default_Height); - const blockTransactions = test.db.createDbTransactions(2, test.random.publicKey(), test.random.address()); - - // Assert: - return runDbTest( - { block: seedBlock, transactions: blockTransactions }, - db => db.blockWithMerkleTreeAtHeight(Long.fromNumber(Default_Height), 'transactionMerkleTree'), - block => expect(block).to.deep.equal(stripBlockFields(seedBlock, ['statementMerkleTree'])) - ); - }); - }); - - describe('latest blocks fee multiplier', () => { - it('returns empty array when requesting 0 blocks', () => { - // Arrange: - const blockDbEntities = [ - { block: { height: 10, feeMultiplier: 10 } }, - { block: { height: 11, feeMultiplier: 11 } } - ]; - - // Act + Assert: - return runDbTest( - { blocks: blockDbEntities }, - db => db.latestBlocksFeeMultiplier(0), - feeMultipliers => { - expect(feeMultipliers).to.deep.equal([]); - } - ); - }); - - it('returns latest available blocks based on height', () => { - // Arrange: - const blockDbEntities = [ - { block: { height: 12, feeMultiplier: 12 } }, - { block: { height: 15, feeMultiplier: 15 } }, - { block: { height: 10, feeMultiplier: 10 } }, - { block: { height: 14, feeMultiplier: 14 } }, - { block: { height: 11, feeMultiplier: 11 } }, - { block: { height: 13, feeMultiplier: 13 } } - ]; - - // Act + Assert: - return runDbTest( - { blocks: blockDbEntities }, - db => db.latestBlocksFeeMultiplier(5), - feeMultipliers => { - expect(feeMultipliers).to.deep.equal([15, 14, 13, 12, 11]); - } - ); - }); - - it('respects requested number of blocks', () => { - // Arrange: - const blockDbEntities = [ - { block: { height: 10, feeMultiplier: 1 } }, - { block: { height: 11, feeMultiplier: 1 } }, - { block: { height: 12, feeMultiplier: 1 } }, - { block: { height: 13, feeMultiplier: 1 } }, - { block: { height: 14, feeMultiplier: 1 } } - ]; - - // Act + Assert: - return runDbTest( - { blocks: blockDbEntities }, - db => db.latestBlocksFeeMultiplier(3), - feeMultipliers => { - expect(feeMultipliers.length).to.equal(3); - } - ); - }); - - it('returns only fee multiplier values', () => { - // Arrange: - const blockDbEntities = [ - { - meta: { hash: 'h1' }, - block: { - network: 144, - type: 33091, - height: 11, - feeMultiplier: 11.1 - } - }, - { - meta: { hash: 'h2' }, - block: { - network: 144, - type: 33091, - height: 10, - feeMultiplier: 10.1 - } - } - ]; - - // Act + Assert: - return runDbTest( - { blocks: blockDbEntities }, - db => db.latestBlocksFeeMultiplier(5), - feeMultipliers => { - expect(feeMultipliers).to.deep.equal([11.1, 10.1]); - } - ); - }); - }); - - const createTransactionHash = id => catapult.utils.convert.hexToUint8(`${'00'.repeat(16)}${id.toString(16)}`.slice(-32)); - - const createSeedTransactions = (numTransactionsPerHeight, heights, options) => { - // notice that generated transactions only contain what was used by transactionsAtHeight for filtering (meta.height) - let id = 1; - const transactions = []; - const addTransactionAtHeight = (height, type) => { - const aggregateId = test.db.createObjectId(id); - const hash = new Binary(Buffer.from(createTransactionHash(id++))); - const meta = { height: Long.fromNumber(height), hash, addresses: [] }; - transactions.push({ _id: aggregateId, meta, transaction: { type } }); - - const numDependentDocuments = (options || {}).numDependentDocuments || 0; - for (let j = 0; j < numDependentDocuments; ++j) { - transactions.push({ - _id: test.db.createObjectId(id++), - meta: { height: Long.fromNumber(height), aggregateId }, - transaction: {} - }); - } - }; - - for (let i = 0; i < numTransactionsPerHeight; ++i) { - // transactionsAtHeight only worked for both aggregates, so pick each type alternatively - const type = 0 === i % 2 ? EntityType.aggregateComplete : EntityType.aggregateBonded; - heights.forEach(height => { addTransactionAtHeight(height, type); }); - } - - return transactions; - }; - - /** - * It creates the blocks for the given transactions. - * - * @param {object[]} transactions the transactions to know the required blocks - * @returns {object[]} the block of the transactions to be stored - */ - const createBlocks = transactions => { - // notice that generated transactions only contain what was used by transactionsAtHeight for filtering (meta.height) - const heights = transactions.map(transaction => transaction.meta.height).map(Long.fromNumber); - return uniqueLongList(heights).map(height => test.db.createDbBlock(height)); - }; - - /** - * It copies the transactions adding the blocks meta. - * - * @param {object[]} transactions the transactions without the blocks' meta. - * @param {object[]} blocks the blocks of the transactions. - * @returns {object[]} the transactions with the blocks' meta like the db would return after joining the results. - */ - const addBlockMeta = (transactions, blocks) => transactions.map(transaction => { - const { height } = transaction.meta; - const blockEntity = blocks.find(storedBlock => '0' !== height.toString() && storedBlock.block.height.equals(height)); - if (!blockEntity) - return transaction; - - return { - ...transaction, - meta: { - ...transaction.meta, - timestamp: blockEntity.block.timestamp, - feeMultiplier: blockEntity.block.feeMultiplier - } - }; - }); - - describe('transaction by id', () => { - const runTransactionsDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => { - // Arrange: - const db = new CatapultDb(Object.assign({ networkId: Testnet_Network }, DefaultPagingOptions)); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test', testDbOptions.connectionPoolSize) - .then(() => test.db.populateDatabase(db, dbEntities)) - .then(() => issueDbCommand(db)) - .then(assertDbCommandResult) - .then(() => db.close()); - }; - - const addTestsWithId = (traits, idTraits) => { - it('can retrieve each transaction by id', () => { - // Arrange: - const seedTransactions = traits.createSeedTransactions(); - const blocks = createBlocks(seedTransactions); - const transactionsWithBlockMeta = addBlockMeta(seedTransactions, blocks); - const allIds = traits.allIds.map(idTraits.convertToId); - - // Act + Assert: - return runTransactionsDbTest( - { [idTraits.collectionName]: seedTransactions, blocks }, - db => idTraits.transactionsByIds(db, allIds), - transactions => assertEqualDocuments(traits.expected(transactionsWithBlockMeta, traits.allIds), transactions) - ); - }); - - it('can retrieve transaction using known id', () => { - // Arrange: - const seedTransactions = traits.createSeedTransactions(); - const blocks = createBlocks(seedTransactions); - const transactionsWithBlockMeta = addBlockMeta(seedTransactions, blocks); - const documentId = idTraits.convertToId(traits.validId); - - // Act + Assert: - return runTransactionsDbTest( - { [idTraits.collectionName]: seedTransactions, blocks }, - db => idTraits.transactionsByIds(db, [documentId]), - transactions => assertEqualDocuments(traits.expected(transactionsWithBlockMeta, [traits.validId]), transactions) - ); - }); - - it('cannot retrieve transaction using unknown id', () => { - // Arrange: - const seedTransactions = traits.createSeedTransactions(); - const blocks = createBlocks(seedTransactions); - const documentId = idTraits.convertToId(traits.invalidId); - - // Act + Assert: - return runTransactionsDbTest( - { [idTraits.collectionName]: seedTransactions, blocks }, - db => idTraits.transactionsByIds(db, [documentId]), - transactions => expect(transactions).to.deep.equal([]) - ); - }); - - it('can retrieve only known transactions by id', () => { - // Arrange: - const seedTransactions = traits.createSeedTransactions(); - const blocks = createBlocks(seedTransactions); - const transactionsWithBlockMeta = addBlockMeta(seedTransactions, blocks); - const allIds = traits.allIds.map(idTraits.convertToId); - // make a copy and insert invalid id in the middle - const mixedIds = allIds.slice(); - mixedIds.splice(mixedIds.length / 2, 0, idTraits.convertToId(traits.invalidId)); - - // Act + Assert: - return runTransactionsDbTest( - { [idTraits.collectionName]: seedTransactions, blocks }, - db => idTraits.transactionsByIds(db, mixedIds), - transactions => assertEqualDocuments(traits.expected(transactionsWithBlockMeta, traits.allIds), transactions) - ); - }); - }; - - const addTests = traits => { - describe('by object id', () => - addTestsWithId(traits, { - convertToId: test.db.createObjectId, - collectionName: 'transactions', - transactionsByIds: (db, ids) => db.transactionsByIds(TransactionGroups.confirmed, ids) - })); - - describe('by transaction hash', () => - addTestsWithId(traits, { - convertToId: createTransactionHash, - collectionName: 'transactions', - transactionsByIds: (db, ids) => db.transactionsByHashes(TransactionGroups.confirmed, ids) - })); - - describe('by transaction hash (unconfirmed)', () => - addTestsWithId(traits, { - convertToId: createTransactionHash, - collectionName: 'unconfirmedTransactions', - transactionsByIds: (db, ids) => db.transactionsByHashes(TransactionGroups.unconfirmed, ids) - })); - - describe('by transaction hash (partial)', () => - addTestsWithId(traits, { - convertToId: createTransactionHash, - collectionName: 'partialTransactions', - transactionsByIds: (db, ids) => db.transactionsByHashes(TransactionGroups.partial, ids) - })); - }; - - describe('for transactions', () => { - addTests({ - createSeedTransactions: () => createSeedTransactions(3, [21, 34]), - expected: (transactions, ids) => ids.map(id => transactions[id - 1]).map(renameId), - allIds: [1, 2, 3, 4, 5, 6], - validId: 2, - invalidId: (3 * 2) + 1 - }); - }); - - describe('for transactions with dependent documents', () => { - addTests({ - // 1 (2, 3) (height 21) - // 4 (5, 6) (height 34) - // 7 (8, 9) (height 21) - // ... - createSeedTransactions: () => createSeedTransactions(3, [21, 34], { numDependentDocuments: 2 }), - expected: (transactions, ids) => ids.map(id => { - const index = id - 1; - const stitchedAggregate = Object.assign({}, transactions[index]); - stitchedAggregate.transaction.transactions = [transactions[index + 1], transactions[index + 2]].map(renameId); - return stitchedAggregate; - }).map(renameId), - allIds: [1, 4, 7, 10, 13, 16], - // transaction with id 4 is an aggregate - validId: 4, - invalidId: (3 * 3 * 2) + 1 - }); - }); - - describe('for a dependent document', () => { - it('can retrieve dependent document by id', () => { - // Arrange: - // transaction with id 5 is a dependent document - // 1 (2, 3) (height 21) - // 4 (5, 6) (height 34) - // ... - const seedTransactions = createSeedTransactions(3, [21, 34], { numDependentDocuments: 2 }); - const blocks = createBlocks(seedTransactions); - const transactionsWithBlockMeta = addBlockMeta(seedTransactions, blocks); - const documentId = test.db.createObjectId(5); - - // Act + Assert: - return runTransactionsDbTest( - { transactions: seedTransactions, blocks }, - db => db.transactionsByIds(TransactionGroups.confirmed, [documentId]), - transactions => assertEqualDocuments([renameId(transactionsWithBlockMeta[4])], transactions) - ); - }); - }); - - describe('translates group to collection name', () => { - const validObjectId = test.db.createObjectId(10); - const validHash = '112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00'; - - const runTransactionsByIdTest = (dbCall, param, group, collection) => { - it(group, () => { - // Arrange: - const transactionsByIdsImplStub = sinon.stub(CatapultDb.prototype, 'transactionsByIdsImpl').returns(''); - const db = new CatapultDb(Object.assign({ networkId: Testnet_Network }, DefaultPagingOptions)); - - // Act - db[dbCall](group, [param]); - - // Assert - expect(transactionsByIdsImplStub.calledOnce).to.equal(true); - expect(transactionsByIdsImplStub.firstCall.args[0]).to.equal(collection); - transactionsByIdsImplStub.restore(); - }); - }; - - const groupToCollectionName = { - confirmed: 'transactions', - unconfirmed: 'unconfirmedTransactions', - partial: 'partialTransactions' - }; - - describe('transactions by ids', () => { - Object.keys(groupToCollectionName).forEach(group => { - runTransactionsByIdTest('transactionsByIds', validObjectId, group, groupToCollectionName[group]); - }); - }); - describe('transactions by hashes', () => { - Object.keys(groupToCollectionName).forEach(group => { - runTransactionsByIdTest('transactionsByHashes', validHash, group, groupToCollectionName[group]); - }); - }); - }); - }); - - describe('names by ids', () => { - const createDbMarkedTransaction = (id, parentId, markerId) => { - // meta data - const meta = {}; - - // transaction data - const transaction = { - type: 0x12345, - parentMarkerId: Long.fromNumber(parentId), - markerId: Long.fromNumber(markerId), - markerName: `marker-${markerId}` - }; - - return { _id: id, meta, transaction }; - }; - - const createDbMarkedTransactions = (numTransactions, numRepetitions) => { - const transactions = []; - let id = 0; - // create multiple (numRepetitions) transactions with same markerId, but different _id field. - for (let i = 0; i < numRepetitions; ++i) { - for (let j = 0; j < numTransactions; ++j) - transactions.push(createDbMarkedTransaction(test.db.createObjectId(++id), 15000 + j, 20000 + j)); - } - - return transactions; - }; - - const createDbEntities = () => ({ transactions: createDbMarkedTransactions(12, 3) }); - - const assertTransactions = (expectedTransactions, ids) => runDbTest( - // Arrange: seed with transactions with markerIds: 20000 - 20011 - createDbEntities(), - db => db.findNamesByIds(ids, 0x12345, { id: 'markerId', name: 'markerName', parentId: 'parentMarkerId' }), - transactions => { - // Assert: - expect(transactions.length).to.equal(expectedTransactions.length); - expect(transactions).to.deep.equal(expectedTransactions); - } - ); - - const createExpected = (parentId, markerId) => ({ - markerId: Long.fromNumber(markerId), - markerName: `marker-${markerId}`, - parentMarkerId: Long.fromNumber(parentId) - }); - - it('returns empty array for unknown ids', () => - // Act + Assert: query for markerId outside seed range - assertTransactions([], [[123, 456]])); - - it('returns single matching entry', () => { - // Act + Assert: query for markerId in seed range (20000-20011) - // note: there are multiple transactions with same markerId, so this also checks that only non-duplicates are returned - const expected = [createExpected(15010, 20010)]; - - return assertTransactions(expected, [[20010, 0]]); - }); - - it('returns multiple matching entries', () => { - // Act + Assert: query for markerIds in seed range (20000-20011) - // note: there are multiple transactions with same markerId, so this also checks that only non-duplicates are returned - const expected = [createExpected(15008, 20008), createExpected(15005, 20005), createExpected(15003, 20003)]; - - return assertTransactions(expected, [[20003, 0], [20005, 0], [20008, 0]]); - }); - - it('returns only matching entries', () => { - // Act + Assert: query for markerId in seed range (20000-20011) and one outside of range - // note: there are multiple transactions with same markerId, so this also checks that only non-duplicates are returned - const expected = [createExpected(15008, 20008), createExpected(15003, 20003)]; - - return assertTransactions(expected, [[20003, 0], [123, 456], [20008, 0]]); - }); - - it('does not promote MongoDb.Long to regular `number` for small enough numbers and ends up returning Long always', () => { - const dbEntity = { - transactions: [{ - _id: test.db.createObjectId(55), - meta: {}, - transaction: { id: Long.fromNumber(23), type: 0x12345, parentId: Long.fromNumber(10) } - }] - }; - return runDbTest( - dbEntity, - db => db.findNamesByIds([23], 0x12345, { id: 'id', name: 'name', parentId: 'parentId' }), - tuples => { - expect(tuples[0].parentId instanceof Long).to.be.equal(true); - } - ); - }); - }); - - describe('query paged documents', () => { - const account1 = { - publicKey: test.random.publicKey(), - address: keyToAddress(test.random.publicKey()) - }; - const account2 = { - publicKey: test.random.publicKey(), - address: keyToAddress(test.random.publicKey()) - }; - const { createObjectId } = test.db; - const sortConditions = { _id: 1 }; - const options = { pageSize: 10, pageNumber: 1 }; - - describe('can return empty result', () => { - it('empty db', () => { - // Arrange - const conditions = {}; - - // Act + Assert: - return runDbTest( - {}, - db => db.queryPagedDocuments(conditions, [], sortConditions, 'accounts', options), - page => { - expect(page.data).to.deep.equal([]); - expect(page.pagination).to.deep.equal({ pageNumber: 1, pageSize: options.pageSize }); - } - ); - }); - - it('conditions produces empty result', () => { - // Arrange - const dbAccounts = () => [ - { _id: createObjectId(10), account: { addressHeight: 10 } }, - { _id: createObjectId(30), account: { addressHeight: 30 } } - ]; - const conditions = { 'account.addressHeight': 20 }; - - // Act + Assert: - return runDbTest( - { accounts: dbAccounts() }, - db => db.queryPagedDocuments(conditions, [], sortConditions, 'accounts', options), - page => { - expect(page.data).to.deep.equal([]); - expect(page.pagination).to.deep.equal({ pageNumber: 1, pageSize: options.pageSize }); - } - ); - }); - }); - - describe('respects query conditions', () => { - // Arrange: - const accounts = () => ([ - { _id: createObjectId(10), account: { address: account1.address, addressHeight: 10 } }, - { _id: createObjectId(20), account: { address: account2.address, addressHeight: 20 } }, - { _id: createObjectId(30), account: { address: account2.address, addressHeight: 30 } } - ]); - - it('no conditions', () => { - const conditions = {}; - - // Act + Assert: - return runDbTest( - { accounts: accounts() }, - db => db.queryPagedDocuments(conditions, [], sortConditions, 'accounts', options), - page => { - expect(page.data.length).to.equal(3); - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('one condition', () => { - const conditions = { 'account.addressHeight': 20 }; - - // Act + Assert: - return runDbTest( - { accounts: accounts() }, - db => db.queryPagedDocuments(conditions, [], sortConditions, 'accounts', options), - page => { - expect(page.data.length).to.equal(1); - expect(page.data[0].id).to.deep.equal(createObjectId(20)); - } - ); - }); - - it('multiple conditions', () => { - const conditions = { - 'account.address': account2.address, - 'account.addressHeight': { $gt: 20 } - }; - - // Act + Assert: - return runDbTest( - { accounts: accounts() }, - db => db.queryPagedDocuments(conditions, [], sortConditions, 'accounts', options), - page => { - expect(page.data.length).to.equal(1); - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - } - ); - }); - }); - - describe('renames _id to id', () => { - // Arrange: - const blocks = () => ([ - { - _id: createObjectId(10), - meta: { - hash: 0x0100, - transactionsCount: 10 - }, - block: { - version: 1, - type: 2 - } - } - ]); - - it('id is in the query result and _id is not', () => - // Act + Assert: - runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, [], sortConditions, 'blocks', options), - page => { - expect(page.data[0]._id).to.equal(undefined); - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - } - )); - - it('_id is gone when explicitly removed and id isn\'t present in the result either', () => - // Act + Assert: - runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, ['_id'], sortConditions, 'blocks', options), - page => { - expect(page.data[0]._id).to.equal(undefined); - expect(page.data[0].id).to.equal(undefined); - } - )); - }); - - describe('removed fields', () => { - // Arrange: - const blocks = () => ([ - { - _id: createObjectId(10), - meta: { - hash: 0x0100, - transactionsCount: 10 - }, - block: { - version: 1, - type: 2 - } - } - ]); - - it('does not remove fields if no supplied fields to remove', () => { - const removedFields = []; - - // Act + Assert: - return runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, removedFields, sortConditions, 'blocks', options), - page => { - expect(page.data.length).to.equal(1); - expect(page.data[0]).to.deep.equal({ - id: createObjectId(10), - meta: { hash: 0x0100, transactionsCount: 10 }, - block: { version: 1, type: 2 } - }); - } - ); - }); - - it('removes supplied fields', () => { - const removedFields = ['meta.hash', 'block.version']; - - // Act + Assert: - return runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, removedFields, sortConditions, 'blocks', options), - page => { - expect(page.data.length).to.equal(1); - expect(page.data[0]).to.deep.equal({ - id: createObjectId(10), - meta: { transactionsCount: 10 }, - block: { type: 2 } - }); - } - ); - }); - }); - - describe('respects sort conditions', () => { - // Arrange: - const blocks = () => ([ - { _id: createObjectId(10), meta: { transactionsCount: 1 }, block: { version: 3, type: 2 } }, - { _id: createObjectId(20), meta: { transactionsCount: 2 }, block: { version: 2, type: 1 } }, - { _id: createObjectId(30), meta: { transactionsCount: 3 }, block: { version: 1, type: 3 } } - ]); - - it('direction ascending', () => - // Act + Assert: - runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, [], { _id: 1 }, 'blocks', options), - page => { - expect(page.data.length).to.equal(3); - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - )); - - it('direction descending', () => - // Act + Assert: - runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, [], { _id: -1 }, 'blocks', options), - page => { - expect(page.data.length).to.equal(3); - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - )); - - it('sort field', () => - // Act + Assert: - runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, [], { 'block.type': 1 }, 'blocks', options), - page => { - expect(page.data.length).to.equal(3); - expect(page.data[0].id).to.deep.equal(createObjectId(20)); - expect(page.data[1].id).to.deep.equal(createObjectId(10)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - )); - }); - - describe('uses provided collection', () => { - // Arrange: - const accounts = () => ([{ _id: createObjectId(10), account: { address: account1.address, addressHeight: 10 } }]); - const blocks = () => ([{ _id: createObjectId(20), meta: { transactionsCount: 1 }, block: { version: 3, type: 2 } }]); - const transactions = () => ([{ _id: createObjectId(30), meta: { height: 1 }, transaction: { type: 3 } }]); - - it('respects collection', () => - // Act + Assert: - runDbTest( - { accounts: accounts(), blocks: blocks(), transactions: transactions() }, - db => db.queryPagedDocuments({}, [], sortConditions, 'blocks', options), - page => { - expect(page.data.length).to.equal(1); - expect(page.data[0].id).to.deep.equal(createObjectId(20)); - } - )); - }); - - describe('options', () => { - const blocks = numBlocks => { - const resultBlocks = []; - for (let i = 0; numBlocks > i; i++) - resultBlocks.push({ _id: createObjectId(i), meta: { hash: 0x0100 }, block: { type: 1 } }); - - return resultBlocks; - }; - - describe('respects page size', () => { - it('page size: 25', () => { - const pageSize = 25; - - // Act + Assert: - return runDbTest( - { blocks: blocks(25 + 10) }, - db => db.queryPagedDocuments({}, [], { id: 1 }, 'blocks', { pageSize, pageNumber: 1 }), - page => { - expect(page.data.length).to.equal(25); - expect(page.pagination).to.deep.equal({ pageNumber: 1, pageSize: 25 }); - } - ); - }); - - it('less results than a page size', () => { - const pageSize = 25; - - // Act + Assert: - return runDbTest( - { blocks: blocks(10) }, - db => db.queryPagedDocuments({}, [], { id: 1 }, 'blocks', { pageSize, pageNumber: 1 }), - page => { - expect(page.data.length).to.equal(10); - expect(page.pagination).to.deep.equal({ pageNumber: 1, pageSize: 25 }); - } - ); - }); - }); - - describe('respects page number', () => { - const runPageNumberTest = (pageNumber, expectedNumberOfElements) => { - it(`page number: ${pageNumber}`, () => - // Act + Assert: - runDbTest( - { blocks: blocks(12) }, - db => db.queryPagedDocuments( - {}, - [], - { id: 1 }, - 'blocks', - { pageSize: 10, pageNumber } - ), - page => { - expect(page.data.length).to.equal(expectedNumberOfElements); - expect(page.pagination).to.deep.equal({ pageNumber, pageSize: 10 }); - } - )); - }; - - runPageNumberTest(1, 10); - runPageNumberTest(2, 2); - runPageNumberTest(3, 0); - }); - }); - - describe('does not promote MongoDb.Long to regular `number` for small enough numbers', () => { - // Arrange: - const blocks = () => ([{ _id: createObjectId(10), block: { height: Long.fromNumber(10) } }]); - - it('returns long', () => - // Act + Assert: - runDbTest( - { blocks: blocks() }, - db => db.queryPagedDocuments({}, [], sortConditions, 'blocks', options), - page => { - expect(page.data[0].block.height instanceof Long).to.be.equal(true); - } - )); - }); - }); - - describe('transactions', () => { - const account1 = { publicKey: test.random.publicKey() }; - account1.address = keyToAddress(account1.publicKey); - const account2 = { publicKey: test.random.publicKey() }; - account2.address = keyToAddress(account2.publicKey); - const account3 = { publicKey: test.random.publicKey() }; - account3.address = keyToAddress(account3.publicKey); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const { createObjectId } = test.db; - - const createTransaction = (objectId, addresses, height, signerPublicKey, recipientAddress, type, mosaics) => ({ - _id: createObjectId(objectId), - meta: { - height: Long.fromNumber(height), - addresses: addresses.map(a => Buffer.from(a)) - }, - transaction: { - signerPublicKey: signerPublicKey ? Buffer.from(signerPublicKey) : undefined, - recipientAddress: recipientAddress ? Buffer.from(recipientAddress) : undefined, - mosaics, - type - } - }); - - const createInnerTransaction = (objectId, aggregateId, signerPublicKey, recipientAddress, type) => ({ - _id: createObjectId(objectId), - meta: { aggregateId: createObjectId(aggregateId) }, - transaction: { - signerPublicKey: signerPublicKey ? Buffer.from(signerPublicKey) : undefined, - recipientAddress: recipientAddress ? Buffer.from(recipientAddress) : undefined, - type - } - }); - - const runTestAndVerifyIds = (dbTransactions, filters, options, expectedIds) => { - const blocks = createBlocks(dbTransactions); - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runDbTest( - { transactions: dbTransactions, blocks }, - db => db.transactions(TransactionGroups.confirmed, filters, options), - transactionsPage => { - const returnedIds = transactionsPage.data.map(t => t.id); - expect(transactionsPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [account1.address], 123, account1.publicKey, account2.address, EntityType.transfer) - ]; - const blocks = createBlocks(dbTransactions); - - // Act + Assert: - return runDbTest( - { transactions: dbTransactions, blocks }, - db => db.transactions(TransactionGroups.confirmed, {}, paginationOptions), - page => { - const expected_keys = ['meta', 'transaction', 'id']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('does not expose private meta.addresses field', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [account1.address], 1, 0, 0, 0) - ]; - const blocks = createBlocks(dbTransactions); - - // Act + Assert: - return runDbTest( - { transactions: dbTransactions, blocks }, - db => db.transactions(TransactionGroups.confirmed, {}, paginationOptions), - transactionsPage => { - expect(transactionsPage.data[0].meta.addresses).to.equal(undefined); - } - ); - }); - - it('if address is provided signerPublicKey and recipientAddress are omitted', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [account1.address], 1), - createTransaction(20, [account1.address], 1, account1.publicKey), - createTransaction(30, [account1.address], 1, account2.publicKey), - createTransaction(40, [account1.address], 1, account1.publicKey, account1.address), - createTransaction(50, [account1.address], 1, account2.publicKey, account2.address), - createTransaction(60, [account2.address], 1) - ]; - - const filters = { - address: account1.address, - signerPublicKey: account1.publicKey, - recipientAddress: account1.address - }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 20, 30, 40, 50]); - }); - - it('ignores inner aggregate transactions in the results', () => { - // Arrange: - const dbTransactions = [ - // Aggregate - createTransaction(10, [], 1, 0, 0, EntityType.aggregateComplete), - createInnerTransaction(100, 30, 0, 0, EntityType.mosaicDefinition), - createInnerTransaction(200, 30, 0, 0, EntityType.mosaicSupplyChange), - - createTransaction(20, [], 1, 0, 0, EntityType.aggregateBonded), - createInnerTransaction(300, 30, 0, 0, EntityType.transfer), - createInnerTransaction(400, 30, 0, 0, EntityType.mosaicDefinition), - - createTransaction(30, [], 1, 0, 0, EntityType.aggregateComplete), - createInnerTransaction(500, 30, 0, 0, EntityType.registerNamespace) - ]; - - const filters = { - transactionTypes: [EntityType.transfer, EntityType.mosaicDefinition, EntityType.aggregateComplete] - }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 30]); - }); - - it('returns correct transactions when no filters are provided', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [account1.address], 1), - createTransaction(20, [account1.address], 1, account1.publicKey), - createTransaction(30, [account1.address], 1, account1.publicKey, account1.address), - createTransaction(40, [account1.address], 1, account1.publicKey, account1.address, EntityType.transfer) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, {}, paginationOptions, [10, 20, 30, 40]); - }); - - it('all the provided filters are taken into account', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [account1.address], 1), - createTransaction(20, [account1.address], 1), - createTransaction(30, [account1.address], 1, account1.publicKey), - createTransaction(40, [account1.address], 1, account1.publicKey, account1.address), - createTransaction(50, [account1.address], 1, account1.publicKey, account1.address, EntityType.transfer), - createTransaction( - 60, [account1.address], 1, account1.publicKey, account1.address, EntityType.transfer, [{ id: 10, amount: 100 }] - ), - createTransaction( - 70, [account1.address], 1, account1.publicKey, account1.address, EntityType.transfer, [{ id: 10, amount: 200 }] - ), - createTransaction( - 80, [account1.address], 1, account1.publicKey, account1.address, EntityType.transfer, [{ id: 10, amount: 300 }] - ) - ]; - - const filters = { - height: 1, - signerPublicKey: account1.publicKey, - recipientAddress: account1.address, - transactionTypes: [EntityType.transfer], - transferMosaicId: 10, - fromTransferAmount: 101, - toTransferAmount: 299 - }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [70]); - }); - - describe('respects offset', () => { - // Arrange: - const dbTransactions = () => [ - createTransaction(10, [], 20), - createTransaction(20, [], 30), - createTransaction(30, [], 10) - ]; - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions(), {}, options, [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions(), {}, options, [10]); - }); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbTransactions = () => [ - createTransaction(10, [], 20), - createTransaction(20, [], 30), - createTransaction(30, [], 10) - ]; - const blocks = createBlocks(dbTransactions()); - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runDbTest( - { transactions: dbTransactions(), blocks }, - db => db.transactions(TransactionGroups.confirmed, [], options), - transactionsPage => { - expect(transactionsPage.data[0].id).to.deep.equal(createObjectId(10)); - expect(transactionsPage.data[1].id).to.deep.equal(createObjectId(20)); - expect(transactionsPage.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runDbTest( - { transactions: dbTransactions(), blocks }, - db => db.transactions(TransactionGroups.confirmed, [], options), - transactionsPage => { - expect(transactionsPage.data[0].id).to.deep.equal(createObjectId(30)); - expect(transactionsPage.data[1].id).to.deep.equal(createObjectId(20)); - expect(transactionsPage.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runDbTest( - { transactions: dbTransactions(), blocks }, - db => db.transactions(TransactionGroups.confirmed, [], options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('correctly applies each filter:', () => { - it('height', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [], 5), - createTransaction(20, [], 10), - createTransaction(30, [], 15) - ]; - - const filters = { height: 10 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [20]); - }); - - it('fromHeight', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [], 5), - createTransaction(20, [], 10), - createTransaction(30, [], 15) - ]; - - const filters = { fromHeight: 10 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [20, 30]); - }); - - it('toHeight', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [], 5), - createTransaction(20, [], 10), - createTransaction(30, [], 15) - ]; - - const filters = { toHeight: 10 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 20]); - }); - - it('fromHeight toHeight', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [], 5), - createTransaction(20, [], 10), - createTransaction(30, [], 15), - createTransaction(40, [], 20), - createTransaction(50, [], 25) - ]; - - const filters = { fromHeight: 10, toHeight: 20 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [20, 30, 40]); - }); - - it('address', () => { - // Arrange: - const dbTransactions = [ - createTransaction(10, [account1.address], 1), - createTransaction(20, [account2.address], 1), - createTransaction(30, [account3.address], 1), - createTransaction(40, [account2.address, account1.address], 1), - createTransaction(50, [account3.address, account1.address], 1) - ]; - - const filters = { address: account1.address }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 40, 50]); - }); - - it('signerPublicKey', () => { - // Arrange: - const dbTransactions = [ - // Non aggregate - createTransaction(10, [], 1, account1.publicKey), - createTransaction(20, [], 1, account2.publicKey), - - // Aggregate - createTransaction(30, [], 1, account1.publicKey), - createInnerTransaction(100, 30, account2.publicKey), - createInnerTransaction(200, 30, account2.publicKey), - - createTransaction(40, [], 1, account2.publicKey), - createInnerTransaction(300, 40, account1.publicKey), - createInnerTransaction(400, 40, account2.publicKey), - - createTransaction(50, [], 1, account2.publicKey), - createInnerTransaction(500, 50, account2.publicKey) - ]; - - const filters = { signerPublicKey: account1.publicKey }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 30]); - }); - - it('recipientAddress', () => { - // Arrange: - const dbTransactions = [ - // Non aggregate - createTransaction(10, [], 1, 0, account1.address), - createTransaction(20, [], 1, 0, account2.address), - - // Aggregate - createTransaction(30, [], 1, 0, account1.address), - createInnerTransaction(100, 30, 0, account2.address), - createInnerTransaction(200, 30, 0, account2.address), - - createTransaction(40, [], 1, 0, account2.address), - createInnerTransaction(300, 40, 0, account1.address), - createInnerTransaction(400, 40, 0, account2.address), - - createTransaction(50, [], 1, 0, account2.address), - createInnerTransaction(500, 50, 0, account2.address) - ]; - - const filters = { recipientAddress: account1.address }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 30]); - }); - - it('transactionTypes', () => { - // Arrange: - const dbTransactions = [ - // Non aggregate - createTransaction(10, [], 1, 0, 0, EntityType.transfer), - createTransaction(20, [], 1, 0, 0, EntityType.accountLink), - - // Aggregate - createTransaction(30, [], 1, 0, 0, EntityType.aggregateBonded), - createInnerTransaction(100, 30, 0, 0, EntityType.mosaicDefinition), - createInnerTransaction(200, 30, 0, 0, EntityType.mosaicSupplyChange), - - createTransaction(40, [], 1, 0, 0, EntityType.aggregateComplete), - createInnerTransaction(300, 40, 0, 0, EntityType.transfer), - createInnerTransaction(400, 40, 0, 0, EntityType.transfer), - - createTransaction(50, [], 1, 0, 0, EntityType.aggregateBonded), - createInnerTransaction(500, 50, 0, 0, EntityType.registerNamespace), - createInnerTransaction(600, 50, 0, 0, EntityType.aliasAddress) - ]; - - const filters = { - transactionTypes: [EntityType.mosaicDefinition, EntityType.aggregateComplete, EntityType.transfer] - }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 40]); - }); - - it('transferMosaicId', () => { - // Arrange: - const dbTransactions = [ - // Non aggregate - createTransaction(10, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 1 }]), - createTransaction(20, [], 1, 0, 0, EntityType.transfer, [{ id: 20, amount: 1 }]), - createTransaction(30, [], 1, 0, 0, EntityType.accountMetadata, [{ id: 10, amount: 1 }, { id: 20, amount: 1 }]) - ]; - - const filters = { transferMosaicId: 20 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [20, 30]); - }); - - it('fromTransferAmount', () => { - // Arrange: - const dbTransactions = [ - // Non aggregate - createTransaction(10, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 5 }]), - createTransaction(20, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 6 }]), - createTransaction(30, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 7 }]) - ]; - - const filters = { transferMosaicId: 10, fromTransferAmount: 6 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [20, 30]); - }); - - it('toTransferAmount', () => { - // Arrange: - const dbTransactions = [ - // Non aggregate - createTransaction(10, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 5 }]), - createTransaction(20, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 6 }]), - createTransaction(30, [], 1, 0, 0, EntityType.transfer, [{ id: 10, amount: 7 }]) - ]; - - const filters = { transferMosaicId: 10, toTransferAmount: 6 }; - - // Act + Assert: - return runTestAndVerifyIds(dbTransactions, filters, paginationOptions, [10, 20]); - }); - - describe('group', () => { - // Arrange: - const dbTransactions = () => ({ - transactions: [createTransaction(10, [], 1)], - partialTransactions: [createTransaction(20, [], 1)], - unconfirmedTransactions: [createTransaction(30, [], 1)], - blocks: [test.db.createDbBlock(1)] - }); - - const runGroupTest = (group, expectedIds) => { - it(`group: ${group}`, () => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - const transactions = dbTransactions(); - return runDbTest( - transactions, - db => db.transactions(group, {}, paginationOptions), - transactionsPage => { - const returnedIds = transactionsPage.data.map(t => t.id); - expect(transactionsPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }); - }; - - runGroupTest(TransactionGroups.confirmed, [10]); - runGroupTest(TransactionGroups.partial, [20]); - runGroupTest(TransactionGroups.unconfirmed, [30]); - - it('defaults to confirmed', () => - // Act + Assert: - runDbTest( - dbTransactions(), - db => db.transactions(TransactionGroups.confirmed, {}, paginationOptions), - transactionsPage => { - expect(transactionsPage.data.length).to.equal(1); - expect(transactionsPage.data[0].id).to.deep.equal(createObjectId(10)); - } - )); - }); - - describe('embedded', () => { - // Arrange: - const dbTransactions = () => [ - // Non aggregate - createTransaction(10, [], 1), - - // Aggregate - createTransaction(20, [], 1), - createInnerTransaction(100, 20) - ]; - - const runEmbeddedTest = (embedded, expectedIds) => - it(`embedded: ${embedded}`, () => - // Act + Assert: - runTestAndVerifyIds(dbTransactions(), { embedded }, paginationOptions, expectedIds)); - - runEmbeddedTest(true, [10, 20, 100]); - runEmbeddedTest(false, [10, 20]); - - it('defaults to false', () => - // Act + Assert: - runTestAndVerifyIds(dbTransactions(), {}, paginationOptions, [10, 20])); - }); - }); - }); - - describe('accounts', () => { - const addressTest1 = address.stringToAddress('SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'); - const addressTest2 = address.stringToAddress('NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'); - const addressTest3 = address.stringToAddress('SAAM2O7SSJ2A7AU3DZJMSTTRFZT5TFDPQ3ZIIJX'); - const addressTest4 = address.stringToAddress('SAMZMPX33DFIIVOCNJYMF5KJTGLAEVNKHHFROLX'); - const mosaicIdTest1 = Long.fromNumber(12345678); - const mosaicIdTest2 = Long.fromNumber(87654321); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const { createObjectId } = test.db; - - const createAccount = (objectId, accountAddress, mosaics, importances) => ({ - _id: createObjectId(objectId), - account: { - address: accountAddress ? Buffer.from(accountAddress) : undefined, - mosaics, - importances: importances || [] - } - }); - - const runTestAndVerifyIds = (dbAccounts, accountAddress, mosaicId, options, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runDbTest( - { accounts: dbAccounts }, - db => db.accounts(accountAddress, mosaicId, options), - page => { - const returnedIds = page.data.map(t => t.id); - expect(page.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - const runAccountsFilteredByAddressTest = pagination => { - it('returns accounts filtered by accountAddress', () => { - // Arrange: - const dbAccounts = [ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest2, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(30, addressTest3, []) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, addressTest2, undefined, pagination, [20]); - }); - }; - - const runAccountsFilteredByMosaicIdTest = pagination => { - it('returns accounts filtered by mosaicId', () => { - // Arrange: - const dbAccounts = [ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest1, [{ id: mosaicIdTest2, amount: Long.fromNumber(1) }]) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, undefined, mosaicIdTest2, pagination, [20]); - }); - }; - - const runImportancesDbTest = (dbAccounts, pagination, value, height) => - runDbTest( - { accounts: dbAccounts }, - db => db.accounts(undefined, undefined, pagination), - page => { - expect(page.data[0].account.importance).to.deep.equal(Long.fromNumber(value)); - expect(page.data[0].account.importanceHeight).to.deep.equal(Long.fromNumber(height)); - expect(page.data[0].account.importances).to.equal(undefined); - } - ); - - it('returns expected structure', () => { - // Arrange: - const dbAccounts = [createAccount(10, addressTest1, [])]; - - // Act + Assert: - return runDbTest( - { accounts: dbAccounts }, - db => db.accounts(undefined, undefined, paginationOptions), - page => { - const expected_keys = ['id', 'account']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns empty for unknown accountAddress', () => { - // Arrange: - const dbAccounts = [createAccount(10, addressTest1, [])]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, addressTest2, undefined, paginationOptions, []); - }); - - it('returns empty for unknown mosaicId', () => { - // Arrange: - const dbAccounts = [ - createAccount(10, addressTest1, [ - { id: mosaicIdTest1, amount: Long.fromNumber(1) } - ]) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, undefined, mosaicIdTest2, paginationOptions, []); - }); - - runAccountsFilteredByAddressTest(paginationOptions); - - runAccountsFilteredByMosaicIdTest(paginationOptions); - - it('returns all accounts if no accountAddress or mosaicId are provided', () => { - // Arrange: - const dbAccounts = [ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest2, [{ id: mosaicIdTest2, amount: Long.fromNumber(1) }]), - createAccount(30, addressTest3, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(40, addressTest4, [{ id: mosaicIdTest2, amount: Long.fromNumber(1) }]) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, undefined, undefined, paginationOptions, [10, 20, 30, 40]); - }); - - describe('picks top importance', () => { - it('no importances', () => { - // Arrange: - const dbAccounts = [createAccount(10, addressTest1, [], [])]; - - // Act + Assert: - return runImportancesDbTest(dbAccounts, paginationOptions, 0, 0); - }); - - it('one importance', () => { - // Arrange: - const importances = [ - { value: Long.fromNumber(100), height: Long.fromNumber(10) } - ]; - const dbAccounts = [createAccount(10, addressTest1, [], importances)]; - - // Act + Assert: - return runImportancesDbTest(dbAccounts, paginationOptions, 100, 10); - }); - - it('multiple importances', () => { - // Arrange: - const importances = [ - { value: Long.fromNumber(100), height: Long.fromNumber(10) }, - { value: Long.fromNumber(200), height: Long.fromNumber(20) } - ]; - const dbAccounts = [createAccount(10, addressTest1, [], importances)]; - - // Act + Assert: - return runImportancesDbTest(dbAccounts, paginationOptions, 100, 10); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbAccounts = () => ([ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest2, [{ id: mosaicIdTest1, amount: Long.fromNumber(2) }]), - createAccount(30, addressTest3, [{ id: mosaicIdTest1, amount: Long.fromNumber(3) }]) - ]); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts(), undefined, undefined, options, [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts(), undefined, undefined, options, [10]); - }); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbAccounts = () => ([ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest1, [{ id: mosaicIdTest2, amount: Long.fromNumber(1) }]), - createAccount(30, addressTest2, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]) - ]); - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runDbTest( - { accounts: dbAccounts() }, - db => db.accounts(undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runDbTest( - { accounts: dbAccounts() }, - db => db.accounts(undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runDbTest( - { accounts: dbAccounts() }, - db => db.accounts(undefined, undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('when sorting by balance', () => { - const paginationOptionsBalanceSorting = { - pageSize: 10, - pageNumber: 1, - sortField: 'balance', - sortDirection: -1 - }; - - it('returns expected structure', () => { - // Arrange: - const dbAccounts = [createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }])]; - - // Act + Assert: - return runDbTest( - { accounts: dbAccounts }, - db => db.accounts(undefined, undefined, paginationOptionsBalanceSorting), - page => { - const expected_keys = ['id', 'account']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns empty for unknown accountAddress', () => { - // Arrange: - const dbAccounts = [createAccount(10, addressTest1, [])]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, addressTest2, undefined, paginationOptionsBalanceSorting, []); - }); - - it('returns empty for unknown mosaicId', () => { - // Arrange: - const dbAccounts = [ - createAccount(10, addressTest1, [ - { id: mosaicIdTest1, amount: Long.fromNumber(1) } - ]) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, undefined, mosaicIdTest2, paginationOptionsBalanceSorting, []); - }); - - runAccountsFilteredByAddressTest(paginationOptionsBalanceSorting); - - runAccountsFilteredByMosaicIdTest(paginationOptionsBalanceSorting); - - it('returns all accounts if no accountAddress or mosaicId are provided', () => { - // Arrange: - const dbAccounts = [ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest2, [{ id: mosaicIdTest2, amount: Long.fromNumber(1) }]), - createAccount(30, addressTest3, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(40, addressTest4, [{ id: mosaicIdTest2, amount: Long.fromNumber(1) }]) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts, undefined, undefined, paginationOptionsBalanceSorting, [10, 20, 30, 40]); - }); - - describe('picks top importance', () => { - it('no importances', () => { - // Arrange: - const dbAccounts = [createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }], [])]; - - // Act + Assert: - return runImportancesDbTest(dbAccounts, paginationOptionsBalanceSorting, 0, 0); - }); - - it('one importance', () => { - // Arrange: - const importances = [ - { value: Long.fromNumber(100), height: Long.fromNumber(10) } - ]; - const dbAccounts = [createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }], importances)]; - - // Act + Assert: - return runImportancesDbTest(dbAccounts, paginationOptionsBalanceSorting, 100, 10); - }); - - it('multiple importances', () => { - // Arrange: - const importances = [ - { value: Long.fromNumber(100), height: Long.fromNumber(10) }, - { value: Long.fromNumber(200), height: Long.fromNumber(20) } - ]; - const dbAccounts = [createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }], importances)]; - - // Act + Assert: - return runImportancesDbTest(dbAccounts, paginationOptionsBalanceSorting, 100, 10); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbAccounts = () => ([ - createAccount(10, addressTest1, [{ id: mosaicIdTest1, amount: Long.fromNumber(1) }]), - createAccount(20, addressTest2, [{ id: mosaicIdTest1, amount: Long.fromNumber(2) }]), - createAccount(30, addressTest3, [{ id: mosaicIdTest1, amount: Long.fromNumber(3) }]) - ]); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'balance', - sortDirection: 1, - offset: Long.fromNumber(2) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts(), undefined, mosaicIdTest1, options, [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbAccounts(), undefined, mosaicIdTest1, options, [10]); - }); - }); - - describe('sorts by correct mosaic', () => { - const seedAccounts = []; - seedAccounts.push(createAccount( - 1, - test.random.address(), - [ - { id: Long.fromNumber(22), amount: Long.fromNumber(1) }, - { id: Long.fromNumber(33), amount: Long.fromNumber(5) }, - { id: Long.fromNumber(44), amount: Long.fromNumber(3) } - ] - )); - seedAccounts.push(createAccount( - 2, - test.random.address(), - [ - { id: Long.fromNumber(22), amount: Long.fromNumber(7) } - ] - )); - seedAccounts.push(createAccount( - 3, - test.random.address(), - [ - { id: Long.fromNumber(33), amount: Long.fromNumber(8) } - ] - )); - seedAccounts.push(createAccount( - 4, - test.random.address(), - [ - { id: Long.fromNumber(44), amount: Long.fromNumber(9) } - ] - )); - seedAccounts.push(createAccount( - 5, - test.random.address(), - [ - { id: Long.fromNumber(22), amount: Long.fromNumber(4) }, - { id: Long.fromNumber(33), amount: Long.fromNumber(2) }, - { id: Long.fromNumber(44), amount: Long.fromNumber(6) } - ] - )); - - const mosaicAmountEquals = (accountsPage, accountIndex, mosaicId, amount) => - accountsPage.data[accountIndex].account.mosaics - .find(mosaic => mosaic.id.equals(Long.fromNumber(mosaicId))).amount.equals(Long.fromNumber(amount)); - - it('asc', () => - runDbTest( - { accounts: seedAccounts }, - db => db.accounts(undefined, 33, { - sortField: 'balance', - sortDirection: 1, - pageNumber: 1, - pageSize: 10 - }), - accountsPage => { - expect(mosaicAmountEquals(accountsPage, 0, 33, 2)).to.equal(true); - expect(mosaicAmountEquals(accountsPage, 1, 33, 5)).to.equal(true); - expect(mosaicAmountEquals(accountsPage, 2, 33, 8)).to.equal(true); - } - )); - - it('desc', () => - runDbTest( - { accounts: seedAccounts }, - db => db.accounts(undefined, 33, { - sortField: 'balance', - sortDirection: -1, - pageNumber: 1, - pageSize: 10 - }), - accountsPage => { - expect(mosaicAmountEquals(accountsPage, 0, 33, 8)).to.equal(true); - expect(mosaicAmountEquals(accountsPage, 1, 33, 5)).to.equal(true); - expect(mosaicAmountEquals(accountsPage, 2, 33, 2)).to.equal(true); - } - )); - }); - }); - }); - - describe('accounts by ids', () => { - const publicKey = test.random.publicKey(); - const decodedAddress = keyToAddress(publicKey); - const publicKeyUnknown = test.random.publicKey(); - const decodedAddressUnknown = keyToAddress(publicKeyUnknown); - - const runAccountByIdsDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => { - // Arrange: - const db = new CatapultDb(Object.assign({ networkId: Testnet_Network }, DefaultPagingOptions)); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test', testDbOptions.connectionPoolSize) - .then(() => test.db.populateDatabase(db, dbEntities)) - .then(() => issueDbCommand(db)) - .then(assertDbCommandResult) - .then(() => db.close()); - }; - - const transformDbAccount = (dbAccountDocument, numImportances) => { - // the db call should replace importances with the most recent importance and importance height, - // so update the expected object to match - const accountWithMetadata = Object.assign({ id: dbAccountDocument._id }, dbAccountDocument); - delete accountWithMetadata._id; - const { account } = accountWithMetadata; - account.importance = Long.fromNumber(numImportances); - account.importanceHeight = Long.fromNumber(numImportances * numImportances); - delete account.importances; - return accountWithMetadata; - }; - - const runSingleKnownAccountTest = (description, accountId, options) => { - it(description, () => { - // Arrange: - // note: createAccounts uses options.numImportances to seed the importances for the accounts - // with values i for the importance and i * i for the importance height (0 < i <= numImportances) - // the last entry thus is (numImportances, numImportances * numImportances) - const seedAccounts = test.db.createAccounts(publicKey, options); - - // Assert: - return runAccountByIdsDbTest( - { accounts: seedAccounts }, - db => db.accountsByIds([accountId]), - accounts => { - // Assert: compare against the transformed account instead of the db account - const account = transformDbAccount(seedAccounts[0], options.numImportances); - expect(accounts).to.deep.equal([account]); - } - ); - }); - }; - - const runUnknownAccountTest = (accountId, options) => { - it('returns empty array for unknown ids', () => - // Assert: - runDbTest( - { accounts: test.db.createAccounts(publicKey, options) }, - db => db.accountsByIds([accountId]), - accounts => expect(accounts).to.deep.equal([]) - )); - }; - - const addAccountsByIdsTestsForSingleAccountLookup = (knownAccountId, unknownAccountId) => { - runSingleKnownAccountTest( - 'can retrieve account with neither public key nor mosaics', - knownAccountId, - { savePublicKey: false, numMosaics: 0 } - ); - runSingleKnownAccountTest( - 'can retrieve account with public key but no mosaics', - knownAccountId, - { savePublicKey: true, numMosaics: 0 } - ); - runSingleKnownAccountTest( - 'can retrieve account without public key but with mosaics', - knownAccountId, - { savePublicKey: false, numMosaics: 3 } - ); - runSingleKnownAccountTest( - 'can retrieve account with public key and with mosaics', - knownAccountId, - { savePublicKey: true, numMosaics: 3 } - ); - runSingleKnownAccountTest( - 'can retrieve account without importances', - knownAccountId, - { savePublicKey: true, numMosaics: 3, numImportances: 0 } - ); - runSingleKnownAccountTest( - 'can retrieve account with single importance', - knownAccountId, - { savePublicKey: true, numMosaics: 3, numImportances: 1 } - ); - runUnknownAccountTest( - unknownAccountId, - { savePublicKey: false, numMosaics: 3, expectedAddress: decodedAddressUnknown } - ); - }; - - describe('account from decoded address', () => { - addAccountsByIdsTestsForSingleAccountLookup({ address: decodedAddress }, { address: decodedAddressUnknown }); - - it('picks top importance', () => { - const numImportances = 2; - const seedAccounts = test.db.createAccounts(publicKey, { savePublicKey: true, numMosaics: 1, numImportances }); - - // Assert: - return runAccountByIdsDbTest( - { accounts: seedAccounts }, - db => db.accountsByIds([{ address: decodedAddress }]), - accounts => { - expect(accounts[0].account.importance).to.deep.equal(Long.fromNumber(numImportances)); - expect(accounts[0].account.importanceHeight).to.deep.equal(Long.fromNumber(numImportances * numImportances)); - expect(accounts[0].account.importances).to.equal(undefined); - } - ); - }); - }); - - describe('account from public key', () => { - // note: even if public key is not known in the accounts collection, the call to accountsByIds() - // will succeed since the public key is converted to a decoded address. - addAccountsByIdsTestsForSingleAccountLookup({ publicKey }, { publicKey: publicKeyUnknown }); - - it('picks top importance', () => { - const numImportances = 2; - const seedAccounts = test.db.createAccounts(publicKey, { savePublicKey: true, numMosaics: 1, numImportances }); - - // Assert: - return runAccountByIdsDbTest( - { accounts: seedAccounts }, - db => db.accountsByIds([{ publicKey }]), - accounts => { - expect(accounts[0].account.importance).to.deep.equal(Long.fromNumber(numImportances)); - expect(accounts[0].account.importanceHeight).to.deep.equal(Long.fromNumber(numImportances * numImportances)); - expect(accounts[0].account.importances).to.equal(undefined); - } - ); - }); - }); - - describe('multiple accounts', () => { - const runMultipleAccountsByIdsTests = runTest => { - // Arrange: create 5 random accounts and extract their public keys - const seedAccounts = test.db.createAccounts(test.random.publicKey(), { - numAccounts: 4, - savePublicKey: true, - saveRandomPublicKey: true, - numMosaics: 3, - numImportances: 1 - }); - const publicKeys = seedAccounts.map(seedAccount => seedAccount.account.publicKey.buffer); - - // Assert: - return runTest(seedAccounts, publicKeys); - }; - - it('returns multiple matching accounts', () => - // Arrange: - runMultipleAccountsByIdsTests((seedAccounts, publicKeys) => runAccountByIdsDbTest( - { accounts: seedAccounts }, - db => db.accountsByIds([ - { publicKey: publicKeys[1] }, - { address: keyToAddress(publicKeys[3]) }, - { publicKey: publicKeys[4] } - ]), - accounts => expect(accounts).to.deep.equal([1, 3, 4].map(index => transformDbAccount(seedAccounts[index], 1))) - ))); - - it('returns only known matching accounts', () => - // Arrange: - runMultipleAccountsByIdsTests((seedAccounts, publicKeys) => runAccountByIdsDbTest( - { accounts: seedAccounts }, - db => db.accountsByIds([ - { publicKey: publicKeys[1] }, - { publicKey: test.random.publicKey() }, - { address: test.random.address() }, - { address: keyToAddress(publicKeys[3]) } - ]), - accounts => expect(accounts).to.deep.equal([1, 3].map(index => transformDbAccount(seedAccounts[index], 1))) - ))); - - it('picks top importance', () => { - const publicKey1 = test.random.publicKey(); - const publicKey2 = test.random.publicKey(); - - const importanceValue = Long.fromNumber(100); - const importanceHeight = Long.fromNumber(10); - - const seedAccounts = [ - test.db.createAccount(1, publicKey1, true, [], [{ value: importanceValue, height: importanceHeight }, {}]), - test.db.createAccount(2, publicKey2, true, [], [{ value: importanceValue, height: importanceHeight }, {}]) - ]; - - // Assert: - return runAccountByIdsDbTest( - { accounts: seedAccounts }, - db => db.accountsByIds([{ publicKey: publicKey1 }, { publicKey: publicKey2 }]), - accounts => { - accounts.forEach(account => { - expect(account.account.importance).to.deep.equal(importanceValue); - expect(account.account.importanceHeight).to.deep.equal(importanceHeight); - expect(account.account.importances).to.equal(undefined); - }); - } - ); - }); - }); - }); - - // region failed transactions - - describe('failed transactions by hashes', () => { - const runTransactionsByHashesFailedTest = (numSeeds, runTest) => { - // Arrange: - const hashes = Array.from(Array(numSeeds), () => test.random.hash()); - const failedTransactionResults = []; - for (let i = 0; i < numSeeds; ++i) - failedTransactionResults.push({ status: { hash: new Binary(hashes[i]), validationResult: i } }); - - // Assert: - return runTest(failedTransactionResults, hashes); - }; - - it('returns empty array for unknown hashes', () => - // Arrange: - runTransactionsByHashesFailedTest(3, seedResults => runDbTest( - { transactionStatuses: seedResults }, - db => db.transactionsByHashesFailed([test.random.hash(), test.random.hash()]), - results => { expect(results).to.deep.equal([]); } - ))); - - it('returns single matching failed transaction', () => - // Arrange: - runTransactionsByHashesFailedTest(3, (seedResults, hashes) => runDbTest( - { transactionStatuses: seedResults }, - db => db.transactionsByHashesFailed([hashes[1]]), - results => { expect(results).to.deep.equal([seedResults[1]]); } - ))); - - it('returns multiple matching failed transactions', () => - // Arrange: - runTransactionsByHashesFailedTest(5, (seedResults, hashes) => runDbTest( - { transactionStatuses: seedResults }, - db => db.transactionsByHashesFailed([1, 3, 4].map(index => hashes[index])), - results => { expect(results).to.deep.equal([1, 3, 4].map(index => seedResults[index])); } - ))); - - it('returns only known matching failed transactions', () => - // Arrange: - runTransactionsByHashesFailedTest(3, (seedResults, hashes) => runDbTest( - { transactionStatuses: seedResults }, - db => db.transactionsByHashesFailed([hashes[0], test.random.hash(), hashes[2], test.random.hash()]), - results => { expect(results).to.deep.equal([0, 2].map(index => seedResults[index])); } - ))); - }); - - // endregion - - // region utils - - describe('utils', () => { - it('can retrieve account public key from account address', () => { - // Arrange: - const accountPublicKeyOne = test.random.publicKey(); - const accountAddressOne = keyToAddress(accountPublicKeyOne); - const accountPublicKeyTwo = test.random.publicKey(); - const accountAddressTwo = keyToAddress(accountPublicKeyTwo); - - const accountDbEntities = [ - { - meta: {}, - account: { - address: new Binary(accountAddressOne), - publicKey: new Binary(accountPublicKeyOne) - } - }, - { - meta: {}, - account: { - address: new Binary(accountAddressTwo), - publicKey: new Binary(accountPublicKeyTwo) - } - } - ]; - - // Act + Assert: - return runDbTest( - { accounts: accountDbEntities }, - db => db.addressToPublicKey(accountAddressOne), - accountDbEntity => { expect(accountDbEntity.account.publicKey.buffer.equals(accountPublicKeyOne)).to.be.equal(true); } - ); - }); - }); - - // endregion -}); diff --git a/rest/test/db/connector_spec.js b/rest/test/db/connector_spec.js deleted file mode 100644 index 793b6d611..000000000 --- a/rest/test/db/connector_spec.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const testDbOptions = require('./utils/testDbOptions'); -const connector = require('../../src/db/connector'); -const { expect } = require('chai'); - -describe('connector', () => { - const connections = []; - - afterEach(() => { - // close database connections used during the previous test - while (0 < connections.length) { - const connection = connections.pop(); - connection.close(); - } - }); - - it('can connect to database', () => - // Act: - connector.connectToDatabase(testDbOptions.url, 'tokyo', testDbOptions.connectionPoolSize) - .then(client => { - connections.push(client); - - // Assert: - expect(client).to.not.equal(null); - expect(client.db().s.namespace.db).to.equal('tokyo'); - })); -}); diff --git a/rest/test/db/dbFormattingRules_spec.js b/rest/test/db/dbFormattingRules_spec.js deleted file mode 100644 index 9cd4830ea..000000000 --- a/rest/test/db/dbFormattingRules_spec.js +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const formattingRules = require('../../src/db/dbFormattingRules'); -const { convertToLong } = require('../../src/db/dbUtils'); -const test = require('../testUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const { Binary } = require('mongodb'); - -const { ModelType } = catapult.model; - -describe('db formatting rules', () => { - it('can format none type', () => { - // Arrange: - const object = { foo: 8 }; - - // Act: - const result = formattingRules[ModelType.none](object); - - // Assert: - expect(result).to.deep.equal({ foo: 8 }); - }); - - it('can format binary type', () => { - // Arrange: - const object = test.factory.createBinary(Buffer.from('FEDCBA9876543210', 'hex')); - - // Act: - const result = formattingRules[ModelType.binary](object); - - // Assert: - expect(result).to.equal('FEDCBA9876543210'); - }); - - it('can format javascript buffer as binary type', () => { - // Arrange: - const object = Buffer.from('FEDCBA9876543210', 'hex'); - - // Act: - const result = formattingRules[ModelType.binary](object); - - // Assert: - expect(result).to.equal('FEDCBA9876543210'); - }); - - it('can format object id type', () => { - // Arrange: - const object = test.factory.createObjectIdFromHexString('3AEDCBA9876F94725732547F'); - - // Act: - const result = formattingRules[ModelType.objectId](object); - - // Assert: - expect(result).to.equal('3AEDCBA9876F94725732547F'); - }); - - it('can format status code type', () => { - // Arrange: notice that codes are signed in db - [0x80530001, -2142044159].forEach(code => { - // Act: - const result = formattingRules[ModelType.statusCode](code); - - // Assert: - expect(result, `${code} code`).to.equal('Failure_Signature_Not_Verifiable'); - }); - }); - - it('can format string type', () => { - // Arrange: - const object = test.factory.createBinary(Buffer.from('6361746170756C74', 'hex')); - - // Act: - const result = formattingRules[ModelType.string](object); - - // Assert: - expect(result).to.equal('catapult'); - }); - - describe('can format uint8 type', () => { - const testCases = [ - { name: 'value 0', value: 0, formated: 0 }, - { name: 'value 128', value: 128, formated: 128 }, - { name: 'value 255 (max)', value: 255, formated: 255 } - ]; - - testCases.forEach(testCase => { - it(testCase.name, () => { - // Arrange + Act: - const result = formattingRules[ModelType.uint8](testCase.value); - - // Assert: - expect(result).to.equal(testCase.formated); - }); - }); - }); - - describe('can format uint16 type', () => { - const testCases = [ - { name: 'value 0', value: 0, formated: 0 }, - { name: 'value 17434', value: 17434, formated: 17434 }, - { name: 'value 32768', value: 32768, formated: 32768 }, - { name: 'value 65535 (max)', value: 65535, formated: 65535 } - ]; - - testCases.forEach(testCase => { - it(testCase.name, () => { - // Arrange + Act: - const result = formattingRules[ModelType.uint16](testCase.value); - - // Assert: - expect(result).to.equal(testCase.formated); - }); - }); - - it('can format uint16 type from Binary', () => { - // Arrange: - const buffer = Buffer.alloc(2, 0); - buffer.writeUInt16LE(17434); - const object = new Binary(buffer); - - // Act: - const result = formattingRules[ModelType.uint16](object); - - // Assert: - expect(result).to.deep.equal(17434); - }); - }); - - describe('can format uint32 type', () => { - const testCases = [ - { name: 'value 0', value: 0, formated: 0 }, - { name: 'value 2147483647', value: 2147483647, formated: 2147483647 }, - { name: 'value -2147483648', value: -2147483648, formated: 2147483648 }, - { name: 'value 4294967295 (max)', value: -1, formated: 4294967295 } - ]; - - testCases.forEach(testCase => { - it(testCase.name, () => { - // Arrange + Act: - const result = formattingRules[ModelType.uint32](testCase.value); - - // Assert: - expect(result).to.equal(testCase.formated); - }); - }); - }); - - describe('can format uint64 type', () => { - it('can format uint64 type from Long', () => { - // Arrange: - const object = convertToLong([1, 2]); - - // Act: - const result = formattingRules[ModelType.uint64](object); - - // Assert: - expect(result).to.equal('8589934593'); - }); - - it('can format uint64HexIdentifier type from Long', () => { - // Arrange: - const object = convertToLong([1, 2]); - - // Act: - const result = formattingRules[ModelType.uint64HexIdentifier](object); - - // Assert: - expect(result).to.equal('0000000200000001'); - }); - - it('can format uint64HexIdentifier type from Binary', () => { - // Arrange: - const buffer = Buffer.alloc(8, 0); - buffer.writeUInt32LE(0x00ABCDEF, 0); - buffer.writeUInt32LE(0x000FDFFF, 4); - const object = new Binary(buffer); - - // Act: - const result = formattingRules[ModelType.uint64HexIdentifier](object); - - // Assert: - expect(result).to.equal('000FDFFF00ABCDEF'); - }); - }); - - describe('can format int type', () => { - const testCases = [ - { name: 'value 0', value: 0, formated: 0 }, - { name: 'value 255', value: 255, formated: 255 }, - { name: 'value 65535', value: 65535, formated: 65535 }, - { name: 'value -1', value: -1, formated: -1 }, - { name: 'value -2147483648 (min)', value: -2147483648, formated: -2147483648 }, - { name: 'value 2147483647 (max)', value: 2147483647, formated: 2147483647 } - ]; - - testCases.forEach(testCase => { - it(testCase.name, () => { - // Arrange + Act: - const result = formattingRules[ModelType.int](testCase.value); - - // Assert: - expect(result).to.equal(testCase.formated); - }); - }); - }); - - describe('can format boolean type', () => { - const testCases = [ - { name: 'boolean true', value: true, formated: true }, - { name: 'boolean false', value: false, formated: false } - ]; - - testCases.forEach(testCase => { - it(testCase.name, () => { - // Arrange + Act: - const result = formattingRules[ModelType.boolean](testCase.value); - - // Assert: - expect(result).to.equal(testCase.formated); - }); - }); - }); - - it('can format encodedAddress type using hex', () => { - // Arrange - const object = test.factory.createBinary(Buffer.from('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56', 'hex')); - - // Act: - const result = formattingRules[ModelType.encodedAddress](object, false); - - // Assert: - expect(result).to.equal('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56'); - }); -}); diff --git a/rest/test/db/dbUtils_spec.js b/rest/test/db/dbUtils_spec.js deleted file mode 100644 index 7bbfebdde..000000000 --- a/rest/test/db/dbUtils_spec.js +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const dbUtils = require('../../src/db/dbUtils'); -const { convertToLong } = require('../../src/db/dbUtils'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); - -const { ObjectId } = MongoDb; - -describe('db utils', () => { - describe('convertToLong', () => { - it('can convert from integer to long', () => { - // Act + Assert: - expect(dbUtils.convertToLong(123)).to.deep.equal(MongoDb.Long(123, 0)); - }); - - it('can convert from uint64 array to long', () => { - // Act + Assert: - expect(dbUtils.convertToLong([123, 456])).to.deep.equal(MongoDb.Long(123, 456)); - }); - - it('can convert from negative one to long', () => { - // Act + Assert: - expect(dbUtils.convertToLong(-1)).to.deep.equal(MongoDb.Long.NEG_ONE); - }); - - it('can convert from one to long', () => { - // Act + Assert: - expect(dbUtils.convertToLong(1)).to.deep.equal(MongoDb.Long.ONE); - expect(dbUtils.convertToLong([1, 0])).to.deep.equal(MongoDb.Long.ONE); - }); - - it('can convert from zero to long', () => { - // Act + Assert: - expect(dbUtils.convertToLong(0)).to.deep.equal(MongoDb.Long.ZERO); - expect(dbUtils.convertToLong([0, 0])).to.deep.equal(MongoDb.Long.ZERO); - }); - - it('returns same value if value is already long', () => { - // Arrange - const longValue = MongoDb.Long.fromNumber(12345); - - // Act + Assert: - expect(dbUtils.convertToLong(longValue)).to.deep.equal(longValue); - }); - - it('throws error if value not integer and not array', () => { - // Act + Assert: - expect(() => dbUtils.convertToLong('abc')).to.throw('abc has an invalid format: not integer or uint64'); - }); - }); - - describe('longToUint64', () => { - it('can convert from long to uint64', () => { - // Act + Assert: - expect(dbUtils.longToUint64(MongoDb.Long(123, 456))).to.deep.equal([123, 456]); - }); - - it('can convert from one, long value, to uint64', () => { - // Act + Assert: - expect(dbUtils.longToUint64(MongoDb.Long.ONE)).to.deep.equal([1, 0]); - }); - - it('can convert from zero, long value, to uint64', () => { - // Act + Assert: - expect(dbUtils.longToUint64(MongoDb.Long.ZERO)).to.deep.equal([0, 0]); - }); - - it('throws error if value not long', () => { - // Act + Assert: - expect(() => dbUtils.longToUint64('abc')).to.throw('abc has an invalid format: not long'); - }); - }); - describe('uniqueLongList', () => { - it('unique list empty', () => { - // Act + Assert - expect(dbUtils.uniqueLongList([])).to.deep.equal([]); - }); - - it('unique list not duplicated', () => { - // Act + Assert - expect(dbUtils.uniqueLongList([convertToLong(1), convertToLong(2), convertToLong(3)])) - .to.deep.equal([convertToLong(1), convertToLong(2), convertToLong(3)]); - }); - - it('unique list duplicated', () => { - // Act + Assert - expect(dbUtils.uniqueLongList([convertToLong(3), convertToLong(1), convertToLong(3)])) - .to.deep.equal([convertToLong(3), convertToLong(1)]); - }); - }); - - describe('buildOffsetCondition', () => { - it('undefined offset', () => { - // Arrange - const options = { offset: undefined }; - const sortFieldDbRelation = { id: '_id' }; - - // Act + Assert - expect(dbUtils.buildOffsetCondition(options, sortFieldDbRelation)).to.equal(undefined); - }); - - it('can create object id offset condition', () => { - // Arrange - const options = { - offset: '112233445566778899AABBCC', - offsetType: 'objectId', - sortField: 'id', - sortDirection: 'desc' - }; - const sortFieldDbRelation = { id: '_id' }; - - // Act + Assert - expect(dbUtils.buildOffsetCondition(options, sortFieldDbRelation)).to.deep.equal({ - _id: { $lt: new ObjectId('112233445566778899AABBCC') } - }); - }); - - it('can create uint64 offset condition', () => { - // Arrange - const options = { - offset: [1234, 5678], - offsetType: 'uint64', - sortField: 'height', - sortDirection: 'desc' - }; - const sortFieldDbRelation = { height: 'height' }; - - // Act + Assert - expect(dbUtils.buildOffsetCondition(options, sortFieldDbRelation)).to.deep.equal({ - height: { $lt: convertToLong([1234, 5678]) } - }); - }); - - it('can create uint64Hex offset condition', () => { - // Arrange - const options = { - offset: [1234, 5678], - offsetType: 'uint64Hex', - sortField: 'id', - sortDirection: 'desc' - }; - const sortFieldDbRelation = { id: '_id' }; - - // Act + Assert - expect(dbUtils.buildOffsetCondition(options, sortFieldDbRelation)).to.deep.equal({ - _id: { $lt: convertToLong([1234, 5678]) } - }); - }); - }); - - describe('bufferToUnresolvedAddress', () => { - it('can convert from Buffer to encoded address', () => { - // Arrange - const object = Buffer.from('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56', 'hex'); - - // Act: - const result = dbUtils.bufferToUnresolvedAddress(object, true); - - // Assert: - expect(result).to.equal('TDQNCOHK6KWDILABL7YLMMPMGYRORL72AS74YVQ'); - }); - - it('can convert from Buffer to decoded address', () => { - // Arrange - const object = Buffer.from('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56', 'hex'); - - // Act: - const result = dbUtils.bufferToUnresolvedAddress(object); - - // Assert: - expect(result).to.equal('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56'); - }); - - it('can convert from undefined to undefined address', () => { - // Arrange - const object = undefined; - - // Act: - const result = dbUtils.bufferToUnresolvedAddress(object); - - // Assert: - expect(result).to.equal(undefined); - }); - - it('cannot convert from invalid data type', () => { - // Arrange - const object = '99CAAB0FD01CCF25BA000000000000000000000000000000'; - - // act + Assert: - expect(() => dbUtils.bufferToUnresolvedAddress(object)).to.throw('Cannot convert binary address, unknown String type'); - }); - }); -}); diff --git a/rest/test/db/entityEmitterFactory_spec.js b/rest/test/db/entityEmitterFactory_spec.js deleted file mode 100644 index 86e2b77fc..000000000 --- a/rest/test/db/entityEmitterFactory_spec.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const entityEmitterFactory = require('../../src/db/entityEmitterFactory'); -const { expect } = require('chai'); -const EventEmitter = require('events'); - -describe('entity emitter factory', () => { - it('registers block listener', () => { - // Act: - const queries = []; - const entityEmitterPromise = entityEmitterFactory.createEntityEmitter(query => { - queries.push(query); - return Promise.resolve(new EventEmitter()); - }); - entityEmitterPromise.then(() => { - // Assert: - expect(queries.length).to.equal(1); - expect(queries[0]).to.deep.equal({ ns: 'catapult.blocks', op: 'i' }); - }); - }); - - const createEntityEmitter = opEmitters => entityEmitterFactory.createEntityEmitter(query => { - const opEmitter = new EventEmitter(); - opEmitters[query.ns] = opEmitter; - return Promise.resolve(opEmitter); - }); - - const assertNoEvents = (emitter, eventName) => { - emitter.once(eventName, () => { - // Assert: fail the test if the event was raised - expect(true, `${eventName} event was unexpected`).to.equal(false); - }); - }; - - it('maps op event to block event', () => { - // Arrange: - const opEmitters = {}; - return createEntityEmitter(opEmitters) - .then(entityEmitter => { - assertNoEvents(entityEmitter, 'error'); - - return new Promise(resolve => { - // - set up a block listener - entityEmitter.once('block', block => { - // Assert: the op event was translated to a block event - expect(block).to.deep.equal({ height: 7 }); - resolve(); - }); - - // Act: raise an op event - opEmitters['catapult.blocks'].emit('op', { ns: 'catapult.blocks', op: 'i', o: { height: 7 } }); - }); - }); - }); - - it('forwards op error event', () => { - // Arrange: - const opEmitters = {}; - return createEntityEmitter(opEmitters) - .then(entityEmitter => { - assertNoEvents(entityEmitter, 'block'); - - return new Promise(resolve => { - // - set up an error listener - entityEmitter.once('error', err => { - // Assert: the op error event was forwarded - expect(err.message).to.equal('op error'); - resolve(); - }); - - // Act: raise an op error event - opEmitters['catapult.blocks'].emit('error', new Error('op error')); - }); - }); - }); -}); diff --git a/rest/test/db/utils/dbTestUtils.js b/rest/test/db/utils/dbTestUtils.js deleted file mode 100644 index cb91e192c..000000000 --- a/rest/test/db/utils/dbTestUtils.js +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const testDbOptions = require('./testDbOptions'); -const CatapultDb = require('../../../src/db/CatapultDb'); -const { convertToLong } = require('../../../src/db/dbUtils'); -const test = require('../../testUtils'); -const catapult = require('catapult-sdk'); -const MongoDb = require('mongodb'); - -const { address } = catapult.model; - -const { Binary, Long, ObjectId } = MongoDb; - -const Default_Height = 34567; -const Key_Size = 32; - -const DefaultPagingOptions = { - pageSizeMin: 10, - pageSizeMax: 100, - pageSizeDefault: 20 -}; - -const createDbCollection = (db, collectionName) => - // note: db.database.collection() will always return a collection even if it doesn't exist in the database - db.database.collection(collectionName) - .drop() - .catch(() => Promise.resolve()); - -const createObjectId = id => new ObjectId(`${'00'.repeat(12)}${id.toString(16)}`.slice(-24)); - -const createMosaics = count => { - const mosaics = []; - for (let i = 0; i < count; ++i) - mosaics.push({ id: Long.fromNumber(i), amount: Long.fromNumber(i * i) }); - - return mosaics; -}; - -const createImportances = count => { - const importances = []; - for (let i = 1; i <= count; ++i) - importances.push({ value: Long.fromNumber(i), height: Long.fromNumber(i * i) }); - - return importances.reverse(); -}; - -const createAccount = (objectId, publicKey, savePublicKey, mosaics, importances) => { - const decoded = Buffer.from(address.publicKeyToAddress(publicKey, testDbOptions.networkId)); - const account = { - address: new Binary(decoded), - addressHeight: Long.fromNumber(123), - importances, - mosaics - }; - if (savePublicKey) { - account.publicKey = new Binary(publicKey); - account.publicKeyHeight = Long.fromNumber(234); - } else { - // use zeroed public key so the account size stays the same if later the real public key is stored - account.publicKey = new Binary(Buffer.alloc(Key_Size, 0)); - account.publicKeyHeight = Long.fromNumber(0); - } - - return { _id: createObjectId(objectId), account }; -}; - -const createAccounts = (publicKey, options) => { - options.numAccounts = undefined === options.numAccounts ? 10 : options.numAccounts; - options.numImportances = undefined === options.numImportances ? 3 : options.numImportances; - const accounts = []; - - // note: the first account in the array is not random since it is used in tests - accounts.push(createAccount( - 1, - publicKey, - options.savePublicKey, - createMosaics(options.numMosaics), - createImportances(options.numImportances) - )); - - for (let i = 0; i < options.numAccounts; ++i) { - accounts.push(createAccount( - i + 2, - test.random.publicKey(), - 0 === i % 2 || options.saveRandomPublicKey, - createMosaics(options.numMosaics), - createImportances(options.numImportances) - )); - } - - return accounts; -}; - -const createDbBlock = height => { - // meta data - const meta = { - hash: new Binary(test.random.hash()), - generationHash: new Binary(test.random.hash()), - totalFee: Long.fromNumber(12345), - transactionsCount: 5, - statementsCount: 5, - transactionMerkleTree: [new Binary(test.random.hash()), new Binary(test.random.hash())], - statementMerkleTree: [new Binary(test.random.hash()), new Binary(test.random.hash())] - }; - - // block header data - const block = { - signature: new Binary(test.random.signature()), - signerPublicKey: new Binary(test.random.publicKey()), - version: 234, - type: 345, - timestamp: Long.fromNumber(23456), - height: Long.fromNumber(height), - difficulty: Long.fromNumber(45678), - feeMultiplier: 100, - previousBlockHash: new Binary(test.random.hash()), - transactionsHash: new Binary(test.random.hash()) - }; - - return { meta, block }; -}; - -const createDbBlockWithId = (id, height) => Object.assign({ _id: createObjectId(id) }, createDbBlock(height)); - -const createDbTransaction = (id, signerPublicKey, recipientAddress, options) => { - // meta data - const meta = { - hash: new Binary(test.random.hash()), - height: Long.fromNumber((options || {}).height || Default_Height), - addresses: [] - }; - - // transaction data - const transaction = { - signature: new Binary(test.random.signature()), - signerPublicKey: new Binary(signerPublicKey), - version: 432, - type: 543, - timestamp: Long.fromNumber(65432), - maxFee: Long.fromNumber(76543), - deadline: Long.fromNumber(87654), - recipientAddress: new Binary(recipientAddress), - message: { size: 12, payload: new Binary(test.random.bytes(12)) }, - mosaics: [] - }; - for (let j = 0; 3 < j; ++j) - transaction.mosaics.push({ id: Long.fromNumber(j), amount: Long.fromNumber(j * j) }); - - return { _id: id, meta, transaction }; -}; - -const createDbTransactions = (numRounds, signerPublicKey, recipientAddress) => { - // Each round consists of - // - 1 random transaction - // - 1 transaction with signerPublicKey - // - 1 random transaction - // - 1 transaction with recipient - // - 1 random transaction - // - 1 transaction with signerPublicKey and recipient address - // - 1 random transaction with aggregateId - // - 1 transaction with signerPublicKey and aggregateId - // all in all we have 8 * numRounds transactions - let id = 0; - const transactions = []; - - const push = (txSigner, txRecipient) => { - transactions.push(createDbTransaction(createObjectId(++id), txSigner, txRecipient)); - }; - - for (let i = 0; i < numRounds; ++i) { - push(test.random.publicKey(), test.random.address()); - push(signerPublicKey, test.random.address()); - push(test.random.publicKey(), test.random.address()); - push(test.random.publicKey(), recipientAddress); - push(test.random.publicKey(), test.random.address()); - push(signerPublicKey, recipientAddress); - push(test.random.publicKey(), test.random.address()); - transactions[transactions.length - 1].meta.aggregateId = createObjectId(id); - push(signerPublicKey, test.random.address()); - transactions[transactions.length - 1].meta.aggregateId = createObjectId(id); - } - - return transactions; -}; - -const createChainStatistic = (height, scorelow, scoreHigh) => ({ - current: { - height: Long.fromNumber(height), - scoreLow: Long.fromNumber(scorelow), - scoreHigh: Long.fromNumber(scoreHigh) - } -}); - -const collectionUtils = { - names: ['blocks', 'transactions', 'unconfirmedTransactions', 'partialTransactions', - 'transactionStatuses', 'accounts', 'chainStatistic', 'finalizedBlocks'], - findInEntities: (dbEntities, collectionName) => { - if ('blocks' !== collectionName) - return dbEntities[collectionName]; - - return 'blocks' in dbEntities ? dbEntities.blocks : dbEntities.block; - } -}; - -const populateCollection = (db, collectionName, seed) => createDbCollection(db, collectionName).then(() => { - if (seed) { - const insertionFunction = Array.isArray(seed) ? 'insertMany' : 'insertOne'; - return db.database.collection(collectionName)[insertionFunction](seed); - } - - return Promise.resolve(); -}); - -const populateDatabase = (db, dbEntities) => { - const promises = []; - collectionUtils.names.forEach(collectionName => { - const seed = collectionUtils.findInEntities(dbEntities, collectionName); - const createCollectionPromise = populateCollection(db, collectionName, seed); - promises.push(createCollectionPromise); - }); - - return Promise.all(promises); -}; - -const copyAndDeleteId = (item, collectionName) => { - if (!['accounts', 'blocks'].includes(collectionName) && item.meta) - item.meta.id = item._id; - - delete item._id; -}; - -const sanitizeDbEntities = (collectionName, seed) => { - if (Array.isArray(seed)) - seed.forEach(item => copyAndDeleteId(item, collectionName)); - else if (seed) - copyAndDeleteId(seed, collectionName); -}; - -const runDbTest = (dbEntities, collectionName, createDbFacade, issueDbCommand, assertDbCommandResult) => { - // Arrange: - const db = new CatapultDb(Object.assign({ networkId: testDbOptions.networkId }, DefaultPagingOptions)); - const dbFacade = createDbFacade(db); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: convertToLong(10) } })) - .then(() => populateCollection(db, collectionName, dbEntities)) - .then(() => sanitizeDbEntities(collectionName, dbEntities)) - .then(() => issueDbCommand(dbFacade)) - .then(assertDbCommandResult) - .then(() => db.close()); -}; - -const insertEntities = (dbEntities, collectionName) => { - // Arrange: - const db = new CatapultDb(Object.assign({ networkId: testDbOptions.networkId }, DefaultPagingOptions)); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, collectionName, dbEntities)) - .then(() => sanitizeDbEntities(collectionName, dbEntities)) - .then(() => db.close()); -}; - -const dbTestUtils = { - collection: collectionUtils, - db: { - createDbCollection, - createObjectId, - createAccount, - createAccounts, - createDbBlock, - createDbBlockWithId, - createDbTransaction, - createDbTransactions, - createChainStatistic, - populateCollection, - populateDatabase, - sanitizeDbEntities, - runDbTest, - insertEntities - } -}; -Object.assign(dbTestUtils, test); - -module.exports = dbTestUtils; diff --git a/rest/test/db/utils/testDbOptions.js b/rest/test/db/utils/testDbOptions.js deleted file mode 100644 index 04607d4a1..000000000 --- a/rest/test/db/utils/testDbOptions.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); -const parseArgs = require('minimist'); - -module.exports = { - url: (() => { - const args = parseArgs(process.argv.slice(2)); - const mongoHost = args.mongoHost || '127.0.0.1'; - return `mongodb://${mongoHost}:27017/`; - })(), - networkId: catapult.model.networkInfo.networks.testnet.id, - connectionPoolSize: 5 -}; diff --git a/rest/test/merkle/trees.json b/rest/test/merkle/trees.json deleted file mode 100644 index 8f1dec14f..000000000 --- a/rest/test/merkle/trees.json +++ /dev/null @@ -1,322 +0,0 @@ -[ - { - "mosaicId": "5B66E76BECAD0860", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFFAB3E34952CA7AF453EAAAF899665ED269A927EE70E317B47227610F686C031393CBA09D49E035945BBE3892FDEC8FC814A51189AD7FF7B2F687E1C3B29AB6BBEB59E2759236E1022696DCA895DB0517613E2CB688166C00A79769FA191C264CBE28B2D3049349C419BD07ADB00F0D6F7B41B2B23C713CD5F8041D62683DEDC17054ECF1168899B4324FE701D5B9CA92AEF9442832C673DB64C829F9FC32C62489DF233481B7FA8CAFE9157788CFC883F18B2C8099C3B3B83CAA36872818D16648B4FC07564456581775AC3260B152978C409729F51FED2D83831235138A012F40751E3ED7BDC6E80AC4E4FDF8EC5F6FFB43F3D42ABD09ED37E85B0D19FC20AD8C56CB20A3A6BDF80B537E4BEE49E5A0ADE70091AB7FEF965E5F41AB74C8BF94E3F07A3A202E823D8B79C7C878F4F63ACF1872D99C8C3C717EDC175ACC62C2D71C60E3274F9C5421ADF555BB2B03B913416E7E472287BF3B630CF704D1D35530921A8B9E3A4226AF355F8FB6C4D85E12076668D2340D17FE48DC80F62C3D7ED89A14E4820285237CBB127A9B2592381C289E601AE779A3ECFD040683F64A12C3C6C2335B850600741FC5E856BA663E60358777DAF3E4118079773FEF330F8CB88C10ACF963E72C460FFF3240C9782CEE888370F8E0C93D78DC2511257A79A56C2716E91B840B35D96AA96AAC8BFD047D1B2F357F69CA3AFFDAEE83C3731F92EF900001228231B77AB7903E7CB94D618BE80E3BEE8A9EB24D53BE45E54A652F9AE8F470E673160F69B03B8AF7780AA0E21C8D4FE7FA3B8A10BE000BED200DD83BEBD18444EB38384FB72571E575388D403F927CF4C496EC10D83FD81C8CDE5F33CC1490424A547AA107099C763B94842EF75D0A193F0C61B2614A3E2E475783C2479FFAA42FF3DAB5D79C0CE9742FA8C759FF2F09207F2338AB5BEB492CF2BEAA73CFF1B03B012D2DCCE02A98EDBD63A98106169ADC081644C405AFD6F42FBF7490DC922F668" - }, - { - "mosaicId": "519563597CF42EA5", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF141A9AC54818E26EC970C56AAEEB0332F2C25B6C59FA206EED0AA9E21F0C7E5CAF37B538EA6271BF553FB7AC5A4DD99D78EF3F90F238257E43D4D5A9BED66DB1B6F887295D2D1394D92D4F5A17F307B17C188DB047D9DE0F4F98B815FB4704E2EA1039BDC1C27CB06C5FE9C7AB0FA6F97EE40204BA5876728A1FD39E36ABA93194008C70A3F6821A991204507A2476173EFDCBB36A3F08EE0D29E5E04188C7A0A267F991CF25D1B87D272826B6194A0B555B5EB9EC404F09D694521D0385023A45F0E7EB785DC598A611D945AB04F196FC1162C655AA36A89897E5A389585C211D3F9276076D466A1F4E3A7AAFF2C0994A53C6A93AA7B87075829F49D564B30A3CA75BEBA359757F68376A5BD3A8A478326F6C8AE0BCF2B8BF29E89EBA4B2A2960DF4C1E2B62C7E24483A1D94627AD8CA982A342D95E8DE9C698A7E3389CF4B75EBECED5324F480CDDD9FE3A88C049FB5BA94A64E11A0EE45EE4C81E93DEE950C80740AA3D177A9A15A2F14F0760FA759EAFB07F52497891FF27CD1C1701D33B96C4B2159571A794C86F97AF9620E5E6171C753592CBB7451BA34FAFF962DC4EBBCA5D22FBEE63FD74723FDB4E402B2C6C96E63DA2930E0C3CD4C822FBD41116BF797B01F9521A27E5BB08DF77518C2F5F8FD99D228A761B2ADCE64656632165412ABC9294AB98C97BCC112C6D49EC63C17B4524043582DC19187A0DE099156200000638ABF705776E4FC2917DB89F26DDC140AC940C4C58521FDE87581F5BD4A127A2446FE3DF92EC2E410F6B38C79B835F897FC7D0C67C5BB471ECF0F4603112ED2E7ADD3ED7668118B4EE6DE5C2409539EBC58E5734C5CE268BF2A2FE9146A121489155B5E0DE51234F11BE5231E4108BCB46B0962FA37ED95A7C8B64EE179387CCF85CC7DB9D868350C6BA8F4C93662A5B16913332D052F12CCD51A429A74B5CB929FF3D66FDB2F95D491A7158AF20D3F3940E42A8272DC9641699BEC0AEFBB9E7D040301F3053E3A2A59F151C914E2C89507883B5F0E5559F3739ECCE88AF736B9332" - }, - { - "mosaicId": "528857FE1D09E594", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000EFFFF98532D09634A1B25B2213CD63F0D22598D75365380D67FB588757D358B1F07118D889E3FCB14DA4B3309114DDA313441C4181A83A22757DEF0ADCA22335B322E970EA0037657E836CED91439E03F78D070DF555CC038AA1DE068BB4CE2EFFCADCD1D51ADF698D7C3C6574B84C3BC9AC03ACEA2675C363153F866E8525CF09A6F964EF26A372107D5F8E15F48EF78879FEB580736BEC532219D526EE2FA5692F10C8AA5A6C0E46316418AE7E9D4FF7A59518353F6BBA633CF7329F25152F122D310A187D8C2360ADCEF1259D27BD9078B7E4971C94A59964007B6A737F6A020840DF11580578FD60C63658BFF5909CE608EC4829963CDEE522AA747C66625187C0330ADDC19DED7D2C817159B7F2FF985B9B55E32236CAFE5EB374EA610E1F07994AA89EAC2829C4900273CE4162D25F3EFE45AFEC79077F633B1FEEC130D2DD3FC9270A8F2E997D02DABDAA7A176101E494DA56E6DF1E7AECC8662E4567A9CB3172CE5E999FCBEA255BB4CEDC1B64D46ACD6C79B7CBC162D1A195B31389BCCC049987334B3D47EB513168F2FAFC4DACF02BAEE0185CFDCB55782630E5C405F80D53DDA7029B36D61EFD32DBEDF7193D0F9F7FA650B9F2DC82D9005C00AD57F53EFCFFE7BA6FA01CD08DB7D0D63B19BA805352CACA05B2992D382CA03C0FC1A9000042183CE606A14A4B0DD85427441E8092D003269B9DD84674766031CA32ECCEABEFA1B7A424421FC7FA6BC43F9F1048A89557EEA3E51C080E33C9543D8C7FB73426B1E52780482477A1D5847718BFA10E65547C3FE114E821B4613F7C971BA47C0067AAC78303801712CBA9FE0CC78A1E81B398D6ACFA86E6A56BA77DF59B5F4C2C5AFF3D7FC026FD368F2E0A8B22FB2AB0ACB8554F038C299AE2FEE53D329E5EA318705D758E3EB900728BC56CC99BD2241CCA60C251C4A60D7F4063312FB1FA051D69" - }, - { - "mosaicId": "1A8063924EA8695E", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFFA30B4BA68C25E522E783499570D58E3CC14D09B1DE70B4481C197F033BAD3DE6C50AE15E4100BF02B8495FCDE35D4EC8EEA386FE4BEC79109CF87316F1B1D539D107A2489173B859DB2198081B326A5A803A05CE23D2A9F82707E4AF6F4FCEEED3377C93B7EC37FF9C4B82E7F775493666D5B6F3526802194A7171696691990F39CE0642CE0B5A60B7A9016896D48F6E3CF00899AEC0F23099391398053FF36FC2DDE5E33A0CD50B7FA25AEA666DE1019CF33D7DB3E5503CCA74BE18A147D90A9B3D81A34F01DAF89D8A7A9BB278CBE5072A2A60A546BDE49962F75C702F65BDADF45F1F4A21403DA04EF1012BDAC851FDD5E8C0906B994CC715F285D397847C92BB329C68EB876B5F66F7DC169C90807C302305EBEE12B4855AC0B88EDEF754AE230C13786D2A5D448F04D6A173D4669075B2438ABB8AEA5ABFEA68F919AA4303B9980028FE2875CB5232397B015075F1163C7529206B87F41AB4F4417ECE18B349B4D1D6B15F8B68B39FCB45AAA42BA94E0C17C9BD24EA446F91B1901ADEB8A6FBA957A7A47F2BDCCA17101B29FD9CD21A0EC3B633483746B74402F302E565CCF107D139689086E46CC3977404C81BCFD2D83149BDCE9E6629FCB86C1973C110FD6358D8E5CC629D2DEC1471F890372D239BCDCE44D1BE4F6040EAD45946B37E85B209B0AE21232E9849C8D6BB69957D3F0784DAF7437C95B3B51D177A20D00000C20E5C4724E090B0CE79EA9895719FEF9F2D2910FB53191C1E4B0B73BAC6F89226D47FC0FF0E53742D0B05FF374F88D2DFD9C579C4AFD4D0C8AAB433D1970799AC93F97770844A388616B2E498DC0A523FBE3CC7B6CA0C3E91824E60B9496528B665CD1ADAC4949879798403D2C8A85CBA7BCB171AE732DC6B3BE1E5C3D56AF06498AA416A58EA4BF5858BAC24C503CBE50CBFC3EF65494E764129E234908A37391F264A38CE7BC0A23F84E32C08FF1086ADB89E0C3B8E52E998A4DB11B34D2239F9FF3D6AEC7EFED1B05D5736CEB9E078A3A5C15BBF87429714B04F05B6C7501AA430D30D0C98E386F58A722FE9AEBAE3D9A841AC773D95E793014D3CC85B86F1680D" - }, - { - "mosaicId": "1375FD3BE2A4A148", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF2C0D04724CBD6D11C30A75F93D22F713CCCAD06E736E8F6E4F687CE0813ABBC1E35E71E009B3B9C19EBF6CC06EE2085C3267FC4FD93314C12515B522A617E9C5740F3F5AA0F8D7029D73598978C719E4C45FB2CD546E45189E57D6E7045DE69AA8DCFC8706E64C0FE191C38BC1F4CF5370ABEEECCFA0190BD987F874D1AA2E9D69FAD4F7AAA59E653156E0A08865F1C41362E2D5F6296438E69B44B6645937AAA29D8D59184681164F3AC7B86D6F8DFD79407CA970853FFAFA04CE8755BC9A9994152930AE1E0D41FB5E6EB4E89B3F9255B8F27874C02E122972EA7ACB8F0A7156813E09F847C2340E85F879A67817DAD4405C8D2DECBC988659EF647C7EA51E8CD9CD1AF1F12FA96161B0FB8E52D618546436196ACB15C55ABD633A10183943F6FF37195A558940128971BF2052C38B138442B8511050F96E328BEFFA9014828284ECA3C6C02915C058201CC80D4F2C6F12E63C03E66AEB7CBA92681221E2336F248E0AE8273B332E3AC1CE739137DF48A930107C751BCAE802B2012C4233BA36BA0A637431A15C5722816D9DAC60B2A536E80666232A35D425E76D03C36BCDFE9AB23D3A342E621E2AB98E27ADD27A918AAD76BA928530F2FDE1422EEB0A79BA30E0FD9FFE9662CFB5A8E582498A9A7699E3EA44351D770236748722EC302A8EA4D5814A7D67E31B744DCF334A4CCDA34DA0E9985433452EC9BA4DCF677B27FF3E6ABC8DE8E8125ABD3A82B4C3D25B8174ACA51E63F2AF2293236B11DE2099E7760C3851BB217E694FEF29F6A293F8DD62D3A543568EE598CE340B5F7971FE82" - }, - { - "mosaicId": "5D7ED90D46ACD313", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF439E481275324AC9CDA37836479AECEE489EEB5FA3D8846A5DE00BDC37002207F74396018974421060582F4D57D91DDC03E65ECC3BF5D879321E616A0AB1DC642811E5B14B9CB7CD7695F2EE8F04DC96FC67A129D3682BB76432BD4C6372BD33EAB7497210D2A11D163B05031AB386F4D60C59E63FD9EBBB37B4519B1C79F38CBB4FD13ADBDB25470036F701764AE0C08EC2628D8346A6AA139A7189B9BDA20A05E53963A4C61B8DF20FE68D384659C12231653C56C3277DCE81D18E371E30DDC045B7C4F9315D4054A7C40B79255229F93A1BD4A5B69087F1B4EBFFE43A6533881BDDCF4B911381C0F97CD07CBA9D3E2423BD72DF20E9F69155439689A98D0665CB3D0EA6A521CE2BCB740B4DCB14E73B9D6F55B4292C3D779ACE47DB5039CBC41FF374A99F57C7287864D3E25C41CD2F4C6DD03BD29DE08B2B5CE6A96251953B486B514DB8C5E8873AB53E15AD9A7E968D8356DEBD504BCABAB4EEDC50C79DFED3204DF3093A159BF47A48E5ADE144FB897D4B784FD76E29CCBA9944FC665917FEB0F22A94E69BDCB58B7DA7C879DE3C3998728A1727014B7060233F7292904398C0FD9BE0A774A39D4C980290E1737ACF28F26A30C315A0954C7654BECFA15D9634D46BDEBC0FBD54C0ABBCE1285E70C9592FEE28444E34893BBA22BD8334719B2169EB49FE972A54CE657DFB31F2604B463820752E5889DE45E51204B4F700004C7C120E516A440DE2D15CE8E80F245074FF7380745F2CC4D81C684737C4032A87E1D6B6A481CADB17719388CC21256FF90D926CF9A47095A99CFB75F65F08F5878F02F436ECB019C00650BEDA172ADE83B18BB48BDC50D804861D88363A4E5038799D878482968E06F27213A2CFE90F3238695209E2729322A83843135A399A247F15ED0FE5B44DD5FA07EA926B0D2323775A2200C386CA88D8FE2ED37B819BB590F9EC0CBC3D39CE425FABAA5065CA32350D549BA57111776E519E4F40D16DCAB460FCDE861054EB5B884E8E651F53B5CB3D0B09754E7DC272F1575E32CCE248694B71CAE59DB97BCFFA1A2DD8EB62DC56E6DC0955ECD757CB73AC3A87F75F9E75FF3D7FFAD455BAE58FB48B1DCCD5EC3F54A6518442E8E53C1C990874D848FF0B405F9F62579942C8F27677FF4F21F820DE915F343F6923151577A0AC45A2EA9F45" - }, - { - "mosaicId": "190330ED8E417416", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000EFFFF98532D09634A1B25B2213CD63F0D22598D75365380D67FB588757D358B1F07118D889E3FCB14DA4B3309114DDA313441C4181A83A22757DEF0ADCA22335B322E970EA0037657E836CED91439E03F78D070DF555CC038AA1DE068BB4CE2EFFCADCD1D51ADF698D7C3C6574B84C3BC9AC03ACEA2675C363153F866E8525CF09A6F964EF26A372107D5F8E15F48EF78879FEB580736BEC532219D526EE2FA5692F10C8AA5A6C0E46316418AE7E9D4FF7A59518353F6BBA633CF7329F25152F122D310A187D8C2360ADCEF1259D27BD9078B7E4971C94A59964007B6A737F6A020840DF11580578FD60C63658BFF5909CE608EC4829963CDEE522AA747C66625187C0330ADDC19DED7D2C817159B7F2FF985B9B55E32236CAFE5EB374EA610E1F07994AA89EAC2829C4900273CE4162D25F3EFE45AFEC79077F633B1FEEC130D2DD3FC9270A8F2E997D02DABDAA7A176101E494DA56E6DF1E7AECC8662E4567A9CB3172CE5E999FCBEA255BB4CEDC1B64D46ACD6C79B7CBC162D1A195B31389BCCC049987334B3D47EB513168F2FAFC4DACF02BAEE0185CFDCB55782630E5C405F80D53DDA7029B36D61EFD32DBEDF7193D0F9F7FA650B9F2DC82D9005C00AD57F53EFCFFE7BA6FA01CD08DB7D0D63B19BA805352CACA05B2992D382CA03C0FC1A9000001B13AA2312D7A3226E75CC5970E70DC532FE42F30260B0345579915C0A8AFA6E16877A447327CC5E2FE7B047278826700FBD44C371389175A5EE9813AA19A1D4E7440E9789E831C976931BE50E0EB938683CCEF03A14527C553C62FFC9CF71653DB95671ED5DA4A942D17FA1ED13C7A3AE90FE6A8B1402549DD386B0EBA38EEAE047AD2D2E6CC95328E20063FA54704559F9878788223A55EDD321980923783A7F400004002A1C6CE4025E057B9A4D057D657983E26AC010457286D9CC8C56439F77E2A25B21E338DA43EF8DF028E01EDAAF05E0C9F8493E3EED2B289454D77671EE5B8B099FF3CE30FBC8FEFAC03BBA99AF8F0C9B022EDC0397BAAF0EF7FE54D48E8BB5611A0075FB8D10DF9A56FE82865251B02458C3B1772BFCBB29CDDC99B945C3D5104" - }, - { - "mosaicId": "0473E198B87823F1", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF15DB769E58F129790A6BB42939AC0D815AED22A0DD72F5620C033C48535D134312E7F3BA54BB00A8FCBFB9B3F45E79A435F150BA786AE56AA3434E6F3E9E2E26D36FD6364AF1504BFC82DDA1048F98EDBDE6B3DCAE76A84222917F8DC779FA65073304D81CDFFC394899A90874BD07C8BB0ED07C54D3719BABE610311A37CD1A2AD3842B9F7FE7BE858AFCBCB6E1203DBCC50377406F330F0C4DD0681B4EB7787A53027126A4513FF5FD108436CA96C09A83F066440C55417B8613508CD8540D1F6AF50C6CA4454DA7B7AC9CCEF2AD94DA244CE32EE30DAA2F60E32397D7405EE90A1E55BF612821B9E12F389660DD672AD995079964AE5227F4319DA8F9670956A0A25D20B38DEC4D24763D99177511CBFB869D27CC5EC646525A7EBA9D62693B6B9D90C8E9AC9656B7CE42895F1AC17D38823EAC16DE174AE0933F74A5EBA06C9381B4C27466B45627216723FECC90F4A0230C1E5A4961541978DF68BF901261A932B441C4FBE315FAEC51633E965FB5CE20F2BC08A357A0C9C389E0112B48EDCAC5A8980F2541B7EDF4079EE914C3C6BBA376F64DCBE9622BB9003A24EFF92C79F0B59A4A10154C7C152C72A95E5F2D52BD390E2231DAB1B4C1064CF85D0F0C4EB6482097C1AC6827CF28ADF609F5E5C66B533FBDA1A0E797263E9D8E2BBBD9203FFC243068183E9A5C1C1B2AFFCCFF892E36C407905AFA21CA5132698F0100002240B3594B79EB00E8959F32A1E102D325C2ABD5AF8B482EB0FF90E88FC49E6CAE3AC33EB13987A1C9467C5D6B036FCD48691B745B024FE1B26EAE94EBCA57E905CBC99D4F6D79A010875F683BD03F7EAC577EB2841C47443D0F8BF339446006832C00008800D1E398B614E72E1CCAA2F9720FA0BC19BBBC44C075F8939FFDEB7A370C8C2CDDDBA5ADEDF776BB232B6979EB397B16CB931CDAD3AADDDAA2C637537103BA90E3FF3C541CEBCF66C1500355C20B0978D571726155756E63604C4D5E00859E2D9A4266C1FFE0B25CA94314751CBF4D5710CC20A47F2B6F309B1ADB117B19544CE5" - }, - { - "mosaicId": "4B98249B605AEF11", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF4ED978E00348F64C9D13E0027B279B08D08D16AA495E0DEC28C44AC386571A646B4C4AAB0B1EB5C54B4F392C23E4D06142AF26BB82EA479FC3CDD7FD48182931546574D8FA0940E15D2795B6016400DD4F946F7DB597EA3E0CAFFCFC1F6D3AA6222F051D4FFDCB639BBD2DB9B912EF837FD354BD20754F3E78200837C235AE0FBFE624689631A55F6104EE6BC52462CC97BA543F00FB1C3094B7B33263646DEB32DDCB1B9ADC13B15FE1E390BD2C37B0EB04F901EC026CFB5629FFBBD8ECEDF27FB3C32B2E11D9D10958D82C9AFF9E1C8601CCB0DFD8AD5A3D18BCDEEDB1ABC6B7E9500AA89B2C3D669EB709A4F306FB4D13FCE488B325B5263561E6124BA28AA30BC1DF89C0BC38D765319B475557AEDB8A6BE655A0DC3E0C0CE782B8E4FF35977DF81AB71963F868EEBD1CFFD4659EE9028E8DD26428DA20434466E1E9471E5CEEDD1059F400F43452D1ED54F519832076889635A5AF8B536BBA1F5ED3869DD00A69D5D2B021DDD373AEC19242A6E815AB0C682BAE51E3F6A8E4E2AE3182FEA814937FF7B5F3E8CEC537133837EA396E787A14FCA2F78FDBE6932A81BA019D0703C341EF914DC4FEBB6F5A656BBE4AC10B48D69FECE38FDE3139988CCBEB5BFC7F74D07F9436CC68845DC074AC9747F2FA6F761FC038D51C534DA9FB2F37E47DE2FDF9475264C42CAA6F21200B49847B09A20564C90E183A58D6E07F579CF40000082A084B458A408390A88A57585C2C7B5C492F77637519D41FAFBF30DFF6E8EC87B18895240F6DFD940C5B7503404EDB5B8CF97A4931361148AFF18B0560E902C7018A610BB612C83EA14A217B6661384F9397068C0ECC2F8F4EF88315163FBBEEB0F5F28DE4680FC0BF09BA285A3CC0D92346F78B0581240C6F0EB83E4CF06702C4FF3D5CA8ADFE2139BFAAF889A9A3506E809A29A4C5FB484E6AEBBB87D89FD34C200951C4D25BE56053F4F672937D11652404A1B92FF4BCA7C79AA7A4B0789052CF" - }, - { - "mosaicId": "74784E0EA0CFC38E", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FF7F23FD25DF133D7DD7F677F15E835E3ACB7A97F37EEE8A3C3FA14DCCF8D39902C68B2AAD5C33B43D29A7745DFB6594B5321113DBB334CDA627BCF4485B47E30AC97DDA5EC410409B2AFDF6D8A2C5D3971FF3DCC789FF782276A29AE81C427F7FEE0B3009893B0FB69BCB8702301994ADF8D7310039EE25D49026534579DFFDEE35152037CD9B3BACCF038B684B9F710BD2CFFADE42AA8D89FB6B747A059635C8DB536FDFC4288096A7BDC333BB3FC28B617E985849B3C5798F67558FE58DE726705EC894B00B807C5A988072C1C19B8280D087D846061CC19683906BAAB76E22C68F857161ACF6D9C66D031EA24A343E50F115F580A346CDAB5AED2BDF58FDA344B466FBC811ABEA1CB9942CBFAFB12EE7557281DD1031F1064D5A75AF4C7799D384D408DAC9FAC6C1380502FA0B399E779051D8E47D096FF12760636E16E9E4D00B4248A0EED496071D2C54E137356F173D6457E13E875C430EBC1F73CB79CBCACFFAF99EA98F45C655E759FE265D1A3944C623E4676C616DEADCEAE440E3308E94B6FEC6C67318DBE7D9ACCC4D26F634F422E1A65EDC3BDEE9C3E0FB16C3EE9DE2299A226A0B45FF12D2AD72A0B11BF96A3623AB1FBB519955A90E1F5AE4FA1159927C0498F62531F2AB02DF3ED5BFED1A13FC91C42BC4878F65A946DE4D3BB300007551613D4769D50031D19AEF78B981A00EA1F56631D3343C6FFD31F011112F51FFB9B8491F3220B73D88CD3E7D12D2669A85C4D582FFDC494F1877F04338A5B328169AECBC81FFD7714575DCA92FAA540826943DC0BEB45EF8EA576090ED6D1EFF85E448863705A49CCBE4441D3047D3501A8C57E524C1616464B18018B6CB7245B352677E15E288F57F7021E69CDA1354DFB82D663DB1A85C8B268E567073F1758E7B9827D54FF82353FD321F98797E9791E4B85D7832C416FF5042AC4D674B434941CF238D7AF1EA05EC7A2664D61AE76FE56E89B96CA8EFA72FA40CD938B38F1D2F978DDA0F3F7F93783007D78CFED7FE471FF0A4B11CA29984574864E619EE9CFF3DE65EE1A7A441D9EC31E32B1074EFDFE0C7E891E526B8D08F38282EED89749072B1280FE139F59A7C1603CD4E9D341507549D2A2F1BDE7099537BB8F75F8FAC" - }, - { - "namespaceId": "A95F1F8A96159516", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF4ED978E00348F64C9D13E0027B279B08D08D16AA495E0DEC28C44AC386571A646B4C4AAB0B1EB5C54B4F392C23E4D06142AF26BB82EA479FC3CDD7FD48182931546574D8FA0940E15D2795B6016400DD4F946F7DB597EA3E0CAFFCFC1F6D3AA6222F051D4FFDCB639BBD2DB9B912EF837FD354BD20754F3E78200837C235AE0FBFE624689631A55F6104EE6BC52462CC97BA543F00FB1C3094B7B33263646DEB32DDCB1B9ADC13B15FE1E390BD2C37B0EB04F901EC026CFB5629FFBBD8ECEDF27FB3C32B2E11D9D10958D82C9AFF9E1C8601CCB0DFD8AD5A3D18BCDEEDB1ABC6B7E9500AA89B2C3D669EB709A4F306FB4D13FCE488B325B5263561E6124BA28AA30BC1DF89C0BC38D765319B475557AEDB8A6BE655A0DC3E0C0CE782B8E4FF35977DF81AB71963F868EEBD1CFFD4659EE9028E8DD26428DA20434466E1E9471E5CEEDD1059F400F43452D1ED54F519832076889635A5AF8B536BBA1F5ED3869DD00A69D5D2B021DDD373AEC19242A6E815AB0C682BAE51E3F6A8E4E2AE3182FEA814937FF7B5F3E8CEC537133837EA396E787A14FCA2F78FDBE6932A81BA019D0703C341EF914DC4FEBB6F5A656BBE4AC10B48D69FECE38FDE3139988CCBEB5BFC7F74D07F9436CC68845DC074AC9747F2FA6F761FC038D51C534DA9FB2F37E47DE2FDF9475264C42CAA6F21200B49847B09A20564C90E183A58D6E07F579CF400002093641B858E25B1F49E83CED307BC9E0E8848501F582769A53D7455917A848F54A8CEE68574ED1995A1C4E34ADB2D18A7E7FB5F49A51EEB739861CF60CC3807DA47ECCC2BF41820D17B1518A2B297750ABD9D267670FE6EBE0AD482596578E3409F8451289D0B61D0F805720290A0686E8377613B4242CE4AD11A7A369718392ACF350D5C525CA1F2F15C00CA1DA719DDD1CEF056F3669EF398A12B0A171F4A3D08" - }, - { - "namespaceId": "E74B99BA41F4AFEE", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF39F0C9E2AE57B9AC984F44F9BB48E7AE3F26B7486431FFEE4F09B83C8FD093DA5520E6D1314507C8DAF4AA20DAB56C13DF3D7417FE05E980AB1FD37E57D65C9BF78277752F0C164923FC6308F97C412616375C465F506DA255ED6AB483D4162C7BC5CDD04424282434D09B68F00DB80ECFF1DA7C2273387EE1494E80E3EBC80725C5E1BE1381DD70FADA41CF214033F84B90745AE3DBB09000713D2CA78E953742C0987452F2CA61794D092231AE8A18163794F3C07742C35C24B96E712A34396B1F513EB9D002E14BA1B50EBF444D236D86CF83EC2D4E27E0A6313C318A22D08F61131851A049AF7E69785E1B4035AF311BE8FAED1BC1001191B4DBC177E7AC5F4446A2985A2FCF6AE749388914F328F0AFC50AB1B866EF3AD557E7054A35A9C694DD638D85118045FCABC24B0527F09BBA31D5AD91233310F8540797F1860A41A9B46FC9F7C169C028084A34E712A5E0C6CA57F2DFA0F45660233CC2E628A18186C884953CD3645C96D54DF9FEB1250B347F5AC60584B431F590F8EDE7FEA24E4116C36A62B7C70F1C6DAC8EDEE8585534627ABB584ADB00BDF32BCFF9E9401C6A0ABF263894A01A13EA65E23CD1F8DD6678BD03AA097FD107CBB8D51B7DA8F97C263A409AED02293740CBCAE58168A7E9BEAE2492CA7544C7E1E91A6C0D5FC3A645A96AC1694F87C9CC65EE4AE9346EBFDA122CDB6E429803DA20F75C65FE00000642082F1B54BABB4A76A8C98F6C9BDD4B1DBD501DA1710FC3C9E681406D11BC091DDEF1E82C605152819EF0D4F282D0054CBE6C1125DD83C7354AF80C66DA5FB63797674530EFD3DE3DB58EDBF709CCE93561DF9EEDB7B4827AEE532276E1283ACD6EE58788DD0874458144B7E9EE58A5BFF94D53B3D67D488E4B3251F0F5497506" - }, - { - "namespaceId": "EDF799C2A9356501", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFFD381A7265538BF7E9A45D41EDFC76D71FFB5DE7821D7FC8325B35891EC917A0A3E314AC74E93DE3247929556000DF6B33481257E08643CE4A44ACC04FABE2733A1C74BFFEBC6789993DAB815BAB036495C487A96CDF3BF4B48F3D737E3A1A00B737DE571F325045DE4D50D9B60FD263A3780EF82A490EFAC5E489F5648DD848302BB777D45BFB8C1EED97E039A017CF326804772EE776FBEFDDEB99A17AF7FEED9D70D4AC340D7B61AC29F3A3039A3954DF36174447C48CD5B94E2363B14EAAEA129916A5BDC623D8EF1D07F2F6047EF35E860712E17C626F2C1B80FC8A76894D7F6574CC585D5452179970D369457022BE0ABDCA064B614464709C5F6C4B82E239321AF0EE32012B5E75AE64D47D090CCE6D45CAB18073AF44789B45C74BC1C7572B56E9FE599DCCCDFF2CF76392DC7C37DE96D659B3C62BAE04E722D09BD58B408C5720BEEFE539A5350168B235F0E3A123425A96CDB502AD54393BF65164C07CDF13ABEE3B6A90C7C92364AB79BF3F47FDD67800B2E51AF850C5DA13EE96514CAAFC2C8C01FDA0F5D02E2E9277FDE887DEBDB6E1B00F522AED5C883609C9373F71A6C794CD6C82157A889072169B0001E4CDAFCFA4800C04DEFBBFDE7580A6DC77AE0A03F18BAA82567596E8488017ECE98100928CC57A5ECEA12708412FB1F6897FC52C460519A61710838C6561E43C726E1AC87F119004320E748228B25000010A1F8DF029A798033E16DD1755C74369C64365A1008A315B05FB318436866C4D86C485A7B3254B2AE5CDBC47FE64F66C20422AC704D7E5E4E37D98AF313D2400A886C7486ABE09247512A6757AC32320FF36026B084277922D0F8CC45340154C650023A97E08401A781E6066B71C27EF2D480E37B0C12C8D4BE2793C1E713EF00A6" - }, - { - "namespaceId": "CE1899D22D4AA311", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF439E481275324AC9CDA37836479AECEE489EEB5FA3D8846A5DE00BDC37002207F74396018974421060582F4D57D91DDC03E65ECC3BF5D879321E616A0AB1DC642811E5B14B9CB7CD7695F2EE8F04DC96FC67A129D3682BB76432BD4C6372BD33EAB7497210D2A11D163B05031AB386F4D60C59E63FD9EBBB37B4519B1C79F38CBB4FD13ADBDB25470036F701764AE0C08EC2628D8346A6AA139A7189B9BDA20A05E53963A4C61B8DF20FE68D384659C12231653C56C3277DCE81D18E371E30DDC045B7C4F9315D4054A7C40B79255229F93A1BD4A5B69087F1B4EBFFE43A6533881BDDCF4B911381C0F97CD07CBA9D3E2423BD72DF20E9F69155439689A98D0665CB3D0EA6A521CE2BCB740B4DCB14E73B9D6F55B4292C3D779ACE47DB5039CBC41FF374A99F57C7287864D3E25C41CD2F4C6DD03BD29DE08B2B5CE6A96251953B486B514DB8C5E8873AB53E15AD9A7E968D8356DEBD504BCABAB4EEDC50C79DFED3204DF3093A159BF47A48E5ADE144FB897D4B784FD76E29CCBA9944FC665917FEB0F22A94E69BDCB58B7DA7C879DE3C3998728A1727014B7060233F7292904398C0FD9BE0A774A39D4C980290E1737ACF28F26A30C315A0954C7654BECFA15D9634D46BDEBC0FBD54C0ABBCE1285E70C9592FEE28444E34893BBA22BD8334719B2169EB49FE972A54CE657DFB31F2604B463820752E5889DE45E51204B4F700002109209C00292C3D9E291EBC7B074407C77F50D292DB0BF6E17D7B756F8E37F5C0AFA212A8B36F1CEEF152CA9E913AF0FDE223BF92E70D9EBA8444C8590EFCF55B1EE4CA18E5C6516E3E0492B3076FCE5F98A4DECEC47292A4F0F5F972EE967BDD010ABE033CE2E6470C1F957C1C67C5F02EE4F93D05749E3766C659CFEC78B287DAFF3DD3659D9DB92829B5598B97A9F21A48CE39168EEFB2B2FB5DB9A74409EE11E083F51CBEA89465AEF0E5473A90726A156B30EFFD7E0BC467B3481F50E17EDC46" - }, - { - "namespaceId": "9D163A9E230037E6", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF439E481275324AC9CDA37836479AECEE489EEB5FA3D8846A5DE00BDC37002207F74396018974421060582F4D57D91DDC03E65ECC3BF5D879321E616A0AB1DC642811E5B14B9CB7CD7695F2EE8F04DC96FC67A129D3682BB76432BD4C6372BD33EAB7497210D2A11D163B05031AB386F4D60C59E63FD9EBBB37B4519B1C79F38CBB4FD13ADBDB25470036F701764AE0C08EC2628D8346A6AA139A7189B9BDA20A05E53963A4C61B8DF20FE68D384659C12231653C56C3277DCE81D18E371E30DDC045B7C4F9315D4054A7C40B79255229F93A1BD4A5B69087F1B4EBFFE43A6533881BDDCF4B911381C0F97CD07CBA9D3E2423BD72DF20E9F69155439689A98D0665CB3D0EA6A521CE2BCB740B4DCB14E73B9D6F55B4292C3D779ACE47DB5039CBC41FF374A99F57C7287864D3E25C41CD2F4C6DD03BD29DE08B2B5CE6A96251953B486B514DB8C5E8873AB53E15AD9A7E968D8356DEBD504BCABAB4EEDC50C79DFED3204DF3093A159BF47A48E5ADE144FB897D4B784FD76E29CCBA9944FC665917FEB0F22A94E69BDCB58B7DA7C879DE3C3998728A1727014B7060233F7292904398C0FD9BE0A774A39D4C980290E1737ACF28F26A30C315A0954C7654BECFA15D9634D46BDEBC0FBD54C0ABBCE1285E70C9592FEE28444E34893BBA22BD8334719B2169EB49FE972A54CE657DFB31F2604B463820752E5889DE45E51204B4F700000158CA649F912308B69AB7C62032D481C6B10C2EFABD6D1AD94C695257C7CE9C935892F6AFC6F5F413A3125027A22D376B392DA2BA58B8CCFE8974337F51985F8F069FE0A48F2C252A5DED97F843F1D22D2727AC35E4C994F6D59A432C99CFA0C76C8CEA8D7AA18BF3586870098F4985219FE71E8F32255189CC9C4FAC0062087FBF" - }, - { - "namespaceId": "D12E930CFB8AC5A3", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FF7F23FD25DF133D7DD7F677F15E835E3ACB7A97F37EEE8A3C3FA14DCCF8D39902C68B2AAD5C33B43D29A7745DFB6594B5321113DBB334CDA627BCF4485B47E30AC97DDA5EC410409B2AFDF6D8A2C5D3971FF3DCC789FF782276A29AE81C427F7FEE0B3009893B0FB69BCB8702301994ADF8D7310039EE25D49026534579DFFDEE35152037CD9B3BACCF038B684B9F710BD2CFFADE42AA8D89FB6B747A059635C8DB536FDFC4288096A7BDC333BB3FC28B617E985849B3C5798F67558FE58DE726705EC894B00B807C5A988072C1C19B8280D087D846061CC19683906BAAB76E22C68F857161ACF6D9C66D031EA24A343E50F115F580A346CDAB5AED2BDF58FDA344B466FBC811ABEA1CB9942CBFAFB12EE7557281DD1031F1064D5A75AF4C7799D384D408DAC9FAC6C1380502FA0B399E779051D8E47D096FF12760636E16E9E4D00B4248A0EED496071D2C54E137356F173D6457E13E875C430EBC1F73CB79CBCACFFAF99EA98F45C655E759FE265D1A3944C623E4676C616DEADCEAE440E3308E94B6FEC6C67318DBE7D9ACCC4D26F634F422E1A65EDC3BDEE9C3E0FB16C3EE9DE2299A226A0B45FF12D2AD72A0B11BF96A3623AB1FBB519955A90E1F5AE4FA1159927C0498F62531F2AB02DF3ED5BFED1A13FC91C42BC4878F65A946DE4D3BB30000E840D53789E5A7D3FED8BB3D8B82DD19E5BAF3BA351B33B84DA95066075B76EA62EB3592777F194AD4F2FF9F5A93C8496C2A60028010A8DB631BD12A9EC01C6761922547EDDBFC42B08CC75B9D9E14D74C527715E1C4A97CD6FB800BC4AFC4E65AAED682BB2BBDCC9731ADDDBCB46ACD910AFA0C611965022B029100299E16B58CDA5BC73DB771903B656444FF0A35FE77B8CF55D6DBE91F57AA6247F8DEB9295329FF3DEC230A93342083B8813359A26F8247764AE6667FDA04979936A16A3B010810DC8755176B8AB57974D635DCC6F4EF5D54C7C0257529D5D7358C7D098909999D" - }, - { - "namespaceId": "B420875AC0C07947", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF15DB769E58F129790A6BB42939AC0D815AED22A0DD72F5620C033C48535D134312E7F3BA54BB00A8FCBFB9B3F45E79A435F150BA786AE56AA3434E6F3E9E2E26D36FD6364AF1504BFC82DDA1048F98EDBDE6B3DCAE76A84222917F8DC779FA65073304D81CDFFC394899A90874BD07C8BB0ED07C54D3719BABE610311A37CD1A2AD3842B9F7FE7BE858AFCBCB6E1203DBCC50377406F330F0C4DD0681B4EB7787A53027126A4513FF5FD108436CA96C09A83F066440C55417B8613508CD8540D1F6AF50C6CA4454DA7B7AC9CCEF2AD94DA244CE32EE30DAA2F60E32397D7405EE90A1E55BF612821B9E12F389660DD672AD995079964AE5227F4319DA8F9670956A0A25D20B38DEC4D24763D99177511CBFB869D27CC5EC646525A7EBA9D62693B6B9D90C8E9AC9656B7CE42895F1AC17D38823EAC16DE174AE0933F74A5EBA06C9381B4C27466B45627216723FECC90F4A0230C1E5A4961541978DF68BF901261A932B441C4FBE315FAEC51633E965FB5CE20F2BC08A357A0C9C389E0112B48EDCAC5A8980F2541B7EDF4079EE914C3C6BBA376F64DCBE9622BB9003A24EFF92C79F0B59A4A10154C7C152C72A95E5F2D52BD390E2231DAB1B4C1064CF85D0F0C4EB6482097C1AC6827CF28ADF609F5E5C66B533FBDA1A0E797263E9D8E2BBBD9203FFC243068183E9A5C1C1B2AFFCCFF892E36C407905AFA21CA5132698F01000042800AA20D464FC4BDED0C86EE64E02DEDDBD134C53798A42CE119B14909279CC4BB3CC39B7756E1B1E951D614EF1CAD75B25FBE7C839C4DC0DC17125BCFF0CE544291A664A1630BBB3FFD275601344BDF522F2F52A917B6C93752B7CC8143512417" - }, - { - "namespaceId": "ACBA2E41C057B1E7", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF15DB769E58F129790A6BB42939AC0D815AED22A0DD72F5620C033C48535D134312E7F3BA54BB00A8FCBFB9B3F45E79A435F150BA786AE56AA3434E6F3E9E2E26D36FD6364AF1504BFC82DDA1048F98EDBDE6B3DCAE76A84222917F8DC779FA65073304D81CDFFC394899A90874BD07C8BB0ED07C54D3719BABE610311A37CD1A2AD3842B9F7FE7BE858AFCBCB6E1203DBCC50377406F330F0C4DD0681B4EB7787A53027126A4513FF5FD108436CA96C09A83F066440C55417B8613508CD8540D1F6AF50C6CA4454DA7B7AC9CCEF2AD94DA244CE32EE30DAA2F60E32397D7405EE90A1E55BF612821B9E12F389660DD672AD995079964AE5227F4319DA8F9670956A0A25D20B38DEC4D24763D99177511CBFB869D27CC5EC646525A7EBA9D62693B6B9D90C8E9AC9656B7CE42895F1AC17D38823EAC16DE174AE0933F74A5EBA06C9381B4C27466B45627216723FECC90F4A0230C1E5A4961541978DF68BF901261A932B441C4FBE315FAEC51633E965FB5CE20F2BC08A357A0C9C389E0112B48EDCAC5A8980F2541B7EDF4079EE914C3C6BBA376F64DCBE9622BB9003A24EFF92C79F0B59A4A10154C7C152C72A95E5F2D52BD390E2231DAB1B4C1064CF85D0F0C4EB6482097C1AC6827CF28ADF609F5E5C66B533FBDA1A0E797263E9D8E2BBBD9203FFC243068183E9A5C1C1B2AFFCCFF892E36C407905AFA21CA5132698F010000202045CCD82748537DBEFD1C833E410992077EE089F3F21AEEF6264BB3E9F2349F92AD4EBDC3F32F5EF2DFEE034495ABBF2B37672DFE63AEB7C930C68B5641B0AAECFF3D9B22655EF9ED0AA23A4891659CF195E46536CDAA18317B692BCCE16CA61B205CDB8C9243CD96263685D8CD9528C867B9801A29B9DE20CBE5EA07025548EB25" - }, - { - "namespaceId": "E85021AD09616799", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF439E481275324AC9CDA37836479AECEE489EEB5FA3D8846A5DE00BDC37002207F74396018974421060582F4D57D91DDC03E65ECC3BF5D879321E616A0AB1DC642811E5B14B9CB7CD7695F2EE8F04DC96FC67A129D3682BB76432BD4C6372BD33EAB7497210D2A11D163B05031AB386F4D60C59E63FD9EBBB37B4519B1C79F38CBB4FD13ADBDB25470036F701764AE0C08EC2628D8346A6AA139A7189B9BDA20A05E53963A4C61B8DF20FE68D384659C12231653C56C3277DCE81D18E371E30DDC045B7C4F9315D4054A7C40B79255229F93A1BD4A5B69087F1B4EBFFE43A6533881BDDCF4B911381C0F97CD07CBA9D3E2423BD72DF20E9F69155439689A98D0665CB3D0EA6A521CE2BCB740B4DCB14E73B9D6F55B4292C3D779ACE47DB5039CBC41FF374A99F57C7287864D3E25C41CD2F4C6DD03BD29DE08B2B5CE6A96251953B486B514DB8C5E8873AB53E15AD9A7E968D8356DEBD504BCABAB4EEDC50C79DFED3204DF3093A159BF47A48E5ADE144FB897D4B784FD76E29CCBA9944FC665917FEB0F22A94E69BDCB58B7DA7C879DE3C3998728A1727014B7060233F7292904398C0FD9BE0A774A39D4C980290E1737ACF28F26A30C315A0954C7654BECFA15D9634D46BDEBC0FBD54C0ABBCE1285E70C9592FEE28444E34893BBA22BD8334719B2169EB49FE972A54CE657DFB31F2604B463820752E5889DE45E51204B4F7000000C1505CB630E86471483939939FA6F1644E6438DAF6A401927DC0CFC0257804F764EDF7513C4C29C40BF0F8348F2439C815DB518E3D755EE7A758A328895A4E9FFA1D5408F53879CA881671937A4248288C6BD304F9CCE5E4801934EE3CA1967C82" - }, - { - "namespaceId": "9CF66FB0CFEED2E0", - "raw": "0000FFFF7DA075B4B4778C304DE54648FEF7AD1682820378DDF2B591315B04778BF2802B95756FF916EC067DA8275EFCBD41F6DD322BC705527E9157E0B1C06C63560F4FF502FB815633CF41DFA3142AAF54A4C054202EB307C10FBE2D877781BCD09633F31C0015AC43E57E59927315A6D058C7E56082238C08323D490468AB2010BE365DA6B16056AD64106E88E8C829B2A862181B147BC567725DA8D8083210DF3BB7A726386BD9C09BB4B32253DA02EA5D5BFC35D77E5BDA5BB6B283D06D16C44F58A6E311098469EEFEAD68FC6EAA4A739F8864CE2E73DFA123416C789F54E91C957CB483BCFA2F15605F9E11D438D6B2636B12221BE1531FFC1C20C4A0B9B258A6A51F6D311A2823EE2D32F35875FCCA812ED80963F03159ABE19217D17A770A32993EBAB037A4F66A816B89FBC7E13CE2AE89149736891F37BD7DAAEFB2147DF6B3D87E12DF6F6EEB45C16EE097C012348D06D97EE565B16034111B07122218D339C3E38D4A67AAE5F08607DA8D06E64CA0BA7A2511D8AC09C0694F3AE4C13D8C09538BB1176A876C6A38E08B613602C99C13450974A8FF88AE1B8D0B9D85487B064D6AF8375E357E8EE2235E67F4073DD0B8B24BA4D652FE748F06A3CFE36AA8625834731F55EB2536B4AA17D6D65EFC5C456024F4711B54D9CD45299F1B25404BA7D1326D585C1265D2F0C5316B4701237865C23638E3AFEC7C4C615BBB7B740000FFFF141A9AC54818E26EC970C56AAEEB0332F2C25B6C59FA206EED0AA9E21F0C7E5CAF37B538EA6271BF553FB7AC5A4DD99D78EF3F90F238257E43D4D5A9BED66DB1B6F887295D2D1394D92D4F5A17F307B17C188DB047D9DE0F4F98B815FB4704E2EA1039BDC1C27CB06C5FE9C7AB0FA6F97EE40204BA5876728A1FD39E36ABA93194008C70A3F6821A991204507A2476173EFDCBB36A3F08EE0D29E5E04188C7A0A267F991CF25D1B87D272826B6194A0B555B5EB9EC404F09D694521D0385023A45F0E7EB785DC598A611D945AB04F196FC1162C655AA36A89897E5A389585C211D3F9276076D466A1F4E3A7AAFF2C0994A53C6A93AA7B87075829F49D564B30A3CA75BEBA359757F68376A5BD3A8A478326F6C8AE0BCF2B8BF29E89EBA4B2A2960DF4C1E2B62C7E24483A1D94627AD8CA982A342D95E8DE9C698A7E3389CF4B75EBECED5324F480CDDD9FE3A88C049FB5BA94A64E11A0EE45EE4C81E93DEE950C80740AA3D177A9A15A2F14F0760FA759EAFB07F52497891FF27CD1C1701D33B96C4B2159571A794C86F97AF9620E5E6171C753592CBB7451BA34FAFF962DC4EBBCA5D22FBEE63FD74723FDB4E402B2C6C96E63DA2930E0C3CD4C822FBD41116BF797B01F9521A27E5BB08DF77518C2F5F8FD99D228A761B2ADCE64656632165412ABC9294AB98C97BCC112C6D49EC63C17B4524043582DC19187A0DE09915620000040122FE6EEA5EC1591F0AB3F490738370D0A902D87F5946219530BA8315ED9FF0111E7D1702677695BD93064C04372AD24A5A893D75B6F495EC07A40539143993FF" - }, - { - "address": "9818267928596B214CCF27AF6E989F63CABEEF6A85AAF4D6", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF8936B2FDBC11C90CB6B3FF92A95CAC7E4F9C10855FC454E486BE234A22A43A3995E2D0606E9720A7A8843785A60FA9BB9541B86B7B361EB46C9C4C89565D2FEE7FA21D6620A6BAA473552DDF2AA903D5F277C9ACD403D73AC035F0080F35128EBA6A13F00FE17136D63791ACB4BA0DA646E6A4840B4EAA2694EF97C58AC758DD6581684DCDABD4F1E295627B9AB666A83A1AAD21591D98319BEBDE794163EE872E679E456ED5D8E6603FFCF6DC4FB46B4561AC1464CE99A63C0502C87580AF59BC80129A00CE3C70A6F8366E76DD31D347621CBD17458F164131A0CB2620209D1F9C5455C13E840D43CD3D5B984F777DB4B11E81DF61B678F0127EF8483DB72DBAC36927CD90F563BFCADCAE9BAF990FBC0006CCFE1544C6EEF544B05B8C6745B749A08B2745B2DD0C129667C8F61EF5C5B97A4218A51DB8638CA4BF3B238DE2BE68D548C9E8CB636B80B15ACF186421A7CAC5D3E79FA3E77F27D7B5593704BB5A8672E8883D946565FBBFF61D15733EDD25E0DE5A7EA8E6C05282ADE2A310A8035201DAADAC269853CB39220363768C06853ECEEAE43F8CE49C0D1ED5BB93E3354066179B789C30C0C7BC695ED80E99C2C9D56C2D8BBB9043C01FE55D99943A65FCA0A72C1C84CCCAD11B07C7A81C519D0602FD24F77D356092DC67CFC5DA5FE757BDD616B08DE391F1772377F1A88A5C64DB5DE8CB0F2241437E88024A730C0000FFFF45A42CAADF4DFDC7DB2BF24CA7A66385EA162A3B5FD1C121A89FDA09F47D7F38B8055AD3D0BEF45D1C45C0B44417CE94118261C0A0382BD8B745A79D60FFA35243791F2EF2323A55037D32EE59F1F548A07BAF83ED17D5CD929DA2E8BB53EBFD9C60E0B154064932CA24491CE75FAECE574C6E506BA6EB2A3DDD5A3EBF763689319A8CD286A119D55E2F1207A8545CE0287B32B12EC96FE820EC06FE480770F721292B7E4D7D91AFF3A4432D1137A1E5071B88F74A1A181432E3D12C7058882631B2ED1C567A020D7CB829E682278B34B26A30F593F6C5FD9A66DA8C9C63B068DC3F23329135A4617336FF0F3D0C49EFD594F30EDEADF91D5882F1888AC5A8046437146F4ACE85CEC75DA00A5C2AD9189BED998C2D6CF9EC4B9DFE7A39A70B56B39479BB838B0C4F27D13A53A72022D78E76A3BB741FDE0A66FFF2CDD6635CEB0A97751AF20F367A9E8BF08CF6B04E2CC59A5E0D362A28F9664AB8C46A22844B24ED489A0020C7024E3D7F0FD6F8DA1131EFAC7B6B12151FDC6B7FC70ECF98E9D9B19D67388E948E0A8F736F4309223D8F5D0BF73AD69C9ABAFE83AEC1A2BE2B6C461D66AB746682F3E0394AD6C3A6DF8997B74EB4BC39404B2BE5C06736B2B1C0F5B4FF3AB9775FE3AFCB671C76759E53A14D4D2B031EC431FD8BADECA7DE3310C9E8CFEA0D82DF0DE4CFFBDB593170756EAEF461FB87C4EFA1BAB180B5FC420000FFFFC3A4555CCFE68AC9F6FF36D80D70A22D790CA30C3967B81EF181A925CAD1DECD7B4B756AAF8D67B77552D890DD5D1F925E687BF1F2DFE5BDC3F3CB5C65005D5EBFAE17BE2EAEAC4A3B6D85E6114D7F611002B13482C4EAA90577B4B4FE90E854D4AFFA66AA2E8BE2705532D1C5B00039DC5F9E39B2EF5AD77218E2E755912A66562C863AD78A7837F4685FFB1ACA3024DD97079D321BF3CC319A90DDC8BD92DB019A204CD3B5D530C4274FA54DF927D2BDF099DC0EB978E7355C3062422BCFB040265D4DB6EABEBBC617A6D6A0E458A0FC3C61E55069B410B8A802E8950117FD38AB71C5091E6F24B76A0B98DEC56909309C818AA7F9679F4BF9E4725B8B4E3DBD764875440AB860D9D5754172C76C708C61EFF18B6082D66CC1ABA91DF3B75D28FFE37C54D2C28EE063F31B854BA4E2D4B98A2F17CA85DC0522F5094E6A5CA1DA808DCDCD2C30B9E3C798EE112254A827F1A4FA01BE63ABFC6691F56A5F9E44ECF804C99F113C52F1837F27F44EC916B58699B7A3D679C0304BABB095EAEC09AA132C31944A616444862AE30BC057F26D62812A67534530FC53BB7AFAEC0D916932C716D1B534994EC026F0A2CF7E92CCF84B49AFF67F8059FA0948325B81AE2FA91221B7812B75E925FEEB7CDFD888737486AA9E145D14E565202282B2F53B72D017BFB101243CA8DC381698E1E4008835796681CA507937B388E59CC88B1B0000DFF7717167B14DF7E9441DE03894808207631566C3E75F27A835D2F0BC6F457DBDAC81454426D2CB1963E3239ED8624922F3C355F007897229AFCBE054E6143B073E01D4788939E1BAF9534D33809EE2636DEC4B64A8019BA8EFDEE22F183EFF1E7DE92AABE70CDB3369AB637B313C58528A22981D8BC37B3B5B37933BC7671A284B2CEE02FEDE4E80AFA5DC965702C0CF1FE6C55281085FD18FB501B2554DD0C528F5EFAF9E01B8D1D9920544B10BD0F72FF7847893971196E65260697733F0C04C86F52B8480D3DAA18C8A2A6FE6EC22DDE452321AF037724347F479F119E6E92B21581F227EE182C31FFF60E17A7F844DD3907D9B24114E955BB4431B347A9FAE52EBFF913C5D2C3FA04E724A660FC0F22A0BC1187D991099700D4A396BEEAEC45DE2C7E5D5B1AE7291776E4C4B7FB41582B57DC7E0EC268AFBF09B4E9A5A8B7500F98379BE84B9F9C1ACFAD4E7AE33E5C722BB5CA43003D9635458E457C08E8B9BCCF0A2A5F100268C4D394722F2A02217B42098B56BE9B7DD164C25E36B81AF76E2A71B28B2DBADA4BD847B3E0977099F67E9C04D461E5FE22B050AF06B3860C9D4DABAA07F141153C33FBDDAB06B30C4CA58D729A546225E21156EA394CEE10001E01004FB57CF3360E4EAE073DED0F9821DF5F032129BDAE9F5C81EF91E41A5157CB5D70604A31E53EE5F24778B4D22AB35FF320FF28D9723F5737E8A46CAD12200716AFF392B2A9A19F6DC22E762516791E6A27B85DD92AE2FA12E28D69CA74B3940BE8F27044F5FB07F39D06FE288CE4F582A69B6ADCC36A61A5E391698B783C4F5" - }, - { - "address": "98A1EE6A5741A3E088388ECA889577B5EC26A4AA3401F1BA", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF890B75526447ABC8A09D32AB7BC33504D98CC83B8E5A3F1A1C6A2B4F619D31095C5639CBA98511F586A0F3CADDE530F75846ACD6293AF4C476E1D768278F797E6D144046A8B1F9959A7F471A9C85D65E9A71B2CF8D726F5080E83361C6196205199427D97BC0AE8485252AD22ADB88D33A84947391276FBE8EC519F3A56BDCD0FBC3B155C9E80E166FB4200AF940C239A1E5819924BCC7A880F7D08F06B4490D176B9D4345E11BD2AA536B85042B67A68B79575F3885C79E732DFBDC4BBC5376892A8181E03B148A610A89DC623A63DA4EE5A2283A1E0BAEBE34160A50921C0E04FED61E10DE325AEEA68A7F90814BD17A901E163CCEBA5887796699E055373B5BA27A6234AF86D1A6A451B0E0C587343DD57839632DEC4237D02B92AA6F0359AC0E4185C802E819C27CEA7356A97B52A8622819EC9217F058EA08CFEC816ABAE676B52A3FA2B6ABE24FF2E5E407BC4DC9E33C878FD45E7C1BB2A0399DCE6A71138C8E8B766BB991620B9746A6C16ABBD765C5F18890F1E779A11EACD09F801A1B91673E224A43C45342D403BCD962F9FE6DBDCD271957A9E174789DB892178052AD29EED00ACAFEBE63F92E30926B2F7A318B369EDFD7BEE0BA336250FCE3A8B0ED5EC0FE1DAEBDEA7A542592F8D7FD19700218EC85DC2D47F550077385AE8555ADFF40A5519C65407B9970F0E6A5706144B49F4CE8163BF63350D68E4200AF0000FFFF4F38B5F8AEE331EFBBB544491BB8D2D770B5C470C803EE9DCC5E0136CBAB4897993B8C9EFCD266170F969FB0067EA169680B57E2C34F63F47F17B2458BAADAB456575517470AF54AEA8744F9AB7E9D122AFBA8C4F0F45CD4E17A3DFF312E52577E44789626322CCE8A9B37C5D2EA8BCF18FCE72C1C81CC209F006EBC3E44D28A7C8229467572B7583077BFCF3551A0B5D314EDA5371CC128175B3CE7E2C0214530D25F65F0EDAB4CA04CB393941E07982DC13000FB88070E430039BCBCC7D40DAA4A449CE170FB794535579727414E2406517A13A77D7536B5F514FA9C7989C401EDDE768AFD7917FCE0C57E85116C8F16F0BEE6540EC4907A66E8A0870CF621BDE2DA5C3B4338FA0D9D1E3C0C490909760E7FD4BCE23CCC1204F6E5E5884ACBA276E07E064ED6AC559A7FAC6F2D41A4B501F169700816274A97D6AFFFAA9C4CB22F618E16F5E90303EE0A739C78E342F053C73BAD0CCEFE3E24D84767E7B59BFF2EDD77A264953DACB8DF7E072047916732C0D8229F738E9D06684CEC24689B4A43B8CABB5284D4D6EF045EA7D30E50F258375C18C61AD2E4CF5D326781D630CD2EE51260577D76D40767FD6ECC2643CFDD953A443F16C34939A507C33664B7465B114F7B80EFB858D08C43DA57492C19871744429191EC700FB6DABC57BE42FCCBD1DE948BFEA7D3B28C467CDD4ADB5E0E12B240FB0AFFBD93F0F0B99EA21F0000FFFF30188209BB5EF8E6F6C5924D593A20C302DBE65AA5B13D65C47F283854310938767A6A0942E88817B599120B6AC7C234EBB3A1692D5210ED3C5F787B866E2555E9F459E26B067CFE86B9E333B4DBE0D268BC07BF14BEDFA4BFC15BBA46DD94508DB5AB1C7AF473B549343FBF7D6F1D924EF763F46E34E3DB6670E5C75039A0A45C294E8BAF8010B2C3D0568B512E7DF566C8FCA7AF06F7E6A627D5919E95698473D3CC537B600276DD483EC8EF872EE30D46667A6D70EF2E64BA3DB8DA81DB7107C4732E5CF8A12D3CCBC60CE7C64C74CF082E3FB90B1EDBBF98D057EED0EE4404FEFA6CFC21BFDFD86C75BE739614A498F3550634FF2E9D0B28D0AF2743ACABED2554EA41AB01FBB32F999E5CBDCF5EDB3D504C4BEF7CC2A848C8AFF65AFD040F1D151B344F8B6428F4183F4EBD38153310343F23EE4444BA034038F3C5C61C7A339ED12232BC64E0FCCAF23ECD9569DBDE1EFEA2CC921E96539DD7AF10277E9085D195536FF3979311EE16547D4D09BA618CB4748B7A07CE65D2E409EEF7D9129103D3F03505BFB25DA5730821B1FEDB26A27E8AAD8C2E7DD5334C4D939CF1836C13E8A3926C0B9B425B5B54E57719E7E88277C1B3C0F6549324096828D818B6947D5810DAA447CC4ABA02D8A3CF813B28AD40BF2CEEF2857C147C8282735D9302386E215BF2A43950C98685D0BEC89215D7BB5756D3F7E0B6CF4555D89E860000FFFBCBA0219CF5CEE96797807BF484B69744842FAE437F0CE1C613CAB63B1F0CAE8B548BE1A40F21D4D87C2EB2156C2DC3BFE205250F4875BB7D8ACB7604F36A2BDFBB94B75F1D713F7F62104601EAA54EAEC969D104C52416D29A280446AAF840E33B4C941F47FDF448955A71181BB40D41682866AF6B32D82A74EE1675B0DF7D52ED776B3C5A338B4C6768DBB2F06457B18620F126346814A87477E347A7C02614A790B419D0EACC0074D336253EFFFEFA7C82B8217A8E3D5228A18E0DFF3E68EF1A27D51C92A4639C792012D22ACD1DF36FEB06CE11CA14707634608C67FCA308C4FCD06FFB72400E62238D8C31093489D4E90DB6BE4C703BD4C9F8EDE860D5ECC3561499FE97D1D0A4218302E2F64BD133AEF9412593FEE0BCD35380729CD6FDF583ACF3899FC2A3D5E44CDA33B1C3F88FB978E6291110D5A49A752945C71FD1FFB44A679DBB00073B300A26F35343F30895BE973CBFDF3DE075F9028CC1B141FA7C2EFC310C9F7996B5743D77360E93CDD770C53862B9E87465BEB6602778F3A5B0E9A8790FFEF464F23D9C6685692E49D0A1B7801DCA39D239867E8700F596AAE4DB498E568E290609DA5E79F79DAA5DC19F19C49DDC7EC5BFFD6166A6B4F70A118CEEA92E7FE7A43BD9BBA6F89631B054FE776CDFC8F4053207820E7E03F9000002299317ABBE272C7D134A62A575B496EEC89FB4D26EDC0184028D3CEF47CE8B6A47381B411AB0BBEE8819370BD70A4D529F750C5504FE17D00FB1F01D1A8AE9F478F293DFEE570B5CFF838A48107A0191E6DED6E681BC21D16931B6B617E723DD127174A9D08CDDFDC18DE7A3029AA294322D6EEE7757006BAED5C676392CBA6A1DFF3A44074E0E3AE0BFE69D2977C7F96E28DEF09367D5005F98514FD70C5B939315754868249D2144CAAB17EED85EB610EC3AF921C259A217A37A16908D3C8C" - }, - { - "address": "98045305F46AC66C57617AA374094A211217093A20514BFB", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF31780FBFF8BD5E6B8608C766DAE8AEACAC1D5720DBD0FF64F34930C99718B235D089B12314E65FDAD07A9D57A341CD4756BFEA06701C7FF99ED1506D0A8F29425BD4911FD76BB6C0EE68075C589FC1BC4F73E01700CC9F56D92AF16A8EBBCB3F6A364845CC6EEA33DFE3585A303BF19D04107A841641462E2112CD8B6D977DA5913BE57AFD5C5047E40A47709CFB24F43B0809183ED34491481B3E90983545679659CE3CF64A8F4ED4E3BE4C25C1F10A0CB11CB4B663411346D7F084007D21011C017EB4540BE5EF4F8AE36CE231AD80518EC64214D191803DD5005B56C89ACAC4C3AE8EB4F81DE6441A955053217E7B6B4DE037E1AD4CE74B7C938DDC17F690AC6BBCD9AF42875CECF65BED47BBB9F0DC6D300270437B2FF8E8D8E424B62797C850531E998AF1D2C81CCFAF02CB0713FA5DEB7B6ADDC14DE1A192AF28E14F5ED85F058850752ACCA04CCFCCBF5B4E6E6C3D2D768937BBA72919F142D4E2EAF7E0FC7971F8CA8AFA1DA6BA240926C85846E8EC6652ADD8273E87746225754A689FE67636EF5D41D46578AAD33A7997D82DFA418131CBEC707DA6BB9EB7FB1E747CB1970ACCE479E53B147B0FFAC85AA4122D1C0548BA150967B342C8CFA3E124053127DBE6FA4352D4C2E00610191DB49BE465B63AAF6846C2FA317BF6895CA5B83B6F4E56B032D4B5F3A67CFB53147589DBDD37EC89EF8C8FF61056E62951910000FFFF8D0C3CB26FA6876739A4436D926E1116269FD5ABD8713B6B1E5A2B962911ED7D825634951263DC63962EFD281170A6250B2A725FACDAF7B562F145371425CF2FE86911D78782C5600C284FFB69041E5FD2D8A612C158F62B9768AE63C7E918242FB2B7EC0B18F0435C30EBEBBF84767E750340A2800C8D2458AD7C53478C4647E9C05AD008A90E490E914A3BE26C96D425224528F4F3B673DD4292F92D21C3E580021CC035DC353AC22C2D420ECD9519AF1B6ABE4F49BBC8ADCB6F1A9930FF794311AED7F4BE3D0545FA91E950288653F5431E8F048A450BEFF4D6B3B1BA7A992234C1C74BA84F32A7D8ACEC4FD20A4277EDB1A76159AB2E15C175252E0D3E186A35F5C44E88C811BB55CB6A175D86826AE79E077331D0FCE4966A1C02B7C274DA10EBFD1A3CFD8AAFAA99C756A95D8D6B1DBEE3AA8582809095B9734C89FA6525D8402843AF7FBD8DCFE643B92D49E0F657D45E46E791C147547A4525318E018B27CE4814CF2685C15582A4FDA146C8442B3B1206D6EDF77AEE60A6532E04F005EB3E4ED3BA3D22E3F3FE777CE505508F13D487A0450190D85BA47BAFA8C72DCB2922ADC22D52D0CF18CD4ED573E99A0C2CC4DE79876D9DF650ACE11A565A9FB38973D725E2926A5D28B0BDB5E0757068FEE9503A104EA5E9B5F2337E67040C242FFB649C823E1FD2140D88325C7A9A6CACE5923CB0112D9F674A9D74A2931C0000FFFFAEBBDA8777A78BBEE9C7EAD50CCCC69BE49C3743CADE7E58F95DD7ED85E6CF171E384AD442F7FCE57931BB91071E80E09DF9E460F74BBA1FD2AB8145058F499585ACA8AA89AC2067017646E1B94E535FAA319AC29501A923CA3904688EE617E55C0C37158D0749D39973B0FF3D802DF80A9845FCF22E8133D2C14AB39FD64D588A42C254298E5A65934CFDE6F0E50A49B31BCCE0E6E70E5B0C344D78FE942F9ECD26F66F6ADF4D1D34A22C72D82CA808C90B2FF55D78B32E7D36A49624FAC9E0E552A226FA456C7AAE80D30076BF4B126FC69D23F2133412345C097626EDE2AC2417211708851397E457695B83EA264D391611F6949F1198D7B424F536E554C50F98E096F634908A0C037393BC4E7E8C304E543524B5F7B9D457D18657B1F7309DEB14C8262DD49F7AEA5A3ADCF994A5FA8FE85121E07AD7F033A3DBC14CFC5B23EAE0C2CB6138BEB4BFC2D98F8E3BC44F2AB2CBA8DB77F07060B83D00246072EADBB1F964964280D17B5AF90D8378D0F562585574A7DF419C387661D8012E69181907DC5DF830FE3CAB04D990A1692CFAF176BF26F84FAFF3EA6C2D151FE583366987059488165CE1231672B29A94ABC44651F6394BC98F6F1FA51EE980D08A8AE4847675516B382F7B1E79DD9793A2C59CF051825CA300AB13AABD2BAF7B6B9141F1A4C59BC1C8932E4369B4EA56208CFF4FA9AB820F7C895A1A5E6A68CBD70000FFFFD0CB2D3A820D7489543064A8D415C7C1C31AEDF952A997FC6C8EFCEAD061EF03244521AA62E45E70AF0550272F365BB3DA3B36376FA9010F27F3F758E0CBC0657C02707B1D7FC4CF5C7DFE9B62A668081B12D90936C513D78B5A87D10BE2578D0DF54421EDA5FF5F3F586C952BA1711F20F6740A2F0C6565E7F8E84A893A4EFD3CCEFE5CEA5079815CF83231D535C47A18800E51561D5A4DC9F7378941356FBE86461D76688A8150CDBCB84FB2D47535B13F42E03A1FCA27DC7844808482120EC70C252D072E276BDD2CCD3A155FDDE7EB5EBB02DE5FB926700F6736C068B9DD93A158E5199B6D94777C910A5BE8EFA720E3CC3621B544E46D852AE74CC935AD3A8618DBE891ED99846EA10F7FDA2D3491FEA8BB90BA5E135BD05F2F68760E1BF907A236DA75EABFCF7962AC536CA1F0F0441DD2B1688FA11C9268DBD9043043F60DA9A6FC1DA28C7B23586E6BB60F0B1E73C83EE3131C06DB2233C7C0635ED2230AD6419A6FAC378EA7B9E9C668244112ABFECE57CE753C5C6C21A5EFF38D927FCB5F1D170B0C054C477FB74560E09A26055B2C5048E87D2727F9D3086106F551F373A382DD147F2A6265DFE9F92A67A7F516DFC8B4BF39A49C98D4D8D95B159D5F3B6FA3F5AB02D4BED86BABA65BE87856869AE1708756034D338963D2B3627BF6F0C3CC9E8F7E3586BF18596A10CE08B4C6A090CAEDB6F1282CA45087AA7200008100C0F5F122DD1B761B9CBAEC19055BF97EBFA32B07FD7137DA6FC901100E2345ECF07A499ED3DA2A95DB2541E99614CC05C61CABAA03E66595EE792C5EE5AD6F0AFF3A52DB76B51A58FFD49FA43F9A7C15BCA674CC1575B533729E87DE10241E1251DFCCD26BCD97C234A40ECB42344B89B43D04C79B0E980F4A8914CCE9747D" - }, - { - "address": "981E33A82A083BA5AB4E64A6D4582C5D40432900C160B1E1", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF8936B2FDBC11C90CB6B3FF92A95CAC7E4F9C10855FC454E486BE234A22A43A3995E2D0606E9720A7A8843785A60FA9BB9541B86B7B361EB46C9C4C89565D2FEE7FA21D6620A6BAA473552DDF2AA903D5F277C9ACD403D73AC035F0080F35128EBA6A13F00FE17136D63791ACB4BA0DA646E6A4840B4EAA2694EF97C58AC758DD6581684DCDABD4F1E295627B9AB666A83A1AAD21591D98319BEBDE794163EE872E679E456ED5D8E6603FFCF6DC4FB46B4561AC1464CE99A63C0502C87580AF59BC80129A00CE3C70A6F8366E76DD31D347621CBD17458F164131A0CB2620209D1F9C5455C13E840D43CD3D5B984F777DB4B11E81DF61B678F0127EF8483DB72DBAC36927CD90F563BFCADCAE9BAF990FBC0006CCFE1544C6EEF544B05B8C6745B749A08B2745B2DD0C129667C8F61EF5C5B97A4218A51DB8638CA4BF3B238DE2BE68D548C9E8CB636B80B15ACF186421A7CAC5D3E79FA3E77F27D7B5593704BB5A8672E8883D946565FBBFF61D15733EDD25E0DE5A7EA8E6C05282ADE2A310A8035201DAADAC269853CB39220363768C06853ECEEAE43F8CE49C0D1ED5BB93E3354066179B789C30C0C7BC695ED80E99C2C9D56C2D8BBB9043C01FE55D99943A65FCA0A72C1C84CCCAD11B07C7A81C519D0602FD24F77D356092DC67CFC5DA5FE757BDD616B08DE391F1772377F1A88A5C64DB5DE8CB0F2241437E88024A730C0000FFFF57C75C1C81C0883580BC16628A50938E5ADB7E26E5ACAFA8A7E356D04AFF877CEBBD5253B10A450505C566EC2C0CF6C77965E3CAE989591D0AD02BF24179DBCA5345255F7D9406D83115671F6D4D62BBEB52F2D0F7ACBA68D43A0574393AA36180C6B8AA70B65DB2E4EB7670AA4141614B56E367F9666817A8E8558A7750C1FF714E9DD2A4E802D88453E820000D0C04DAB62F3C202E43F259CEBCAD247653D3CD82E920C38B070BB554EDA4C9DE80977A2C9A78E143C8AD0BAAA11A56D91704BF2B4070D62BFB759B8FC415FBF3E1D8CFD28B0453EFE45636E171ECC25043FDA7DE4A66E4FFAC5D97D0A14B229CC5D62EEBDDEAF662B50461DE3E7252F506E55DD469C3871AC1134F369B6D43FC2CBC73CBF6E00154453031B14759D536959ADC6A1B60A5C3672AD922F0F952A263D88A9F3A65E702CC614E48C7F28D3358A835FBE8051F9A39731AE0F88DFD4774F6C15F19D6EC6118739BC1A9B509D88CE803B26F68873E8CB8FE44E4002F4FC3CA7BD6CF9DC63ADA1893B1D565AEA970A259D2999917EE95B506CE6F025BC21A245FCBB962AF7BE9652EEACED5B5A1E12BA2484FCC4E7CFC949073CAECC3AB2F85EF3484667EC267CEA10D0186E6BF2873BB2477B6B14B668DC1F537A0DBB8D9AF83536EBC5CC6D11CC4E9E50F76D868B3AF22C210AA74B347FA51844F031D4F4833F3CA27BCDD8581DEFFCA25EAD495060000FFFF7CF10BFF5DF38AA1346D44AC9E35D6AA643A939A0E8FA3020DC9D5ACB32C0B43C62C1FE35B03056F6779EFBDE3832795F67BA5AED8F3C5CF915677126DCF9D96A5E665F2FDC680294F5B28EF5854D0FB0C3FDE4EAA1F393F8F8FD9416C6AD446569A285240474CF989BC8FE59083C6EC0A16B1935EE181137D6264935BC0A4B855D934CD59C8D299C54D08DDB9951C6760D08A95B6F8EDE68070C00610F9198D5211F55A6477D11A162CB06AE60E1389044AE72534DD3260C38BB0FECDE82CB8F426B0F15CCF41BD1CD630A7483A914DA392BBB781E45767072FA6C09A8F6FA28008660EABD7F4E5CFC068E7475788FA66F86D22B68C4D35DE595B65ED6AE178301060420D50FCDCB001A2010933FD87DCC742A6260A31B19445B330E9E62EB283247548A3D2F616E23EB88F39253A1E9B74C829CCAACE073C50DDA5EEE3BD9FAEF68F8BE60726BA0C044166A8C84E2CBB1746348312436B993B69B3B158D56E77ED428C5A279DB156552C7E77C6A10A236D315369924CC474C50AAA28AB77DAB800D87A869A3B61FA5DB5B9E5D8B99F2891463BCF1E082C91E499CD8F251D26E0F83DC5F6C2054B44C45E4964AFC35F871A990F66A2CAD5F8C8579107147970C40E3EC5478A2C53EB0BAAD1EE767359D978EA5C6CE585EAEE85CDB6E6C420D368ED498331D63F6F2007FD55993990C2746C613A9C234250CE79E4B607248B6F0000FFFF633841F20D5AFC63EB0B0885D0D404C71C8FC3816984A625D815D772AE8070D1AF8C9529F120033D98BD21E1B2A9B7B33A229B6CC57EDB5373822E05A39AD25B20D78036ECAAF1CC8489FCCDDF18B5923CA85BE059EEEF5FF37F8A2CA74EB1777D7A036F22ABFCDC5F6971C8BE401DD8C8E546E84D5607FD5354D648D5C9F647CBD505B70FDF1ECC1077D2693C955B5234428336F7B9E304517B02CE0FE512E17637821F964383E83363059BAFE31DC9377F391F8F19FD34B568ED034CE4F45B422DEB252A69E5A4000AE683A70E20064E003FCCFE7586DED08D2AE71ACF8372807175846CE85E7FF671A70167A6F73514084E028E70178AB45EB12C79009B717F135F08F8FD9BCD15C78D52DE7D1E0903171A0AACA5D7453CCE139DCCB678392E0F72669D1A49D53F4B2B341DBD073AE2EB4AF181897A8C20AFCFD4F0BC0D78E870DDEB3B527A84372AF89C6F10C6135FDDC40F3AD90CBB7177CE65E7519000152846E2BCADAEB73DA26238E3A6DF79A88F6F50A0B12E1B370D81B9BA8B7EAF92FC4BD0EE5A4DE8410F1F1D27A101FBD0F15225CD06D0B2B495A9EFF190575EA7FBCA825651B58C6347E9EFF002EA433D60501E2246A02EEAC91E00BE9AA1BB89BB40716C1EA6A3CA5826E56864AC89B343331D3D505C08FF2561A619424E271414EBEE4456B53CFB336FD34246E0FED3B04046920664AE70F71502234925BD00004A8858B2DF3C6F686C3816D9090714D9A875142AE1CA0A7EE6E128690D1D453E4A395F687EB63B1F27FA1E0FA7A4B2738591D09B069FC3C1CE6576CC0919724518C81E4A8EEE8268898D86AD9324EB82F2E13101616B4C8EF063436066365C03547F2EF26A4785A969DF823A1BBAC94AB670016EF1E40712F6147F072B51E3DB82B4439C85D090DF028D9F7E26575D6B316BDD6B294E087867785E57062A3A426521FF3ADFDE11A00DFCFE5C7098EB3612CDF6B578E2891CE03EE7069A85445AC8158BDAD1E655EA493457CF6F1DED6A8A5C1A1FB580599E3D798711CAB69E7153" - }, - { - "address": "98646DB934360F2AFC55BBB3360F9826C23A687633A1E2A6", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFFFBAB417FBF85C1FD245562D400A6EC4A42A760042BDE083FBB4800F8726195D1C1728462E12082F87403485D375B166F8514D90E59B21A4A5ACF75CEAF477430FB52B138C41CAC188CB313C0CF9F25CCA18482D082FF01624003D20C1B71F59CA66E147F97015501B610C472A6F3F9F4457E81D5A913B0B5DBFC8D44A3C209F8F6C5FC9A026DACA0070B3907666CCFE6D4523923CEE4072A7EA55C1D617B0C706804159DB14F78E1947E0750F69BA77EA5864D41A781E38BD02CEC3508912ED4F52C88E07C8F44A9578C37F153A23941D008AEDC9245C83C4E12FC3C5EE29605C23012E8F5001D55E967A943CEA55A293FFDB9B947110C7F50842E668821E8827F5EE3F604E27308019C4560A1DC212F079C472078C88DF6225F7EC65EF71D132F15D0BABD7C739A5104B5BDD54D1B9082A2F07F917D6C9C0ACA93E807F2978FCDC0EF1771394F64E355BEEB71B96B57ED1B291F04DBC2D8A80B9E8C2F30F32B71A5235CF58823AD8FFA1E6906A869A3369FAC1317D25AFC3417462844DFFBF707A8B6147010C246095F92A25D0321B2E00C5992B0E4F2A8591308A71AEB8736346E8036E4F22B0457C62B864028BC93C68D263F73C05DE7E4767DF4254AA84E5E26CE19206F06CF8A96E25F49F83565E6E87C7F5BFE35E65DF784FC749A9A3228A4803CEEFE76F6CD7A73997734199FCF1C2614B653E4FA401B123A5D17B05F0000FFFF0E00AC52B798FFBD33361A330D2B923D64CF7475A6E867A4FE38BA8FAA2535B9C9E70C2F08EA619BAF96F37755067BC0375AEAEA7E3E576507D0BC23C1D03B54D87308E7F967717A3FFB3FA75D5330D710C7561FE395F2F6758DAD52E6A88309FDF6D33BEC918A7E613CAA5D7BF63E840A092049C67A1C88672298F8104128E863D3A2A0E4EC285AD65C2C486FB33B9E274BAE527F6D0A2093112B41811703BD2AA7E2484E5BB702587C539AD1034E8B587556A63DD184B48B8F9FD9335B5ECCE998177192645B7C2E7502504D8184B3628A4330494BB0002600580BA0C06F5255B45F6640D600E59BB1EC4C4B80469C84E32D53935070BFE08E558AD5F1D0F6FA143838F6398669012F09BDAB09435EA4E237744B8E037DC3DC445A40127560A29D96D26659B2A6CB6168D77BBA326CA7045D364CD6E497AAAF788614C8C6625024C2E2E61C850DA306E8FEC0BB657EB87301F0EC22454045453F427864CCB70F19DF5CDB347EADF051510F22774C15A329EB0F5524D4039ACBAEF06CE19E789B41989391299EA04FE9D9951DBC9725A92BC3087FA746A42C0A0B8C43196C723E3025C04CE008CEB8AE6777366FE51C7E18100395223F6363EBC93C2500ED4B519BB3F2FA23C9A230429F01D477289BFA135F166CC83691FBFDC81AE9ABE1BB79393259438275140D6567B4779D93FCD7B13F240C2AA4B8BCD6B82478D613290000FFFFFD1B7903ED6465D782D07A891110F3903C1391E6E30CE38CB20263B0B2DE88C4037E8EA2C03068FDA84384946C0AD2B98D41691B05A54A9D758E812B5E962BF8E4A0181EBD55B00605E6931370F1370C95DC5E9DEDFF8761C3216FDE8EB0C6E5FC5B125996F8D7D3C94B0ECEA3C6D7F3D34AD07E18A0A9A4138564E836148721C9D4D7A4C2B36B7123C106E54F894FC735FD6271FE752875C395D5D1F5908555778FF64F94AEFA9A75BE377ADCF239C46CDB3B0CF65F98D710FB133E7DC099B1225E56E0BCAE74858EE6344936F08E0C3148CFE6CFE9D9A8D66F277EE978D5CDEA61FAAAE7273595397A88CCFE747D28CBFB05F90D16E1566EFD7F9FB836E6331521D2FEC98A6F774D98600D5CD71BD974A4E2820B8671C1F223CA6C7FE0355843E9E7FD288F54E48965D9E925366F429A295F50A706F067B750CFAEA8360BB2AB74B501CB59E5B2BFA3A2B18642C8CE8082B5508BB0EDEBBDE562430210286626056709A46328DC3F50CDA62A7CD5295D0E732294B477B41D4074F5D068DE854B42FAA055F9A0394AB8067184F725A79EC6780D080ACAAC60A9E706A4BDA8C6508A1635B158521645B2AB952692ED57782C46111FD97E08A2F37383255662FE1C0456274EFCB11F712A55EB66797658CC71F7D6AF85358329DD1CC63FB236AA435FACADEC94A97593A2F7C8C2220986679F41B45C6AAEE37224BAB4DAFB836A0000DFFF74709F71DD48AEBF559C193EAA0C6A9606DDBF52D38BFCA87660D3D9A5D30F1ECEF7642B4A3DF5DAEFEDE7FF74DD38B8E5F69E078AAE1CDB32668B69041649043C248604ECC20F45A251DCB99B94BFD404410E9048209AC3F595B3E6B4AC0586E7C9FAF5C914183724666FF338AC0CEA2CBC8F001CE453C76536161921CEE601EE3222391A5F3F7CD4FF951606A987888FB0E5A7F39720280F6F42CA47CE9DA981F976C2AC098AA43BF3993283169DB0B52F00380AD56A1084EF3B68AA1D4713923B53562A478B29D561BEACD2ACED5DB308046A4E26E0C13CF686BC177E337BBC38C8C2487FD0B05D7AEAFD4EA344FA1BCDAB3E08D877B6A2024192F4678E9E2EDF5AE3EA91F58264F658BFF417A42EAFD85D6F00E8C1764C18ABBFF0716DDF5F624DDD21014015E54A203FE28485AE90AA4BDC26C68E8E0937C711C0DBB3222153D3E5E9C5275905939D7A068CEB7CF26A803F486991AD928E411B63B99C4FF48099C7EA5AD6E3159434AFEF830B6946F3BC100004336BCA33E124433789710F83617E61B4F1D4461CA1C5D04EA0650E8BFEEE366E96A083B410A64FF97FA3770DF93388C0DBCCD63A4675415FFAA4740203208FA529F0B60AB7425E15CF132EB5548FFDC98CBBFE071920DAD6B499068A082E86D30029808CAFBBA2CCF0C500000A423E50AA20762EC6F2971A43D4D1433292C29E7CAD9A290A745AC0429A028268067C79ACB3700220E2972E1C6E272364E5C8D23BCED1D4211B44C931D015595F00BFACF78BF900A1006F2A9155056B6E7C22E9A2813E8843E4924369AC255DDDC5AFAC413AC5FC03F611F968CFC99AB9EB55F56EE46384AF5210D8A6F9F7AB8897FF3A6F7779542DABEDDBC3F727850D417888CE677101DE78D3DB5634C31882255274BDF9753F8132230BB232B1852A8EDB2F9CCEADBAF5B09F29E993D65020" - }, - { - "address": "98820A4B2EDE112D1378B755394D10E54E25E16BF7460688", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF15EC50DEB569AF1C4861605F3AF8BC807520007BA55EC8912F0457DC24088DB61CA90A313A902DB3B159F66D03EB83E62222481F13FF3F07373E64E5192D33506808B5067AD30F878BA1DFCDB8DC39C17768F00CCC9B85EFC424CE2D5A4FB798F44E3FC2EF0E2F45E11E3771245A85E51DAA933A8133C85A46E39AC9D84577BA7F71C92DCBEBB4421E8B035A313DD8B7D8A37004529D8D0652D589D747B46107279CD041E90F3741ADB5B24A9003D40160505CCF1F455842DE08756CA6041BFFC6123C08170A4C344C5A0ABE624366E1852F8A1A87B7680B0202D5A70339EA9C8CA2E0DA99117F9F371C2A2ACF1142434126F8ABD7A5CECA32DCF73512044CA32C1BB374E93D6F31BFFC757ECFFBB16C3E3C52591F0AF436F3582991C1485DA0DA3CEED1EF410C2E720EEE2A5561F73CECCBCA0C9E6B5F32CF0B77573C50D8C60403DCC5A86E38D951C31133FD6B66E9C288C91A630DB029888A2336A3501D3FAB3ADB1CAFEA0D817DA84DCFEA144EB20316BED281B06BADF456A303CDE5CF972E596D2E44D4EA6C68A96C204EAA4E712ED7B11758E2C6F007474E88701FDE81871BE95F7C028409F44602B46F198EA0FDB7EA21829468E53C5639E3D67A11793FDBA27463511EADA411DC75A600438A3283FEEA63FD94FD2CBBE18A6A129BA8834F1EB0858F110049DF39EC1241BAE4FFE0CFFAD396B8C3845FBDE20D34C1B00000FFFF2C0F1F048235F7226EEAEC26CA6D7E08B7CAB563F4AC341BE7F043ED9DF98F970DF95D838C7D4AB742393A54F4A597D6163730F5A50ED7D3FE6214A75A829ACCDE57C4A7B7CDD059C4F04DCA225A14B9A57728B53D5F42D9E3646764F607FE1C061252DBD0F85903B33C0A1A4F430AA73A2F2C4A38FBBB7E1109C7C2D2497CC72FDF6846ACE9C1CE9E7F776AC2D1F8825F8BD14FE6E48CB4242ECB6DA6C99DD22A3448CC8EF1CC4DA23C0DC46212ED0CDF37CEED4DC1B2E1EA631C209A05F837D429EB415822776C4493F4F9F15EF757B482B675DBDCE69A23543C3272FE2F1A1E56F039283C274E4A4DF369BFC427299187DE322E2B6E68DA1E59BDFCCE46D58B39AC158C1FEAF8A9B84ABF04C442ADEF2E511CEA866AA255DBF6DA18FC809D5B17E5AE7785120FB50FF5220E139E431D7729B5D2B7F9C0B27D4BE153C8CC0AA7969B893C579E878071D0154CC3E0FB81C35D9EBADBEE489D40FE31DCAB82BDE87D40254C977E1980C2401FA82A266D9EDFB5C39E182BABB41D7CA03FEFD12A2137C1F6BE7966AE2C1DBDDC9904041F7650CF88ACFBB59398F4AC7502D59C9BF00438CB2F3B8A098FF3AB8EA77B8EA532779E81F5114A92E52379B6F3E583FFED7FA10547C132019017C21D63B92447ED8FED8FC8D9D28919D7859B72B5FAEC3A38F2039D5F295DB7DEBEEFC4EB02136D2919F5B15AE55B819DC61DEAAD3E950000FFFFB10414E5C77A5310B122D7589EAE72438D6A835C4BF72ECD67DF0BEF44E1103197862B67677CD5471FE64AC1249D517324F33A31722E1B587207A7A0C4E0E5702045CEA62020A45FBFD20897DE4D34577E46A826584524C763FB51B6AD5F6C980576D874BDE1A329BB1AD5F7B5DD88117F94B30DFF899BCE880817B1FCB986BA549BA67C9706BA99DD85CDF711363040FDD70945F83658A6E9A2BCC1BFEEF6D31D0D48B54458175581E7643EC346EC94459A2B7D8BB4C06BF00F6A27112F17AD45C9FFC55F1E1F7E136AA9D0040A0E96DB2D03B10FA73B85894D21BE2D6EBFCED2EC13E07FD794D098A9E049F1D03BE1363400E19BEAFEA09D566037FCC569E7616B432C005736B6EB99DCEEF5F16789E81A0A2A87A1B5975B1E1302CFA0CC300869638C08D4F575A6AA4CCDDDABB27DA9DD6ECCC8669CE4D889F71B7DDFD82237648F36FA1D83921CB9D53E4C6D4BEFA84B639FF82345504B6E1FA3AFCD1742915520C75A763C1E111F37CDA0318C531186D2ACA71D23C443866387F47CEE4F1CCBEE044C2B47289BC7EC10E7CCEF5105BD924527190E958A79C03F644C08CC01BCC3CF755F2D80426E34E77F2CFF4CEF57857ECE27E851177E83AA499A1C077190B1C6F154FE7F7CABA01EC4ABF4C684BD068778C5D00FF4123D383B34208F9FEDDAD750733270D45C4716718B43793C09128D1998A8221B0B6464D5CF69AC00007FDF0E9F5C6CA743D1FE5097A6C7B868F849335C7E1896F28DCD63FE1615363FC76B28D5A0B110A20F2094740BCA81EE927B06E296D427D6BAA7FC0C02B61819F83784ABB3291F53B480C06E5AF068FBF3489B393F12F4D786DC755128C8F4DAF7547F52F57D8C9EC93CB76C1EF78503F75F14188D8EE52331A61CB01562CCE9E6BB14CB1BAF32AE6F33CB874E89B82F47801FC13E4056658B953BA00FDDBC062CA60C9C9981FBA0828BD24B5DDA75F29585BA620CB200569CC7AC552052C66D7D06207FE207BDF1FD8EC567CE4068E8E21EA6A51C9BE3918F2578A22C19BBA871CD4B19D0979CDF9ADCBC02EEC5A9FE097BB77CA3724BE9F77DFDEFEC025059F250857E6AEA5520426A98350F261CFE2CF88E6EA7AEFC0CF3DF085F2AF2C08FFDC134A998113512A4FDAD87EC32A060A900AA50E365CFE976667BDDE9F737187782F4DBA25FB71938A9A190E6E3994AB6651F9FD71D976CC11486E26B96117EB640B87C89F4EB56469699A265A1C145877D887133449493D704C32382A8B2E59A38C7D876F6DF1BE5D5D8F12C537CE4C703E3AA526E0A170647DE56B68B8F850E2C233667F53BD0659998DF0226FB284F59BBE1A23B8CF52D60405FB22EB1F4BBBF000044106E23FAC0E07B752290A43FD6CE22F3D9F08177F175BDBE8E1721D88CBDB22240BE7AFDF1BF5E217998B842B4D2D7B0A7F4ADA18818073F290FF7B23D2A58F6C0B70059E1734C2F758242AC4A3654D774314145776C483A091485FA907720703CFF3A287B5269A1B2A6001577031302830BC0B3B945840C55602047BD9A313CE19AC8C9007E78AB92B0A053902EEAA1D4577DB78A53BA983BD788E2B677341B" - }, - { - "address": "982DC6CF9E1BBAE017114285CDD923F188B4EE341C0AA4B6", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF60BCE11D819055E7EFF33569946BCC2105A16020A67D73982DD64C7E9511083D5D285EFD008EBE714A5CCEB147DC8E8357C6D15E0A66601D55904FB4D5F258AEE1F2D77C5681896DB7840A3C02AF514B517359FE03358C2AC9EBC61B1EE38C112047B867EC07C525D017D63DC43EEDA82EB6AF0B84FD65C93EB72A8C860FD66489CF4D67ECAA8A82C545142C1E8829F385CB46EB5EF031D13CFEED168C93B9160FD02848F74F922AF31043F5E07165F30F81D2A4678698BCDD3BA072E8622CD90E73329FC01C118929490DD082D51294D29D2E414BC7EEEC8D86A3A2E1A195CE01C382197A56ED55048ECC654C139AC2CE72E07638F3DEF3B572D75D2C6459285DF936B7D820E961E17F6EBA6E5B132256C1037287318A2899DFA84A87A5BCBA0F9D69335DDDCC0E477D6B66D265A818B60FA5903F5B2318AA0FD70E64AFDD8DBDC6FCCF8531628C557C44408FD824978A7046FD858EC0894230BAE9E284A45BE53B5045908D9B874EF456C90B279207D8C4A436FB07477F90AC60A7020920D932E7FF6DE2BB832DCE4F460A1EB6B41B2638E541A9CFE7CCD6C4DAA4D5EE1C6A282E886D02518AE04319460AEF4A2F4848FF4CE2BB50674B3A5706C79EBB1F137F48DF31F7810E1AB04A4E74B89C59707085BC4C6E8E4563C416EBDA1FA34FC7AD48C4C07B7E3946383ADAED0296F96895881CD5728E8DA07A4FDFB37FEFA2690000FFFFF15938FF4C6B776BABAD5F26BC0D9FBFEB6C6BF9B16D0FF8E22F0721AE86392545912939549099616450B79CE3B5161C1828062055CBFA590EE09691A9F96E6DED6CBDF360F7A9A232593F2732B2C7B4806C244D1397BB0593EE750B05F7A0FC92262F7DF0A4F0218EF7203AF12CFDDFB3BBD134750F2C49FDA25D4B147510F4AB775E7600C412AA893797A05C2E6AC67EFF0EC8FAB43B266B30107CC4C2469437AA4D631C8D2D98CA223B7A258BD257F5F8F1D25BD8870013CD55F17E65AA78173F1D4F56924AA26D2C40B3ABCB2E3DC36AC4E0E180867241CC9D262322383F236EBF03645AFA53664F198857B042E5D189D5DA4511E86A824B9EC45528159735D15861F5F729F9B37C6E63B08EE48EA79C271038034BE2521E9C203C48EE8974AB1A112F93B35D3BB3604DF918B2CFCD65B67DDDED3DAAB24B2122874B4EA1057AA57B87EFA6CEB5D69BC4C5EC74C63B3FD17E0FDFEA2214EDBCECE63464679A21341DC749EA77E39B9CD03BCF763C562EB65FFC7C2564EB252BA534E5E5F567412B66AD753BFA00AD5E30B3DBD103ED77FF91695181A92DDBB38FBCC4B7C8A04D010EC1B659064968D9B8F98679F1DB55969BACB532B27B3F4C5C6970AA6F555389FF1A54854F0E6FB5D90D5BB2E158588C468880F0D4B8089745711213FD10CCF289BA28B397B94E5E243E19915A809E57CEFD255D419712D3157ADBA3CA0000FFFF423C2C48BCBED10991EF6B14822C7C84B88FF8C45126B19EC5F9B49FFAF0748F67ED419EB27D298D9DF8774465D2AA45607A34529D9053BAE2EF117E1AD4C55B7BE5F598E6AFFF22EF8AC06CEA7AB130FF1DC3E03515188CE962627EA8E680CC4548A8613FA82648BFB35CE9A98E2902B9A4FB3BF316C70009DCD6643A26CA8D9E92A999159F2BD43EB0E1E869E32C4D84F172B9DC8C128BCB0B713546B06F5C6310923E423BAEC6CAA54379CB7BE63BA9B80734B89B61885CFCAA071D75EDA58C477E081013C85DEB583D9880A4D147F8FEFEE7A9CC8C3AAA2E94F11995C7DDC56526643041080C9A261E169FF0F6E66342FB5E11534FE6B9B663C31F31A6CF83ED7BEE917D2220AB173576A83709D7C66A0CE6DF59A7E7636CC9C0692610250092F68B911D0C7EFBC6A89B4B189FDF14131268360865EB051F5DF24E4B41FF2706CB849441E82169591B1777B8C981DA5831D4518D5AEEE0B1A74EBE6E514CF61C86BB3E1243A89CFFB7E538057D46E11A34D234E5BD0DF02F797B92F0D66AE8DB551E56AE444147618A0E68E9F371D49A3BA9543E5C89794946E5CF3BB09A4230E27DD6B287A8D979D74B6EFFC7A86DDDF58FF765F7632984E809E22D741DDCFDF1C813A9EB2622A3A3939CD70A5BE1DBC04B94D209DC321A062FA71C0BF7E27B9CB74CB4A72417C3429755DE5FA94593C90E7879E437ED35B03852584FCF0000FFFB5E8D1869CDB36070078AB85F3214035AFCE6500BD8F8BE5C6E3044054725208E6BED084EE83E3A644D65283CAA794BBA0E3C12D76E0CCB59C1DCD269A18E843AF1948C408C2BE253A42A16CB081EFF82EA9589045569117C400C205BC5B76D75A751955A7B4771FD02245A6942A5000E6BF2A2F49E0DEF0A179DEC253F98C0B2901FC6285C79625380B202DCA00EAA7F8ECFCD8B57773518CA2610BACE4C34ABFE4DB6C197120471382D70CC94613123E64D837BF607C5341C2B83700EFF2C1104586D920190320BF4BD99EF00DBECDBC06547E74831F4AEF967457074AD8B840926CBB5F5ABF4CD86A09CA3442D2BE4CBCA3BB89E04AF6CFAA2DC8234C4AF1187F70962B9A32141D1B9EB57B302F60CE0CA36B91C26C41D0B5801EBF7217A1B75918E82A383759313753574531553455133DBFC28F41C0970DA4D2DAC8C63EF7BA6DCAF9999A018ED6E7129A8B7393D1EE4E1971CF0D51B92E95ED59D7DC63D39362BFCDA34B3149BFD6824CC35AB80F96D09B7AA702A1E95A6AEB9E8DC51DAFE2729B5B9D406183D983243F75AFAA60568C7E185F3DCF07B4A488A1FD54059B8169553966F1AA2D8F5C682C15E934BDD0EE93462C21EDDAC4D652CA1BFFF526F2122BB63F9F79D3278B4440AEB299AB8E68FA237C2F1EF1FB01B5A9FFAC9BA0000000996B19A5990A681A0687921B0FECD3046550E8AB8499FC673704466E8B2AA718955B8EF6B0332E10CB36E8A44384EA8934BD8F5A61FCF25D8EF940A8B9D0C5232FF3AFA05661D20A72FADF55C9A6DF8394CF2A208F72B4578F2018C8306F7C6343BF9226BEF7ADDABEADF20D9A3E2FF742A5F326A76D3ECF8270CE2257DC649" - }, - { - "address": "9849B21B820DF63E853560830B349572D7ED293BF6D0F566", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF09F920C3453A6D68408969ABE634782C2BF4410B2EA3B7AF1CADE97C3E165BA26540916C566268494ACEAEEA20B9663C14782E73C5BC0460A63D8ADDE507E490588214DB58A77A652497697B29DFE73AE23C6F5DE9531CD745E8682875B605B626EF4BFC235FE29DF79D9DA0A9865B9CA23F79CE0C7A4148AE7D9B55E6C7A7F6EEF1F2C419AD91BB53F7DC78F04B7126E3F92D05ABB6CA0EC802B587D938F62BF9C2C6DB06BD4BD827005C0B564A990C2B826DF3A06A89A2A395AFDEFD2A09168E6144275CF560B7ACAE6C10A73F9DFA7D8266BFF802CA981EE5338577F4D764E6BECF17674844A8DC8B3DCDF6103E2712499C695B66FAD2308773AD1122409C82F37227C11B910AF08AF67B50E20462FA30D38560D1CDF31CF141241CFCD1D415AE94D0F1D19E5E7F8E3A6F11BAF6A4DE254B1CB5BA72461C440A61FDCEFF967113E359F543C3C178ABF6C4AC9FEF3402F8B91D4DE1E545405EC8432FB4D9DC24788F4C18BEA63789C128BAEB2C56AB013F1B9BFDF3EC07B686F6FC3A6FC564C9DA6B4BCB44D32A7C7BB1FD7555961132575BBF04D4B4365AC917975AD449B59CB3EEAE553C6FDE21BB7691F02A7FA476C719BE388F8A71147F35B02A158FD8567C0BA0D6F4B99B5BAE655DDCF3151E55B95F7F0002C3104DB9FA457E9E021E3C1805E152E74F3A446F5FE82E9538476F65BA5951D0F2022A6DD30D1F4148A30000FFFFD839451F9379A0B30E0278C764560C46E468AABEEDA1CD92E2178DA7DC805D2E076B8221B2083599CE92007B1072F4777CAEE345F7B66FCF7905EC6CDB55184858CE9245D70855EDA7D94FFAB2E504DF792D3F8FFDBBB88A60D2A2B4568B1E6968457548B381EB69A412ED7524A1FDAA7B8F2BE953E956B83ED7EE7513936FFE2B2AF28ADF5AEE52F3CA39A81988A609BF2C67B8C9F687538B3137D7BAD0B437959EB4153D84B1EE647670B7ACD47F9FEA75B0FEA5424DD73BA65CCC241448DE1252725DC8329D0496994C3181601734398E65E31A2FEF01E14845A8D83A5B6D272DFD0498654DBB624DAE550BFEFCAEA9C82A6CCBD84A84C13BA7F28DE4A7744C3AF7562D0BAA1D52A94C13CDA16CC764B34065F462030A8095A0A4CA327401940C6A5458AD7759C4829874A37CAAD9EEA4AA9DAA0DFC764BEF3928773BA80BAE3982A4808A09DB67960026A5AB93761C251821D56652018F2086110679F1340EC8C1B3EF96E18E949650CDA446B0722384059F1CD46E0EC92A0241FAF319E9003DC075FB67054C92BF89E155A06DB52AE84827CFEDF8E124BDEA38F618D0FBE7FADCAA12E4F847B45849FF1C09326467B183D789E06DCD9B81A27BDACA2D07995C45531AFFB05CC5C06AEB209FEFF2F6CA34BCDFCFCD4B97266B115ADD3DAD7547DC0437726B4883192BA8B9CDD7F5389F0FD1B153EE39BDFEEA6FBA9517450000FFFF597635EC119272F3E28DC9CC149734FF707A8A0ADE1DEF82FEB30060C35FB89CE4EABEF2DA9644148BB1CC26F9B8324A02373E6B4CBCCD4B762958695359E1B8A6A04C43F1093BAA81EE1A9EE8708CAC84B892400CAE016B103377FFA4D0B35F4D9F9D24295FF4C4CBE2530744A84BF7DF9D91C5F45983EC08005B362B78E22C51DFFCB63835B9FDBBA76F82DE9B564CECF178F6829A93736C5D68DB78CE3DF94F84CE08A309FC684B3ECE4BD410BACAF8B054547E8E802AB9C28A3741AC14CB31D40DD903F291D447113E1434E14401660497C48FE29E097F08025E876A6140E627CFE55CD1CE221A8C933038B9DAB371490D1345C1F63A483AE165C18CFEE0C305D6CD1B881B6469FC05A443C60BF186A929D3B3A42907AB71383D675DD576C26640FB7FD274C418DEEA4CF202093994EA7E2664A3EFD767C4931B54EAB18106DC8D16B98D8E27720ACE57AF7C03D487BE852F659B8BF9AF8C3CABE771FB250398549B2457CA0E94F21F3D2B4465457FE14CEB675B92FC0CA276BCA48AD76351EC654DD66440C8C3ECC7CD97858DDE348047C34C522342929ECB7BEB6B5A37F7C8A23A8A6EEAF6F5C01354DE016EAACF6468C38B2A9646D50703983C6B2947EEFFFE3815EA073FA47E9FC91092704CA6B6A0AED84A81E1B64B5B8BD20A8777D0D8BF9F4360C848296307B760951E6A03EDC0508206500F7308FEF0693EB6F50000FFFFADFF83F3F21465F4684BC9F84F575689D5D98EB415468DA38DD734DA463EFA50129D0D28A72BBA26AB739CE9A91BCE609B31EB0037282AB87D242372779C82C1B9C49FCC7340A6A867F2714A0A2181C9B7001CDC3A4A11D56C2626D6F83E76CC3D48685802DF31CCB8376376AD3D7F017EB97C5D7979FB9BB961321E26B5FDD0E7AEDFBF2AF649AFDD788EFB8FFFFD4908A32D1A8B2BC2E8A3CEE3D2B8062C8B96DB3C14388F69541544CC5DA5ADB7E2320C587258D8CA00C7D1E47CD9D5FB1F505897F29FD2949B80078EDA25D1D77FACE96F10C7E310B36DD1DD74020AF24B6F1627B249AD54CA1CEB8488F8D7C9BB7D2DB08B1BA1DF12EA570342E4F74C802747720193EC07B7175C28FD1A1163C410BAC8716284C0010B9286E3E87534AE993A18A52594C59DD4BCA2F108351ACFC4211A27AB851ACCC95A6983BBD47DAECD67E686966E3BF8F8E3D147914DA4AF7E3CEE75A6883D8DD40801AC38DD8B22007CD0DD5D416837FFAF9BBDB9D857219C704DE12904F8D3ADE0682C18E96AF2A6EA3EFB2EB502E162471F04002615B63CC6DA7AB06300AE1CC5DACCCB62C3579B329FD9AEED30B9D2B459AF887FBE263030FE687995BC77D0CBE9F220453208D254E07D6A441B2488D6FBBD7522B83BC75505B054BF4FF0B4612A9786BAAF8B34A3DC01DDC323F58E53D6EADFB17C43BC372CF99906BF3793A8A122D0C6AC000000A2003028C3460A51C7B2AD34EA3B7498A086E2AEBA03D1BCEBB66FA59C5B1B0123E2762AEEE0A5E171C334734817F7EFDEC96048D162D2C96F5305D9E1DD3D51C90B7CFAB6322C852095D4A119704BDC35A9C054789E7BDDEB334AB7B742D5A6E588FF3A46105E4D66927A4284330E1DA1EF6659438E2C546CDE6DE332441BE308BCF15A5B9B6B43EE247D7AF5039FB41D3F29347365C14308BDC4A8A2820C314D" - }, - { - "address": "987DDA8F07DD1D7C2FA5421DD63D17889DFB1D3415F78AE0", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF02DC718D3420DCBD628A16827A2B71ED0B300B1AD3E62A001FBF6FF6DCA25BC32D91FF65FB0C84AA31ED0F1798080E3492383A08F8EF84A935EE0049D54E0C30FC0C7046772BA35D4EE5EE6B43111A1695EFBC288564E57910D4B5219261392CDA7E5B9E2E3555EBF3539AD527CD39B61CDC661B55A419C84C41056A363BBAE1FE09432BD0BD83F58F25DCD00F3219841F715E1C01BC7B27EA4DE445C3B6CA77A5182E00E03006ABE037C57961926DE24AE1373A286C992432B0D3B6F6FB04DD7B2EFCBAF51A8805376B444E6C71CF81374E4AB7FAE0C1CCE5C291AB065D76F145E9B52F0022867CE8D3BBE6A1F2712D9E9ED435E1EAB239F074ED723D699431D093AF079EAB622FA9978A032E80635F8997487A92F00AC6672D2E9ECB411831DA0124EF44E6B722B79A547E388839DA3619CC73B4D41BC81CB4D5684C0CB74ADC25707B55B448798A0D16887CB3F2167B0E41EF5675F6D890EEFB5D12323DFEBCAE90C18AA9DB4AB0F81B13822A475363C89DBE4AF6BA95EB2DF478EFED8968F1455614D44E519CDAF89E74C63318A2CE60E1E1F76A29910324101483F364A58647B469FE33AB9D040B2AC22F09FB7B50E31FABBEF1F9529E45B13C64271C86C68A5F0CFB5DB6A6764D9E16DDA166AE06552E4B2C2FB4F364299AFDFFD3535B98399BBAD3A167E59DC03A087C515784B16DCA10FCF5374C9FFD426C4C1DAEE20000FFFFBF24383DDBAB272E2E42BC254CB4FC0763A622409F8D95A79465ECE413E6303177B6A4DE7C89B74CF8ACD7D7F13900B8E7749467F48D734C146E771969D279CB6218DD67F0D3AD5707BA874E757DEBA222F4ADBD27F5E582132A07F6784F4E63CD0F2FFA779DDFB716680D859B96C7C4F60278149B3DCD100C7E097F2BC8DA808761D6C3367C93158F917ADFF782A0B7C9F8E193641CA0FFB8C1559DF4043F8DC7840518B9CF91C0D439DA6EB9D82680CD362233688BDA41392822DB3CAA60AF0CB0384E233640DFD25B336CE1C12CDE2B4291247F814AEF212DCFE0B70887EA5686A3222E48B58AB1F587F686C0C6955F9DB1C26FBE295E4FABD20AB85F9B9F7895B38DECCFF692FDB5D481DF251F140F97204737BD3D5EAA878066AC12F1CBC227CB8151CA0B612557CC5EB6B705DE4017FC1CD7A58AB9829573B46E666813E94499435E192C5A53714063365568A6F78C1308A5F0FD1E1C4FF455623040A5C69E88520A6A832648121466917701B9D93A02759B4C36A04E0AF21150FE2F146BF54D5D40636C7CECD7FC140C2D60558E72EABCE727D13C0707EAC58B46DDAE80A472D9079A5FD1C3C264AA59889ED28AFA4DC06951172DE78A99C3EE5D65BE177D8CC5DDD17AD930952C5592CAD6959386D8CD63F702B82CD9EF5DE4AD6A49622C7CFD35FBD06B9013D4095910D37517756E3349E19A44E8BA828285528B6E0000FFFF7C3DD12D5AAD6A756247A28C81C9CA08C43B754876271CCCE37ED9676AAA0A34CC7947EB005B51B8646D452936ACE5219CF8E9788D8437025F4422D3CF7C93E7AEEAEFDE66B02C54FAC5B0AA367CA28CB1BD07284AB5C2AFE92FCC80AE47CFE074ACA3E15F4A321D5C8BE7DD9E7C05F41F9A15EE5E52B67AD53BC9A779C85C8F894546158EC5BF9447D5E6D8076940D5A1B639F57F17C4DCE308BADCE3E207F6ECF5DEDA497CD6E802C8AD624C2E5E47B16A39F79329AE41623328C212DE10A99F17BDC0CB177ADBA5871A10E391D7DECC4B7586861011D9A087BEA233F12CB561E02EAEDC9E43E8AAD24BF9D3009F8965E38DF8584B5CEC84570E4ED5CD25EB84CD3E66FD7F337C9E4CDBD4A28F240DBF0B64D281E8ED310901ED09E405BE390FC66E4AD17287781177DA893F7511A7AC94D346CD89012544BDC3271F5C7CC33F105A84EB9034A3A9A3015DF5D2F859E42C18B08999F6000AAE25E314F77D3305F322ACFB517863DBE3638412BA0EBF1DC5B6DAB89BE733067F763093693951DB78D1A1D39B34FA43B4BFE71C1D0F47BBF24F19894F1BF1DD39E7A3B39CF2BA6D1E438536524728E06FFCFB28BEB67347AC7ADA14D0C54A1CE3E3D295A69B3CC25A2BD8EE7EC8BF3DAA735CE629CCF1B2BA49CD4B2678172BFCB3C7226CAA64D917E7A031D512DB14C97E087D7A00E151EAF0EE087153A02DA5F7B73C1157D40000FFFF12140817F88220519CCE0B2795D7A4FABF9B12704DA9FE240A019E35118C05C461D04B803FFA0C15898E28017EFFDBC1E2077BF4740667156086561015330F56E988F824D1EDB4A53157F637056655D2400A9C478EB2ADB71FDA87328ED9F24EB844E1FDA4D9D4EDF15992C990E92D49BA6378ECBCBDB78EDA4265ACE6D22CF279AAE750E20680D379C2E12DE386FDA9258704671473F17D785CB73926EA4E14E0802623B5A7FA13E5593E805065D31A18D34057A878395F91F94A345D102EF2712EA1319ACE4273FE2AE07C4BA6AFE9F56231FABAA06A675AD45FF9BC04F9AFEE21022FB31B9146DBC1C5E13DA84EB17EACBD067C237DF02D8AC20DCAB8DF6B24354735F3754B4FA24C99F287D064F106EE92CF10F1216AC48F0A390A67C4F72FF3A2A0B771CDD5C60BE94D4EF0D9237EE172F8FE35CA6A6DB7FC1A2371127761B26FA27952DC1BF1C3BF5DD96A2FDA4E36522E4E7C6CBEE02BBAD427A6B19A99D8F2F02F6F2F8BAE052D902F653AC40A8CA3D4D3562803CEE80606A2064757E71A2BA259001E69E8476871DDAB795ED30E0AFDAB09754F12257BA21DD62E266038F1CEBF2286C8363745616CF15DCE95B22FF2A494F022EEAFF4AD6238F3DCCAAE9E31228AF6649745853380513D8840387C3321F3944FCD9DAEBE616030B29E3B975903CE6E1E71AF3AE25665E2CD7077A5313D4D949759C1D3B5D8DA91D90000910225F6AB45852E032C29C1E0D56E2844B5C52A8B4979A7DAD0B365E728BCB92FDDE4DAD990AA58DEED96C541BA32290A0D644B9B449C7277815F61045EB244330354FAB818B0CB9898C0DCAE9C610CD9ECD9D0417082C1DE5FD49FF27411C014B0858F0FE10849F7304147F9CBC023AA2E859E441F17EFFDA216FE3347C066D182FF3AE2B1BA0FBED50E4EBA618AB87971C1049CB1B48D6DFECE5442425DED1457F59F68BE08D218622E1FFB93EC16315E2878794E1D5BCEB399BBC7D008BF9D" - }, - { - "address": "98C678F8D9AC3AAC6D5F11EE5A149658AD79CB22FEA3879A", - "raw": "0000FFFF7A8EC103B65FA7ACF2F18D9C0B836FD838D26236EA7C85DD5F4EB1475A501BE80484531DF723011E44499C216FB7F782753699A96B442AB5CBCA3CDE92A3779FE8A9763854DBF3F6AA487879F15B1588D16DCB5D874777E92A2E35584F1819DBA36BEF42C49E9F868308E42C2DD5647A5E6B086C319E7F77F034BA8B434702685F947A68C5A200B211159A911FB27B58B8CA3535A7423D3279522DAA3F4A91F7B499354505ADAA1969D8AD128BA238622AE3F25A23FEDAC62C8942E38096ED7824236F471CA3E0FC908960440E8EA09E22A63233B125E7E910E24E07F49C90C39D31BD1693CFC24E3214EAE4E1B03DB0761470E1544BE56356F36DB08DFEDAE087C032D6559072CB3F8ADE2FDE36F4CDBE8AE80EAF19897F0EAF6FEC12EEAA9830B17AD2313BAF716911D86AF9F694E8CED2204F779547DCDBC2880E96A7666AB9E99F7DC3ADBF0ED462D80AE423A2DDC2CBFD612DC4539903ECD920DCD4B180984426144CEF45BD69C41F201E6151884AE4BE89263361C87D445536F0EE1D77CF905D3648B8322EF837F9EEF22BC87D7CE61FB7422FB7596C1AAA5389A638F25784AC767DA055EDF1E5D28F61401D7BF2550EFB4427D66B1123E46108D752665C9074DAA3869C6E38272C4ADB50643D23F8E03B4FBCE644D58C7EE79275EC48012A6D20EF42F4CCB86E2F992A6DBB876B4D67971090B828807EAE6B2E161B980000FFFF31780FBFF8BD5E6B8608C766DAE8AEACAC1D5720DBD0FF64F34930C99718B235D089B12314E65FDAD07A9D57A341CD4756BFEA06701C7FF99ED1506D0A8F29425BD4911FD76BB6C0EE68075C589FC1BC4F73E01700CC9F56D92AF16A8EBBCB3F6A364845CC6EEA33DFE3585A303BF19D04107A841641462E2112CD8B6D977DA5913BE57AFD5C5047E40A47709CFB24F43B0809183ED34491481B3E90983545679659CE3CF64A8F4ED4E3BE4C25C1F10A0CB11CB4B663411346D7F084007D21011C017EB4540BE5EF4F8AE36CE231AD80518EC64214D191803DD5005B56C89ACAC4C3AE8EB4F81DE6441A955053217E7B6B4DE037E1AD4CE74B7C938DDC17F690AC6BBCD9AF42875CECF65BED47BBB9F0DC6D300270437B2FF8E8D8E424B62797C850531E998AF1D2C81CCFAF02CB0713FA5DEB7B6ADDC14DE1A192AF28E14F5ED85F058850752ACCA04CCFCCBF5B4E6E6C3D2D768937BBA72919F142D4E2EAF7E0FC7971F8CA8AFA1DA6BA240926C85846E8EC6652ADD8273E87746225754A689FE67636EF5D41D46578AAD33A7997D82DFA418131CBEC707DA6BB9EB7FB1E747CB1970ACCE479E53B147B0FFAC85AA4122D1C0548BA150967B342C8CFA3E124053127DBE6FA4352D4C2E00610191DB49BE465B63AAF6846C2FA317BF6895CA5B83B6F4E56B032D4B5F3A67CFB53147589DBDD37EC89EF8C8FF61056E62951910000FFFF16263703EF198199922C41604B5EE25EC2104EBEA6D8EF94BB124A4FFAF87DAFFCA44C29EC7845684B81CA0D1950EB53739724B0A129B3362FE007BE2A06244C02EA0AC59C11CE25AF5A4A00731CB0FC971EE36C01F6B038418BF575EC5C4C374EDEAB4D50CE29BA1BF9C15AA5CAC6B2D1B457330565E3CEE2BC24D26A767DC27269E0577E99D12740E59C2835D0C5BDE3F9D4A6A90602172EFD8405B7B9EB9AE79ABCFE39BAE7A74C3F2BAA26CB94C70C9188DC258A83C27725143C073C176CE104A7BCD7BCF06E4D5308C12DE1038A6D5A6DFBDC3FDA411484DF51F5C20C03B6EE565BC4BCF06B601D3110A341EC9E52714CFB694AD06D563E546B96C7B36B67211756A0527CAE419AA332A05131AB3DB1C6F41222AC75DCD3DE53808C28CD56E7B0207D9FA8B810434923C9BC23F7D87EF2F7C7B8019629C827BC965AD85B15BCFCE958A99F541DFCBB081D53829D879A507159BA123CEFF36B40878189C823158219A3437E31C3CAE0514A77BA8019D735A0C0E8FE8920656316A5C5AC269F8829591D76511A598CA515F8758A07FE7A52D664107B0EE85113CADB3EFBAA59439A8091B9EF61FFB976C90F24972D1860E2A4CE97D927490848895BE379C2FB4E2BF00A821E677A7530AE2F7B69797A0ADBFFFDEF0B2620A1FF92CC4A18FEE438776A39587EF334753D6E459CD3CABB6D148F457DCB42DAEB97CA165C047E0000FFFF1932CFFF92700C31B9C46FAEFE7F492E786003DC86D146DB4F2378CD80508BEE60108CEAD7446A37342DAEF06ACB000D609532C3CA70EFF0CEFD0F17FC2FAE0524F89216D4E1245C64DDD1D8B2CF799ECE7A035836F619E898B6DD083BD1CC7FD0DF33E8ECD34E89E6C913D90C4F8D3F332DC7994D5E033349ED497C1213ADE925852FDD92168EFAFA2B8D64A5EDE49108AF17AABAB051F13663FA64D4A3F352BA4D964DEF91BD19DD1B35F9CE5459868907DD62D70355A4F1AC7F249A818C67758C6F92197ACDA22198D86A6FFDD5A8616B6057D6F957728E5CA8897E94B2E1D4C8AD79D790A5F3A648F70AD3CE2C8F4222FD335E36FFB8932EDD732893D3B17F93643169A1F2A22B70D389D81225C66299B8558A463937B46D1DE0BE11EF83D9469A76B521742D557A4CD1E1F691ADB8A76A532FF3A25E4DF262EFF1B4A973B01E5D5CC8A7FCE7DCCB1983536F1FEA09D4D34344F31A73498472069B14E192B4BFB30D78142FDBA0CEE6A5846BB2DF82ACCC7A5247DDA2483F8BA17CCFA32D174C36A6B76C5A1E88FC641DA1E2897665B64A8B6D794E6C4C316E1388066103BD1563F3C10768CEF738CBA2C2C91571C6A5C317EC9A4438EE9B4A73A933E5F5E79C24C40BE5D9D1FDD19D19E8312B48C9CD1D9CF50C21487AF358507DFAD34955C19555E90C1B0922BE5D1F2AC197D0F7608B2EFFBAE0F4B74A2F63EBB44BFC0000DFBFD877A040971B2706AEFF898E141D9283E8C6197118CBA1696356EB49BBD49E9E28289B668B766B44B6672987D22E85F15CF83AFCE2114AC4960C75D0A88776ACA591953249256EF30ABF3615C175741DD4CE8E3E2B7956DCDD29E259382BFC683499FC7A545BED65642FA47C382DD4BC2B637302167FA99B3BA3CF1E92F2FE06F4D357C2C770E4B45E39B4D2796C5B4FBFEB9AF8A12883D733C42308E32B6391E24C7C66A32E35FCEBCAD460C33EF630C3DFDEC781979147C401A38C6C6D7A9F04CABF549817986E7F4A62B764129C5EA8D5BC0E91A34D6D8E56DA06346C815B27EE266E814B6A24CCABECDDC8EB39097C536497D78E9B750E394E1836220DE8519F5599D79619BF159497331110FFC1357561B5449464D3CBB1EBFF138D8D2D2F37356B415F18C06DA258C561D45E9A7189170A41D60D401A75F96A298AB6B3821727C0D37B40D33191E849660119D25C57F03FE1DD19DF3610A8E43BB2D6CD4E5F2D50190445A6C24F22B39726E19DBA7F829AD52086AE0F3701882D77319CF44844D3CB87673D379631F3AF40AC4DDFAC972289389FE71A11976863165F7535FC61EBE539B6A126258A1892C1A97B131601F39015A4FF254B9B1E2EFBD3D600005002EDBBCE9C967733A6D12779C7B30447650E5E68346A3DA988EBA1F5C92DCB3F7BA574454B4256AD46CF15F12AB35EB7ADDA16A358904FC83B5EC972FA7586B4600F3C1970D38A91A0E865C1FD7273316E589F7277DDD1203925841E8F891F8804FF3AB0D2C0439B944CE3528083715382C087691216DDBAE600824BDA060D0476B3316E69FCD503C2E064E59D49E3F7035EE38C5808E0F5F663118AB4233F82" - }, - { - "hashLockHash": "94ACDA666CB5B4ABAD68AE5668C9E85386EABA13552CC54432B81D580200D1A2", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "AEB37F224C1EEA31299A478012B7493C2078E250505DEEF7A02F541BFE9AFB14", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "0F3692C9550CD063CAD90F398B089F34F41BE8306552A239FADFAD471ABFC122", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "8D39C51F0D98C5700FB78FCEF063C8EFCF454651CAAA9FC6CA9F5AB99EA2F7FB", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "21B9F9044D1D21772D93C57A9D23019AFFE7FFABDEDAC6640CA1ABF849848154", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "A59F31F7C3A1AB21A81E6A011FCEAC3144550DD89ACD4D9CBAA9EEC17B0CC051", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "F3466C6EF075017B6A1AAE45F074ADF342EA0304E843D35DE67F1E9101A875B9", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "9BD9073DE6419F088884104918AC8B62FB1B9ED32E136E93EA3C51D2119D2A2D", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "31F2B05F370D1E98452BAA2FA3A4B07D8DCCF0B5CF3876C165CEF143737AE4C5", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "hashLockHash": "C534457BF5CFBB40B803BA374D2037DC5BE05E3FC92783AA164FC01DFA91D6A0", - "raw": "FF404152168B32CE79DAC6A6BFC485453AB0F39745764ED4622463DD609D6BE30F3DBA5E872611489353BA5C523CFECF27AA331EA49180F5CEEF4400F7BE7A78FEEB" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17C", - "secretLockCompositeHash": "4F7B29DD2D9C851D34E98076DCEAD5C650DBCAE3F39BA7C7E4F9CE5758FADA78" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17CFF3FA4FBCE8D78CE2C7CD674A81C967E49C7AEDAAE73B279F9981C05091EE2BD3FD0F7FBB73275503294ACF871299F7207A1AF288CD4EF54CE112F749FC27072360A", - "secretLockCompositeHash": "2205D6842E867FEBE3D5064483256B329357E294678A47321EB22FA71188752F" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17C000080024F4ED0F02DD13770B9E0CF5061D820EE62A8E428889937B15F88093F283CFFA2799AC524D30D38EFA1B691F6FCDEEF32E1BE878FD8F42938466E4DFF408C6FF2FF3E8C70393608C48A4F70B833075167C7BA029D7E2D0A3265BF6A67715614BB1A6E35C6742F55BF35187F7BC3127CF275BAFDD273CC4013245C9617A2776AF176", - "secretLockCompositeHash": "1AD66DEC5872149EBB591AC11195E0A061BBC668E07C1BDE0AAEE66CDAE6DF14" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17C", - "secretLockCompositeHash": "F2DA92800BFD7DC05A9BA0D187B970975055D0E476AA3EC82520892893A3DE90" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17C", - "secretLockCompositeHash": "F48DA83538F707EBC78B5E8B0CE6BC3BB73D0242F39C4E02860C5D820EE927E1" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17CFF3F2916E26F1D75E0589145156B6F04A2BF602808C4A1C7A4F862B38D75712ADD204E2737B93133D2C9349750622E2F2740924789733C09118F3ACF84667D071AD8", - "secretLockCompositeHash": "23B6F6E3713FB07244408558521BD967D772E0408CAF486F6989E824DBFB5365" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17C", - "secretLockCompositeHash": "FA517146A20D95FBD2D508C2C34611E318DE3679BC1CEF117267B79EB3B11134" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17CFF3F88A389B14C0206C927E910CCB73AD42F2DA5C09EE2455F0E6101BCAA88600B70A7C1156018ED78B50BA6DF67612D1E7E1A427F4FCB8768DB3C0E42B0168A772D", - "secretLockCompositeHash": "317441C6CB4C0D16FFD917B4F5983954014CB3C3A36FADF8322031F0C0694BDC" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17CFF3FC6D8CAD6FF6887EC62BBC9CC3A79AE21305841EDC9B748E5503AE81FE5B34E80564EC7EA0212258F6143E0B29D2B781CCCC7698873759BDE9C0EE41423BBBA4C", - "secretLockCompositeHash": "C129F741AD19C9DDDF6D0683AEC53991B5789DBD97F30EF6FFA6CCB09518AAD6" - }, - { - "raw": "0000F8AAF7823097143C66659B54D5D55B58CF3CF4FFAD8DB9C8CACCC76455BC27F8F3826BCB63075CD9D4F65B070C3C2D011E7A0F9870CA2E60ACAAA40488915A696CD51A9E497D8BF212D8B4F6098B4873E0CF3B457F85B3B3C9E73D78ACF0FECF0816782923518658A0967CAE38C2D72154AA016A2014548BA8D69B444D4F700E68A35A723A4D1E37A304DC92BFDBBD31AE3BACAAFC157509A862C983863B11D143E7A44DB662D895A2F3F39E026B67BE62EACBA55BFA2568AE2FC90522C3E4F162ABF30CB72934CFCE09B12AEA2D894DDE1BD2ED27186533955563BDD72A74137304FE700711802FB0FBE500F4DE0BAFD9D60E1E5DFC4CF7921C2691ACC66DE854F572ADE73DAA9956EA0D700C17571F8A50AAF8E82D35AD6BADE45CDA81BDF4E17CFF3F2916E26F1D75E0589145156B6F04A2BF602808C4A1C7A4F862B38D75712ADD204E2737B93133D2C9349750622E2F2740924789733C09118F3ACF84667D071AD8", - "secretLockCompositeHash": "18364CBDB8220D52E73ECB51DC73FC09C1D05F163703EB6ACB5226D44A590737" - }, - { - "metadataCompositeHash": "969C0C19158B68C1D5DDD116494BF4F3A5A5F4FD7F32AB0D63734899FD048620", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E460000DED0BE7D2D32D2DF35E36AD3507179FE31D0644976C469B63B2E760749B194763ADAB81BD3A6CEBD31FBA09DA8404B4467A440D3114C349F6245536AC3A48EE771A71FA09F3975A6FD6291582B001A602EBD388A52768F115CFC3C3530429309FDAA41D4635A18B3BB85936467E21DA968BCBC5AFBF1C242D07FBA9875BDAC60D11AE4DBCC6ACEC2743B4E9AE4CD8D986B8362E15DECBFF6AA1B9C7A06557CF2CCFC9E695C9023F6B4205009419901AF6F59D837357CA687A6B29BA46E95B79D86FFC40203BBB4DE56ABBE482E55BB076307DC737E71308718A4A93D1CF1B207E6E0F99434F43579E594207E43CAA4FA5C540339563D33C7AF550B77C8C3E5314F85EF4C165B1735400A3931815B5E822B3BDE5B42CFFE0C3DD99C1D63037395C896FF3EFB659AED418BE337B16A6FFF6CEA20EB414D824D666120B1FB40F68F5E811A89438239553D48E32B41ED88B0E0FB64D25E1A905740F7960DFE4EEA421CF3A3" - }, - { - "metadataCompositeHash": "6FA144B67AD7855E97FCAF09A65BE6A7DA87505A52451DD54C50474A938EB9F7", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E460000A5FD7577EFFB5BB5090337DFE5E51251FFB3E7C596DE813E57B6429FBA8889922FE2575C6B744B32520889940BE5445AE1E072F593DAF8F7C092447F5659457A62585CB320CE6EB790A1A5B67844571310ECE0746337C004860496DEF6126F4B1D4ECFA3068F83D18FE080E44501EC2A7C66F1449C74DFB4D416E6B89EA348A5AC9BCC1C08222B237BC15EF8F683110FB29DE52259F9DF87C4C7ED25EDEBD4C6610CBD4ACBAFB93DB9FE70D966402BAD2559503AEAE139D9BCDE6FF845C84DFACA4F6E76C06A4F3792B20A36B1F0F4F8BC3B1B104FBE92F67BB858208522EBB8B04D881B7D8353CF8D1292C7E3E445166C3CFE4FEE9D71CDF42EBEAD6664A984B11099A4E4FC2A0AE162D37A715BA8FCA17508296D402DF19F45BF90D049E996BE423E7232A007592C9C90FE7D7EEE7AD91FF6B27B3C45D78CD170B6EAE3B95E17AC9461C11EC870566C9986B1723D798FF03168C13EB49F8BEA4A351E55ABBA1E8A000040826F03D6730623CF55C36F0D1710DCED2E47C7EBEF9987CDD1DEAD0AC5380F735CFC534A093678B93F1573691CB5E6534C924135C57896BDC7E4EBF97365D1DC6EAA5BD6B5BBA25485301302E14B892601CBD884922193552111DE68B6F15C1B9AFF3DAAA438CEE988BD459019B21D33983759D6B8E141183F92783AD831A110AA10E48767778B3A9EA3AAF1A1DD17B9B7994E1BD680C8BFD72252D886F40C0031B8" - }, - { - "metadataCompositeHash": "3BD863DEA9B132F535E83B2DFA71CFAA170A98B16AACF637D45B8941C1D59637", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E46000066FE83F574A2E7AC6C1AB8ED90F8DCAE032A00734BCB1F6FB7DC1159CC32420633E06C3E40FC0AB51EB9295F483A3307319C200C00BBCD8E971BD637ADF1B46A55E37C0F70EFD9B429513A00E1B3D93DB1C286C80D292F57BC22F45B8849024461D92A9FAD237F36B70A1BC5242292DB574DBBDBE5FE614A55DF777CB1ED75DCEB586DA4E1AC894B22F2A28BBF380E3C259E09B01F43AD10DE73EF85E1E271046D7FC22CDBFBD61473932F8D537E0887342789B4F1B095FA702759FA96B6068CD65F3FA995847B4EB34EF8A8F014ACE7DE137F666BFEA4D6DDEA416D0D2635ECE9174D3D2BA711F4952F1CCAF228953EC4390A1C8A0B007B89E11D1C629587D48E8679DF8FD4C37B01B0790C6717D9272463A8AD187B6E2309722765310D2796C9AA9A85F7EAB857AA479F91FBA8B0E0314BB66C9951C45DE935F17B7139E4EDD8824946F8501889AE8CDB31A7E9D838070148D6875BD7047A7EC199B528E4B77F880000800262CC870FE5142545A4D7D05C7E3B948330A701524DB81014BD234EEF4D2AB829E4167AA3048BB2ADE749AFDE873068FDA30525583707CBFF9FB67130D1ABE18A00000085053F907AE625D8B31BBAD1636F14A000CF477F9BB2B1F314EA7637B3CB61546D7317F6AB0F4DFA29DCFC2B33157AE57098F20C9B575159A47E448DEC88A442E87007420FA4E152F23586853D9451F251963405DFBF953320C96D41E0AE709D80FF3CFC4C63150A5EDEACB58CD5691CD486B88B84680DC368DFBFD09D7F33F8C483CD6FA4C779910DE051C18A6EA6D9B42C853FDC9F2C2567FA536D8DBE477481" - }, - { - "metadataCompositeHash": "78166EFCB25774A2C3E8F9E3B69608150A93F90B9FC1CA3B6F48269BCC37B11D", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E4600006C4B7003F840FCE9BA07A68BC41CC163A41EC76BA8D20C2A31B24098DB46D298EE04A617CBB48E1F410D35F93889EB93C4A8B8871B7C3663B182FDFAF4C48D4BED50F76407BF33DA853EA66CC48BF51313F29CE4D7F66FC837AD6BB3CB0CDA1BE499A8E7648BF6D27A0275EC98B1216559EE4ED41E8C8CD9293200C3EB73A52029238F7C544C3A5FBC3F170A7BCA816FC4A413FAFF5B17FD1192F52C76B064C030F21A2D4EC0BCD41E7E3CE3C43CC551491F0EB7489B0359254B4BEFF8866C830A5763570FACE8625DCAFCF938C58D0EDAD8BB0B9E9952EC8D77AB8E2F753A8724F4F01261F38B46F48B7EA40A6BE56095637D683AA45E2D226F24E605365B45BCA8000081005EC89424201954B844F3119E0C9CFD7A1C46D9C67BB7B720DAF296EE6ED00E2C5BFAB769B914B2A03984D187EE63E4AD9788AFE124582C38FEF938A47721B6FEFF3DF0ABE4EA70725BA83F45B6B7BEFE82C17C0D3FCD7450001F7E003110007340956DA6A7DF356593CFA4AC45CA30B5DE3A96C0972E0A25B002766DE9B7357FE8" - }, - { - "metadataCompositeHash": "754B2CAB97DCB666F31FA8112A8919FE3AAA2E4010C5C78A2DCBCFF819EBC806", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E460000F29B4FF71C3BF5080B1D833D928991F2DCF1A6768EB5C72F908C57F79FB79B61AC86E4C0FDA234CA8C9996A0E70D9092930EBFA4E249A0EA9D7F01C0614641390258603C6B373D7ABF744C300CCAA2DC99E6812B99CAEDF030C693930331CD9BF5225E7DE9DBF1E6C0932A7CC18CA86B3DD1F54BFE58E48C023C00FA57E594AE39AEC27EA0821036D5DD9F3136EB75E7652E9AFA9484E109967075C4C313043FA90CAFC8D818AD0417DFCE6294A40935246A09F0F99477034D47EFD572ACF656AA79C532504342FEC520CBBE973D257324696159B7BDD3AD6342E2960AF55B15C39B86B7DFB954CFD2FE6C90283596F41DFA2812A8D2AB86394AA5BBE4A27DAFE88DA635BCEE6A650EE8E69845F75BE23FE4C3E17004D36FAF5771E2EDE7B72E2976E2CBF502F29B043B1FA5BCC457D4BDFEF885281FAF586228302E4620EC0E9804000000824C074616CBF0382E98E7D9E8B4D048A9673D335733CA7E277CA4A3507EA8A39A858F308068CCA05F44558A5A10A3E1BDE86A38E5CA3982B87A0048828E22179CFF3DAAD96F3B504B13A045F527A82092596F049DC564B8F30FC7A69EF8F400AE409CF8738835D26778B6ECE5E96E6CAD3346DEDE3FBC85CA93E857599F3E488D0E" - }, - { - "metadataCompositeHash": "ACF6DE42791E7AF3980DE312EBF870714BC418B7B843CD1EC214D50A2B4635CA", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E460000BD3F3EB3C005312AB0729B103C11F7C1DA5C7B82AF22E567293B901837C898CE8C9F4FCEE35056E3CDB2BC99E1BB8E5961A24881DDFDAFCC05074FD115D681AE73615DB741B967461E2FF895D0EE542739995DBDB7A1F198C46355CD68AE0D7844708565A36B650B427F16520CEF33F89EF029D79F15AE5FB668667518C7D9305DF4E442169779FAF949F4E63A9071C3F87A582E7941D7FCE6C75181D5C5B2EB74AD95C8303C7A62987926113328DAB610155804DB7E461669CF85C7549D640FA97CEA44A79393ED15C45B3019755AC6815812F841081206B59ED852D93D29A23E1E791DD5DE0C3BDF0AC31AC39BC7BAE778302D011CF3FAA17AE2043F6F36A149BA30C3146C43747918F037B42CB6064E11719ED2C79C7B8AADCC020551797A95A2B8B2AF09855F6646E1AB2697BB4F134A8E59B6324647BD6E78D8883B92BAE5A15F7DC6F62F5BC2D1328A29A4F7529528FB1F94EEA6B27DF9105EA6D245C10AD1E011F2C483B05758BF909C98E6A60946F3831FD07D0371721BBA3046EABAA53C000001800C7BD4BE239A099F56090ECA0099744DD0B3500A1978943FABE8A658204B025D809469C48A8C87E28D5972F95A60A45F5467DF7B0EAEB0A79EE8E4BD01BD76EBFF3D51F71178E74AFE8376261D84958E3A75C5876B8792339FCEE76A16758A46C00EF79ECAC7C0B9E6CE6433106B0F9FCAE9834D3B0951848B2789296773CFD97F" - }, - { - "metadataCompositeHash": "A67109874A2D6B17E6E9950A987AAFB2CE31062686C8194E0D29B0A1B58E1ECB", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E460000EFA2984AF936C716884479694CE8FEF04C602C994E33C1559A2B05C8330E019A1202D44B92C0A60C7B105E7E1A0A05B75086A9236EFE7EF648B1DF8291BE8F8D3CFE9C3A8CC2D8CC714BE8FB767512ABB124E7EFC02A4ECEEE3A525DE16951FCA10CBACC3625B67F30BAC991115ED19094EBACC0F163661086C69015ECE5E35D1106355D555FBBDB9CFA4B8C523E3AFB7C265A64CE7BCCE919EE2BDE559789E77E6346867AF13E93BB8175F431AC2E2D6097AB370FC6B27C9CFD2DD44902E5E8FAA8F036066AB2A33A0C07F10A15F38045A1C33792F804566B278EA3DBA9712EA3775D1FC3E5AEA084AC931F51A6E4BA24C7C036FC956E9271F3F107064ED916AAFDD155499FB2264AA97A97B3D284C1B271D8F437AACB642278AF8BE1269022060A93B4C743518203823A094DACA7E3758BEA7A50CE87D47459F5BB3A45CB48230EFF3EE4428D0E3108ACD0BB8C5C86659CBCB4650CF5254EBC8E1D4A809AF07D61A521C543E598D3AEC7F4B4C5CFE12D2B840EE2DA7AE5350EEDA1E8C3C797C9E8ED" - }, - { - "metadataCompositeHash": "99DE9DDEFFFD50741DC43954F4AC76293AFCB38F547F480CC319085023B7E53F", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E4600006B0BC95E3A9F8EFBFB5BCAF39D400EB026DEF9704D1F4C2C56D886854BA70CAD319ECD157095DBF4B42EF9079DDED71A76A784768E72AE7F10E0B288E58237D9ACF58D369922DCCFF43AE25E95E4802A2BD56A84C9DA479D579108BB2D5A702F450B0CA3151160FAAFD082036C6134E5E49EF3B91206A04A36102FAB5650BFA1BF792B33EB2A470DD74AB629DB9FC3240115877C032A387981F4228DDF556488BF4F7E6DFA083E50E1C87026F698DA8F56FA12CC91C90FDC309F07D411C2019216F41282BB0594B061C0C0B2A6AA84455E210D591BFF027964FDEB4F57051E76DDE78EB4F282C915D20A478EE3D8A179C260CBBF176F9825DC00E8482856FED891FDFF3E4D015644406D1F7B0C2A047375EE1FC1B116DB7CEAB0FD5650ABA433D162926D23089B15B622DC62AC848E938621CC3BACE8E51E4809EF9AABF47B561F2F46" - }, - { - "metadataCompositeHash": "6B06A2D4D06E3C8984F46FC2A2B012C5D75DD15F1B026F0D4CB9C543253FD27F", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E460000A5FD7577EFFB5BB5090337DFE5E51251FFB3E7C596DE813E57B6429FBA8889922FE2575C6B744B32520889940BE5445AE1E072F593DAF8F7C092447F5659457A62585CB320CE6EB790A1A5B67844571310ECE0746337C004860496DEF6126F4B1D4ECFA3068F83D18FE080E44501EC2A7C66F1449C74DFB4D416E6B89EA348A5AC9BCC1C08222B237BC15EF8F683110FB29DE52259F9DF87C4C7ED25EDEBD4C6610CBD4ACBAFB93DB9FE70D966402BAD2559503AEAE139D9BCDE6FF845C84DFACA4F6E76C06A4F3792B20A36B1F0F4F8BC3B1B104FBE92F67BB858208522EBB8B04D881B7D8353CF8D1292C7E3E445166C3CFE4FEE9D71CDF42EBEAD6664A984B11099A4E4FC2A0AE162D37A715BA8FCA17508296D402DF19F45BF90D049E996BE423E7232A007592C9C90FE7D7EEE7AD91FF6B27B3C45D78CD170B6EAE3B95E17AC9461C11EC870566C9986B1723D798FF03168C13EB49F8BEA4A351E55ABBA1E8AFF3E151CEE97BF100469047BD1D55C0419A8E3E2D1F5AD58C9276EB748AFED3D578F555A5FAF0F61A051757A73F872CF367FB1E6B20E4432B78CA7CA02D15E22EF" - }, - { - "metadataCompositeHash": "6D85827BCDFBE1B83C45D4AF2B97D45FD4CDB674DC5F589E92FC4E5A2C93A7FE", - "raw": "0000FFFF5A7381AF29256142BD2BC5FCC364E69A50E98607994C5100BC439669CE024B4DFE9486EF782579B271764DA59F579097B674B90F2CDD07324E6E6BA36CB92A5BE1429C83D719B074BA83E53E8472DBC9C4CFB53720E1BD628DB19E50456F744B717733C4F93D858A882BAB4CEFF3F4542D7E2272AB5F2EABD77A3AFFE359F128BB92D24EBD7C53EC58F70BED8AC6C5DB57A81C62F6D5C3C7F37AF0D3DA14CCEFFE28A75C8C50161A36EBCE4E6A923EEDB1011D13C3BE767E7FCF2E93612E353D791DE1624787DAB86FA48523B1CAE16C3BCBF1E560185E0164E855DDA86144284973AF324A84C535E50D2E7BE753983FD034214C74EBFF80C0C470AA6012F4347F4EC94EC6B12F6916D9BC3DD289099A4CD86100B7ECF7A6348AA97B6370BB879DEC0A64209DE07AC02A21459A9A4D0A2747DE6E0AEBDCC39E5C22F670E62B1AEAFEAF34B82D124E7FC36A54C6E9FB4E0F7B5E83254BF1DABDFBFEA07F522C78D67493343E1AD20A5CA5055BE3653827BF0855CB9E1380D8CDD017281538EE7A4E390E870F69677561588BCDC1656895D6A7317DE245093CF7B6327DC771349037A83905A4AF8DD4398AF898BA07F2EBE2530596837D8A36E141ECF6AE11B4A7A103932192EBB02EB603A028E1AEE06D974435462AD8365ACA3B3E735854963D11E10A57FACBC749692CE2514BD5FE2C6C313056280BED07F2634F62955F9E4600006C4B7003F840FCE9BA07A68BC41CC163A41EC76BA8D20C2A31B24098DB46D298EE04A617CBB48E1F410D35F93889EB93C4A8B8871B7C3663B182FDFAF4C48D4BED50F76407BF33DA853EA66CC48BF51313F29CE4D7F66FC837AD6BB3CB0CDA1BE499A8E7648BF6D27A0275EC98B1216559EE4ED41E8C8CD9293200C3EB73A52029238F7C544C3A5FBC3F170A7BCA816FC4A413FAFF5B17FD1192F52C76B064C030F21A2D4EC0BCD41E7E3CE3C43CC551491F0EB7489B0359254B4BEFF8866C830A5763570FACE8625DCAFCF938C58D0EDAD8BB0B9E9952EC8D77AB8E2F753A8724F4F01261F38B46F48B7EA40A6BE56095637D683AA45E2D226F24E605365B45BCA8FF3E3680E46CD6FB8BA693E4FF5050787B32B5EDFB67E01E38E8DAC20FAC0E13B6BFCCBA595F99F958BEB73C4B81680EBFAF8AB6ADC74BBD2FF39D58633B2315AE" - }, - { - "accountRestrictionsAddress": "983200C7563D305F83FA1FC2920E4CAF517B06EA64559827", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A10000DC3258221E3E3D8AB4D883AAB8D78866D43FFAD9F72B50795E38C5246AB89A46337D856A615D771975CB8F809A66F1034B97349A5E815504FF045D14994FAB3A70269E55944F1CF264CE0102528E6D0A86181449D815ADB3E6E61D1FD965E1A2101DFBB1FDCDAA427F5FE2C13F6D43CEACFB659CDE47944F4B812059AD177DB021E917CD731D6388373DE6244AB560CDB404027256DF5398418DA1656411D5C53CF0A42B5494E684CA7414E15658818344C54F2D5E29A6C45CCD408506B4800FCB827904D7B9F9A7846EF80B742F6D5AE7921D4D5FD9A32A65244A6D52650460CAC8311523F6238FC94FED327C593DC683168B9566506DC10631BC59E29A5546DA440000001167326726A252165A67069398EB0EF00FA07A6DCF7B2E5D31D14470AF8FCCCA3293D97553CC805355E0161C19CACCA5AEBE8329EB5C393C76EDF9353E1125496FFF3DB0CB8DB3A7AD037EB5C34386584464DE52732D90F3713D3BB72DA5C1BB62A0984A5BF9195893D882EE39FAB52E5C158BD3663C017A0F9AD4C5FE28D31FD332" - }, - { - "accountRestrictionsAddress": "98194B94B6270EAE3F1FFD3ACA631C0BB230A8862BE5D636", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A10000DA883FC0918F4DA3EEE2216FA6695DB9081055C6D16D6593D6A7D24A150E2376582E77A602000EAEDA1DE91FDCFC363C333E4B6260EF13EB29748E47F5BED748D83B307A2AAC9CE33FA498EC164978CB971BA67C5182F78A29E4E31FF087C36FD936EA5D6D6B017CAAA36D93F52038AA51F973A450DEC5898D7464ECEFEECD81793C861B78E133E2A2217E35949158D9CA352B3AF1D2A883A27D775D8D3765605FC0B3AA540CC2B8C7BA910F776E650768E307A7594F55C0429383FB11B5A22ADD4E9F20298025298D94DA6018C6F2438B6BF770E33A7E883E7D1A0DB54426C8894F00000680CE6A0AA2374128611DEACB2B8D9E1A2ADA4CFE2D6822599E7751BD9FF5EEC3FE0F5466855E04C6F1E0245A91A065DDEA95E0D962813208E9D5278E68C5399FDB3A7F4DC91F958F1DF95657CDBA809E97B7221F5F28A35B1624D00BECCCDB507EFF3DF07439853CA9D1F7AFDCA9B9484F44E48A1FD359E71603A00BBC42765CAA507650C907D15B14575163DEAE2041E8910AA753A3C1513BFC1F7EFC6BEC57758E" - }, - { - "accountRestrictionsAddress": "98DA4FFC541C590F899348EAF68E22534410B20EC494DFF0", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A10000DB811ABB9DBCBFF61625B34FC2861150EE28168FA3F09226C4D36B526E90DB0D3BA36961EE422B0325DBBEED03D4E3F50C11420192616D2309BF986BCA7D65EF916AC5766CDF2196AB3E8A2FB33D05F76823E6E6683445CE872925486BAD9EF6FF17DE53ACEF36AAB4C31407865370247D01E02265AE58C57DB1FF20BF277A426E556203362DB2BD104C91163F2E04C4D5BDAC40ACF3C1274D6DF29B68B182FA3EC1A1027EC0C5D7EA1352C190A49EEB5026229DB71EAFA0ED47817DC258D28B11170B1BF698E3DB92EDD6F289D2A795C23CF7E94C93F71ED1950D8D88D627E4BC96D667DB5336E5D5E8AB9986CD477402A651C31D17A730416A2268BCF7876804DF000018005548AE5D606C17AE6D8D1E7C77968EF2F1084ED11AF420C152BDC1A6FDED28EBFD5B5A094682FDE0D9082A88E9037D12BDFB57C86772C5DBD53F0A0B04A2C6DEFF3D41B8ADD3E9A4446F23635C0D5D93A0D5AF24E687A6D4DBFBCD3A3282680BA013A208A6618260AA3DAE363AFD7323F7B00F48CB0D4916EEB90748A69686EFFC" - }, - { - "accountRestrictionsAddress": "981423B4630C8208C5AE46756322842DACCDE1882080488D", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A100000D619B7CC15314B0600C4A30B10BF83853163F3C3DB68BBECA38036D6984DF2EF4353F168A57326EFAF015AF136D48BCA66CAF4CAE75765C1263F7F9896E9EB8F3FD1219B4B7296F227D9D74B9E6CF86338A560FCF6C46758B01F1F90E8D9D689C1CB09C8C45F74041948ABA9BE2B44EB94DD2F2A5AEC45E691D8D55DA3739A755BE7B809CFBEE313E9F83E478F856292D4560C62F0132476DC192A0C62A03C5900585A330F31B0EFC904C9AB0B56C89ECD09BF5D5BC7D043E109C9900F5875141B7FF3EBE9A031F10956F1012AAEC31190BDC945699D68A814F4365833B74C627F14770A38FE07B1BA2E9548D0975BA7E6E42F0030291EB4A0F27FE72184315A7C71E" - }, - { - "accountRestrictionsAddress": "98DBACD0A4C673B7239C788688D8DD5ADC422D2160FFC727", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A1000037EBBE8C99DAB48C79F99DB57AD814168EECF97C816D0019D70CE95FAFCE4EAD2C9A2C424488B0A60741DD6107BD6D5EF27C2F4E528C9626BDE804639C34C06E6D793439CBD0535768AFFCAEF5C756134B6C4DF083A2E8C672CEAF4B3C660FF74C1FD3D44D82E82145160C8C781F79B9CFB17793D9D3EF5DCBCFA6D4B7B6FA5761997E761C43BFBF6D2BD7A86BA2EE4444997D810BAC9E2F223CA0CC9CE6A18CBD833D71742142A01C4FED08877EF2A085BF4023868FEA90C4DD282BD9B4A544C48C7E39070ABD293AEEC0C1DE99BCEE6D7B0568243474B80794A0250E0C89301065F94D706B0DE8996E3FB3F30BEEACCE5036B1DF3094435EBBEC44A91B9ED3C36C764F273930CE5890858FD1D8B09868583BB881255C41F06E9F604BD20CD3D4F3238F8DE5F0D73BA40FBC9205F4412012CB4B257652F88F74C5519F67A7316D1DD45B00D3461C60A021EF0CD1044EC9F4E1F70A4149587738B44066AFB56719FBFF3EA72E3BAE48A639D155A899A23012CBFBB6CFF3ACD5BFE119ADF2873AD0B0EB1E6B4DA50264B57E2956631143C337173F6D290190EA8882C798ED067209AABF" - }, - { - "accountRestrictionsAddress": "989371E351AA43363FBB5100FD325509D9E40C5CBB7BFE79", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A10000D70AA1583EE4E34E74F1B109CC176307CA3898CED4EC28C2383827495DE1438567B3FF4F847B5327CA1844B5236E44C4B5FFAA5AEB2309CC8FA955CAF382C219B12CDB6F0497275F00A6FE6F67C9D8F243FBF2B0E2C7C8D36B0DF81EC38B137A882D3B29E93EF32337DDA27D6A97597BA582671E440E91DC000A427650C5D9929FDF788FF5FB361688526D07BD86032F5CA2602D46AD96F6704F355F28BE76F2BDC016E6BAE3D0A4BC3482FF499AC5EFCD00B17005644790D1D1BF896D32623E462ED0BE9B21BB4912A285F196075C43D189D9BC888DA0C588881CC24581FB5475C0C1A7D8C2BDA0B2AD9E7D11568A92BAFA6C6D436D24FBF1EF2A2B15EADB291CF0FF3E216B7501C4B735F21D4CAF28E5EADF976E1CA368B0C53AA032B0D5108480EA8572174829CE76CA7DAAC844AF3C0FA3E4F45730A06E11B2A56DC783AE016060" - }, - { - "accountRestrictionsAddress": "98CC1ED433921347D37E17BAD6F9EF5CABF44389C49B81C5", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A1000037EBBE8C99DAB48C79F99DB57AD814168EECF97C816D0019D70CE95FAFCE4EAD2C9A2C424488B0A60741DD6107BD6D5EF27C2F4E528C9626BDE804639C34C06E6D793439CBD0535768AFFCAEF5C756134B6C4DF083A2E8C672CEAF4B3C660FF74C1FD3D44D82E82145160C8C781F79B9CFB17793D9D3EF5DCBCFA6D4B7B6FA5761997E761C43BFBF6D2BD7A86BA2EE4444997D810BAC9E2F223CA0CC9CE6A18CBD833D71742142A01C4FED08877EF2A085BF4023868FEA90C4DD282BD9B4A544C48C7E39070ABD293AEEC0C1DE99BCEE6D7B0568243474B80794A0250E0C89301065F94D706B0DE8996E3FB3F30BEEACCE5036B1DF3094435EBBEC44A91B9ED3C36C764F273930CE5890858FD1D8B09868583BB881255C41F06E9F604BD20CD3D4F3238F8DE5F0D73BA40FBC9205F4412012CB4B257652F88F74C5519F67A7316D1DD45B00D3461C60A021EF0CD1044EC9F4E1F70A4149587738B44066AFB56719FBFF3EC0FA0A71E26AC8C03868FB8834EEA8873371AE8B4BEA90A4844266F5D665377C3245677969274C67DE5B1CCF62652AE8DA3EBC64AEB479B5401F26D1277C42" - }, - { - "accountRestrictionsAddress": "9866D9AC77255A99799A954FF4C72695424D026B94E3D669", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A100004D8ED2419CD533DD0A3C2D95EFF139EEB114D4158AD786A173BA3B7E72AF95E8EAD4106EB3105721EB21188CD0EF88DE9B87453FE9E712D1A9CC2919D6F09801E2006ED320F7B6C1E1180CBB6B5DD659F4AC6AF5D60D9244BD8DF2042FF54218E1B832D2734FBCE31FBDC02416DBD3263F82CC315AF60E7C46F83DD0490489AFA325F461E689C6BD647F5CB31C52741A42404F8787E6D0A5336BF4F66B441FE79333C887290AB372CFEBD0B9D937975D6B2667EADC7598A9D81DB3CA227DD13634A17D59BD64EE548DB4E5AE9C250E2A8FCE24C4EBFADF4D7F450E854BB63231041B4A0C8938DEC049EC504167F22AB3697EDA9FD33AA71D987764F02D138394B15300000018592666284C43B33421888AE6275ECAD65CB23C8477AB9FB222BEB71781730C019D63ED27ED71B00F3F3C89FF42D3A7D8BDB38301A98918DAD89D31B4BAF53910FF3D64C49A9E7F86C29F1E6C968DFE6522BE27A971DBED07BCCBC2E68EAF3742B06F59B1AC8DD414530C78621E15B0E8AA9F6039A4AFE7716D7392031C1A165449" - }, - { - "accountRestrictionsAddress": "9873789DE77EDEC34994611057CE33960D17A601973D5FEA", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A100001D975BD03BDA67B051C67E51D2CABE9244077F805B77ED864CBEF3AE7A77B78D01D2479433A74740F21AA21C5433084A2EEBDA3732B2DFF5818212E071EBA29554F5C15E4C09D6A7B69548D43C1E2733DF206FB5EB50D736821DB55F655F334FAD6C674C809F7D02CDFA6E62C07EB04509905306DB72FED19EE66BFFEB486994C61CCF18463B145BAC14F6D5A4FB14F027C5FC0F0DE762DB334079D04EA5BE8BF0FC39765C42712AEE812AF0B4C6BED522A023CE251C1485DD5776F4CD3C8EF4BD888E4C88E81BBC1F4792E3B0320134BC6CFC4CE16A0A7DFAFF26867B3985B243F20382CF7CB4C4A84B84B98E1688D11781E4368AB972EC8E546E41A955303A2BDBBB96B0DEE72DF45181C87FEB0477A7066402D5F924CAE21C3C69041FF3D80281FF3ECE825E9777A4398F4665AE5DAB5F483753B1CF131B364BDE440D6CB1667ED26EFEADD6C785D85942B4EA0D2992C1DA009D5EF43BB3E1158AB63A1B10B5F4B9" - }, - { - "accountRestrictionsAddress": "9859A8618EB8995F4F3F6EA3BAC03DF2C9B1E77CC85170A7", - "raw": "0000FFFF782613DA5EA6428245401C0DA88B1E93925F666A88F4E9AE859D6DED1023A0BDF1FE31D8A9E109EB1A170A7BBBED1E8E63FC57920B28485C5579C45E226EF6B0724BBEB79E0E553E1ACD61327D5F766EC740ACD86CCB8A9FAF510F9788E271D2BC32C4ACD56AB005D0630AA8F2034354FDC789AE81EAFF604E7D5498D1338746E29F55DBFFC5DC619958DFEE3334A4D5B918803C882E243A638CEAB1344223EF6601EAA80958F665715D2FC4FDAF72FF62887B3B59F5EC90679337A20033917827AA79B52339A20F886E09B0052606ABDA6B2818E6801BC219413817881D220B8CC78BED8D2EB7CB37340632BA605D1DC2D17973A8877694AD9FD065B2B70F5A09C25A78FBC48D890FF691155C27563B9165914E7F2E92FEA83BAEBC7386E15AE80A009BA61793B53E9573883440244A9E8791A2B541A0481BB86A15010A7CE8EA29137B97B2452C4F6AF1E7AEF1DBF4367096624A478A335C06486C7E95B05087C9430AA717A260EEBC676DA1A1DB3FF236130BC7FF9D8D254C48603D7482A37D94AA390AEFF1EF9357045804B40E620BAC494AB5FB71C80262DD64E238777D802FCF05D88D93269515A22BB5F52450EBFB97A1FD5D1143B41A07845CA2559564E1EFAAAB4CB990F4E0EFE3CD7E860DC7DB747C459797C357C2DA1D54EA2A5D93BDAF0723514D4510E2F18CBEBE66F8631B542CD8A2952301FDA63402C930A100001D975BD03BDA67B051C67E51D2CABE9244077F805B77ED864CBEF3AE7A77B78D01D2479433A74740F21AA21C5433084A2EEBDA3732B2DFF5818212E071EBA29554F5C15E4C09D6A7B69548D43C1E2733DF206FB5EB50D736821DB55F655F334FAD6C674C809F7D02CDFA6E62C07EB04509905306DB72FED19EE66BFFEB486994C61CCF18463B145BAC14F6D5A4FB14F027C5FC0F0DE762DB334079D04EA5BE8BF0FC39765C42712AEE812AF0B4C6BED522A023CE251C1485DD5776F4CD3C8EF4BD888E4C88E81BBC1F4792E3B0320134BC6CFC4CE16A0A7DFAFF26867B3985B243F20382CF7CB4C4A84B84B98E1688D11781E4368AB972EC8E546E41A955303A2BDBBB96B0DEE72DF45181C87FEB0477A7066402D5F924CAE21C3C69041FF3D80281FF3E298A3599568F6AF784A7E20C92672B6D0FD4A753DFF78D94647C7D7AFB864E85F020B65447E6B1E871871076C76C8715F7601D46D1050F734D8E679BBB8D2E" - }, - { - "mosaicRestrictionsCompositeHash": "992BE452CC273E72CEE4422855102BDD50AA5B869C248114800A06171CCDD594", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600000241171AE04A418DAA268569492180CD6314FCF82B46016D2CAA27F71CBC223958829C392AAA7ED587615D6CD90F27797889AF6A0417CDD84CEC9D6ABF2B464ADFA668ACACA123DF1859D11DCFB4684333D6AE0602A2380508877C53D99288FAE648FF3EBFB45C39062ECCC24280BFCD1B66440B3443D998B59152C4C753D6F4ED7DEFB332BFAF23AAC152824B2DBE14CA3E6902E0876B4E2BB1FF7A19C8CA841DB19E" - }, - { - "mosaicRestrictionsCompositeHash": "4ED2202019AFB6D6E753B4E1A1DAF15DF19B02812B0CC1565E00254D3E5270B0", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600009C257B79D537B5699CB87CD1B879C153E630EA066E9B2AC2BF0D54D4BC1D2C3D64AAA03E69330589671F2A41FBCBD70E7C74DACE03E706FCF0547EDFDA5A20352E77A025268BE61A640098B6D5587659BBB66629FD279C5BC5EFCBBE73E7776A812C003B81633288BB599941A9BA66DC196D14369C14C382FBAD042E02399A4FDE0868502331D0BD7DE371AFC854B09998078F7D90BCFDD9406053DB525DDA0FA4E93138547302F1BFD9268461AD9D9EC7F29DB1449ABBCC8C13B38397B66F778D5FD7BAED05167C42A22DE210EF2B12B38565624DC3EFC82550C5EAA50254F584D8FF3EB3C0C0114AB6022083F91A07D086968E54797690379FCA8892D96E63477A62AAA77943EA1C19B4475DB2F08511530E7C2728165EE7E4877E8FF99F91FB188A" - }, - { - "mosaicRestrictionsCompositeHash": "2507B51607159E8C6BE78B9B4738CCAD4F422FC2160A74D1C15F449DA3D6621F", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F6000023E06C08A60F3DF383F349B661CE9BCE6B5D9F7ECBBFD287A39F0744248F5C61E606A6AB84C8E8A588773D7FAF788C7148EE2C544A70F456AF76FE5D2918C372A4EAB335D0DE48A7693518D85F2036003AC9B0D8C4B521E1A9CE98EC6505E96741A54FA488BA48F159A7E2AA6DE2FA6E23048C2B002E41420C9A39EC54A2834861AA1B34D6C632852ED98F665CA8CB05E96F19AC9CBC930B81C78D7AB47EDE5668F68D6591FEE0D06AC5C42A609104A16117191F870C5DDD7013558C21C19CDED519FF3ECE803A277C446BA63F0DCD9B8614B6F318479DA3E0469AE272A10EF9423A5D27A1D7A1FF052A10F0A617FA8101EF52576287201F57186E9F375E33C83571D3" - }, - { - "mosaicRestrictionsCompositeHash": "856461924215060B82BA702F88C00041FE2BDEF4FD35A9DE1A3ED3D86811A499", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600009C257B79D537B5699CB87CD1B879C153E630EA066E9B2AC2BF0D54D4BC1D2C3D64AAA03E69330589671F2A41FBCBD70E7C74DACE03E706FCF0547EDFDA5A20352E77A025268BE61A640098B6D5587659BBB66629FD279C5BC5EFCBBE73E7776A812C003B81633288BB599941A9BA66DC196D14369C14C382FBAD042E02399A4FDE0868502331D0BD7DE371AFC854B09998078F7D90BCFDD9406053DB525DDA0FA4E93138547302F1BFD9268461AD9D9EC7F29DB1449ABBCC8C13B38397B66F778D5FD7BAED05167C42A22DE210EF2B12B38565624DC3EFC82550C5EAA50254F584D8FF3E1EB0F3FC965F0A84D6E8E704689631ED8467088FAA93F148C2B23FAF617314B426FA4099DD3C4AD60A3271F4B316A8FA888DACB594B9DD6FE403E07B22CC26" - }, - { - "mosaicRestrictionsCompositeHash": "37755CE16BE22DCB083A7F29415205D16EA7CF1F6247C7CB14D6600A03FEE5ED", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600006E8118B28E207E8FAF362AC0CAE89028E002B1FFFF50C4953E6388A4DB468616420430F95228765F9C621B560339E0B0FAB43B5FEFF70D741F88828C58F83F31E12715D822D910A1EFA3B16560C50F0457363D70337D8FE850CC43FF5A12E7489C73D19AE7B4291DB6EBED76E7ED7EC639FB8BB99CF84BD6A9DE3C5BB53E6537E0309FCE83EF7EBF9785FAA05482D9445976DA6FDDCBD129C4244EDA5B563AADDA0B503EB4E8761081FC8F9EB9F24A828DD9F0B33EB21A988A8557E51B951B1F0AD9CCFEB3F73B0915E764906FD8109EAE17118350EED5F059DA67D98E0072E44994FF3E9DAE2A27E29AD835BB28C20E07CAC29F4F3883573116D990F830E57A63D10C3E6C27BC8A73A5A28D6470CCA0266097A7885C83BDB77360906B99233A50DD02" - }, - { - "mosaicRestrictionsCompositeHash": "FE68A3875D2EBF00F5C7C19C67225C55558DE22DF10957D60AD867C74310E7FA", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600000032BB0052DCB740A701652D86DDD93F5B407CFEB036993EC4094A1D577E7E924077404134FF77C23F03BA68301F0B9184601A359C85D56D3D3D69C2DF44429CF8BAA1F8B9D9E7BB088C4C715DACD9FB942C08A7A116DDE9F4210D069828813B1F2200002001A2516BA92860D96DFD3A78EBAEA076516A3A3DB6E88343A2AC21EEC9E2D8E919054C7EEAE98648AA620A2C4D53D91CA158521200D2AA59F9BB71B78FB00F20A70000402022FBFD63C2E446615D60D2FE02CA694ED0E4056C46AE00A63C830524AB6E346B9751DA2B6B2EB2666E5AEFDD9EBC48BC9D48CAE00AC1AD4D1E146AE12E4A951DFF3C6EEEC62AA2D37E24F1DBD01DCB649D2D23258798F2D04A433C941CBF5DA362A6D8533D9DA67257ACB6229EBFA1C24635E163C16A5DE3F63EFD8AB6D7B29A" - }, - { - "mosaicRestrictionsCompositeHash": "EA766AAEA72CF27E0EF898C89D286AB9D1F2A745617DE3568DBE3730648E7DFE", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F6000030049189FEEABDBB14C99701E111990892E67AC15FB73596BC0D4C7A4EE66DA1928EA4A20F49E9F5AD0ED28FAB7F007237A01C206D6076FA591B4481B1DBD40D05A1DB1F60AE15B209624855278E7EE59EF4A96E4A5B965A7E757D128C562A09B3BCFF3EB4F7B009BBAEB0C2AB9A02505F2AA908B39E2A638593B5E6072FB432F79AD722723E61267056C079F6FEAE60329DB226D7EDEA6CC660D84DD8826B33D929BC" - }, - { - "mosaicRestrictionsCompositeHash": "6CB28C636A5DB7496A022541391BE3C4D675B9D1A3A2A61BBED7C43D33054AD9", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600009C257B79D537B5699CB87CD1B879C153E630EA066E9B2AC2BF0D54D4BC1D2C3D64AAA03E69330589671F2A41FBCBD70E7C74DACE03E706FCF0547EDFDA5A20352E77A025268BE61A640098B6D5587659BBB66629FD279C5BC5EFCBBE73E7776A812C003B81633288BB599941A9BA66DC196D14369C14C382FBAD042E02399A4FDE0868502331D0BD7DE371AFC854B09998078F7D90BCFDD9406053DB525DDA0FA4E93138547302F1BFD9268461AD9D9EC7F29DB1449ABBCC8C13B38397B66F778D5FD7BAED05167C42A22DE210EF2B12B38565624DC3EFC82550C5EAA50254F584D8FF3ED55DA763A7F8C0DB37A94554DDB8CBEC99C8B43E2325460BCEF3E2F04C81DBC3D35C58A0696109AC1B4879C88594647FFE2B373E942B30EF3CFEF476E82ECC" - }, - { - "mosaicRestrictionsCompositeHash": "C4C309B72AA9AFEC6EBFA2EB1E61EADB0DE6ABF82CFAE99E28EB5D48D1A631B4", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600000A4284B2A1798064E22D26DD7A8E41E44806CD8A86A5658F094D1E125AEB023FB7480D6DA148FFAD646406F796E796ED44B3F8C7A8B63FAE875BD0FD68D56F49D6EE70682FFD392F7B677D16787124C645877D33DBAEBFCF3A1E0FB44F2F9A3EE2F4297BD6FA8A81523DAFF4EA20F7BAB2990A1C1B05217C6844AE74BD31A08F84A2FF3E64B77794D6BCF5E26966B57CB103A6FA9DAF852773489D85CA370625B6B9732945E939447E35ECA03A298AB39E27D9079E69CF936D3F3F273F70FC8C93555A" - }, - { - "mosaicRestrictionsCompositeHash": "E339FFE52F4E6689A4357D10505601881E886A40F5EC5C991621295988F04426", - "raw": "0000FFFF66F8F5657D691DEC4585B2864DF3F24974F13F5EE1EB28E8567F3B44783229E542409BC7C9B622332A4C398EB0C1BC6AA55D897232C5B178DA91BDACBDEF0F03801C8FC8A04BF1602989F893FA1FEB8CC4464101862DC181DC76FF93FEC38227863A99246528E8FEC0747BEC97D376F4FD4540541E6AE436E471BD500BF06E896B4FB948083DF78F9A1D41C53D2BF89FECA57576317537447021F1C9CC7EEB13DD2A5BB4C5BB46216E3F3E067A96DA4A3C7799BDC51B84CF4BB2298A4455EB10658346DB183B32CCCD04869301692442E4DEF14405E761389251EE5EE520A4BB0210C1AACE4F6E98567CF4B7710955CF4DEA1634CE2BB13066F1BF201B146D6E452C6541C81F3E891C18452D5E826ABDE1A038F6A45B5139CB171066559536D4CBB5C90B86BDA0756C8B57DA03FF8D267BE5A7A25187EE54763C3F0AC3F032812735B5D8D7F77F561989EDF04E5E31F1997AB8DBA6DA738659043006F436AC342B8D6918FD172DF312DFC7E9669616B44120EF50928A63709303FF16B10ADDC46692E47C798CF4C297124D034A8202D5ECEABFAAF65649C6966F1C23E5A9F2DB428141D72D652D6518AE6C18A1D991DA555FB370CB94BDB73C4795C3E66EE6EB0CD1D7A6E029673CFB5D64D286EC5A6CC46EEECA40523FBAE8E649C8E7B3FF5C91C73EAC616F5F464899D65CB34FCCAE9B9D39F064D37DA71110F7D4D65C00F600008404452EB16D003DE3EEECCC13C11E9A8AB22C0A34F2AF281D7FE0ED03FF0AA999DC4D44F71A81B983DC969F69C38265400743DD13DC7B14F7FD958D6B8B4EDA08CA4C996886D7FA361A46CCC04F1573EFAE357FB452132490E61A360B3BA6F2AF89FF3EB394D6692B40DC47365699B7041A2229D619CBE98DBA55F119839DFC83FB8B1757CF3319E862DC84AC3AFFA44F687477ECF81E3A8107B5BD349F83187DAD65" - } -] diff --git a/rest/test/plugins/aggregate/aggregateRoutes_spec.js b/rest/test/plugins/aggregate/aggregateRoutes_spec.js deleted file mode 100644 index d5a7fc204..000000000 --- a/rest/test/plugins/aggregate/aggregateRoutes_spec.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const aggregateRoutes = require('../../../src/plugins/aggregate/aggregateRoutes'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); - -const { PacketType } = catapult.packet; - -describe('aggregate routes', () => { - describe('PUT transaction partial', () => { - const packetTypeBuffer = Buffer.alloc(4); - packetTypeBuffer.writeUInt32LE(PacketType.pushPartialTransactions, 0); - - test.route.packet.addPutPacketRouteTests(aggregateRoutes.register, { - routeName: '/transactions/partial', - packetType: PacketType.pushPartialTransactions, - inputs: { - valid: { - params: { payload: '123456' }, - parsed: Buffer.of( - 0x0B, 0x00, 0x00, 0x00, // size (header) - ...packetTypeBuffer, // type (header) - 0x12, 0x34, 0x56 // payload - ) - }, - invalid: { - params: { payload: '1234S6' }, - error: { key: 'payload' } - } - } - }); - }); - - describe('PUT transaction cosignature', () => { - const packetTypeBuffer = Buffer.alloc(4); - packetTypeBuffer.writeUInt32LE(PacketType.pushDetachedCosignatures, 0); - - test.route.packet.addPutPacketRouteTests(aggregateRoutes.register, { - routeName: '/transactions/cosignature', - packetType: PacketType.pushDetachedCosignatures, - inputs: { - valid: { - params: { - version: '9007199254740993', - signerPublicKey: '123456', - signature: '998811', - parentHash: 'ABEF' - }, - parsed: Buffer.of( - // header - 0x18, 0x00, 0x00, 0x00, // size - ...packetTypeBuffer, // type - - // payload - 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // version - 0x12, 0x34, 0x56, // signerPublicKey - 0x99, 0x88, 0x11, // signature - 0xAB, 0xEF // parentHash - ) - }, - invalid: { - params: { - version: '9007199254740993', - signerPublicKey: '123456', - signature: '998S11', - parentHash: 'ABEF' - }, - error: { key: 'signature' } - } - } - }); - }); -}); diff --git a/rest/test/plugins/aggregate/aggregate_spec.js b/rest/test/plugins/aggregate/aggregate_spec.js deleted file mode 100644 index 7435b1638..000000000 --- a/rest/test/plugins/aggregate/aggregate_spec.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { ServerMessageHandler } = require('../../../src/connection/serverMessageHandlers'); -const aggregate = require('../../../src/plugins/aggregate/aggregate'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); -const { expect } = require('chai'); - -describe('aggregate plugin', () => { - pluginTest.assertThat.pluginDoesNotCreateDb(aggregate); - - describe('register transaction states', () => { - it('registers partial state', () => { - // Arrange: - const states = []; - - // Act: - aggregate.registerTransactionStates(states); - - // Assert: - expect(states.length).to.equal(1); - expect(states[0]).to.deep.equal({ friendlyName: 'partial', dbPostfix: 'Partial', routePostfix: '/partial' }); - }); - }); - - describe('register message channels', () => { - const registerAndExtractChannelDescriptor = channelDescriptorName => { - // Arrange: - const channelDescriptors = []; - const builder = { add: (name, markerChar, handler) => { channelDescriptors.push({ name, markerChar, handler }); } }; - - // Act: - aggregate.registerMessageChannels(builder); - const channelDescriptor = channelDescriptors.find(descriptor => channelDescriptorName === descriptor.name); - - // Sanity: - expect(channelDescriptors.length).to.equal(3); - expect(channelDescriptor).to.not.equal(undefined); - return channelDescriptor; - }; - - it('registers partialAdded', () => { - // Act: - const descriptor = registerAndExtractChannelDescriptor('partialAdded'); - - // Assert: - expect(descriptor).to.deep.equal({ name: 'partialAdded', markerChar: 'p', handler: ServerMessageHandler.transaction }); - }); - - it('registers partialRemoved', () => { - // Act: - const descriptor = registerAndExtractChannelDescriptor('partialRemoved'); - - // Assert: - expect(descriptor).to.deep.equal({ name: 'partialRemoved', markerChar: 'q', handler: ServerMessageHandler.transactionHash }); - }); - - it('registers cosignature', () => { - // Act: - const descriptor = registerAndExtractChannelDescriptor('cosignature'); - - // Assert: - expect(descriptor.name).to.equal('cosignature'); - expect(descriptor.markerChar).to.equal('c'); - }); - - it('registers cosignature with handler that forwards to emit callback', () => { - // Arrange: - const emitted = []; - const { handler } = registerAndExtractChannelDescriptor('cosignature'); - - // Act: - const buffer = Buffer.concat([ - Buffer.of(0x34, 0x54, 0x55, 0xFF, 0xFA, 0x0E, 0xCC, 0xB7), - Buffer.alloc(test.constants.sizes.signerPublicKey, 33), - Buffer.alloc(test.constants.sizes.signature, 44), - Buffer.alloc(test.constants.sizes.hash256, 55) - ]); - handler({}, eventData => emitted.push(eventData))(22, buffer, 99); - - // Assert: - // - 22 is a "topic" so it's not forwarded - // - trailing param 99 should be ignored - expect(emitted.length).to.equal(1); - expect(emitted[0]).to.deep.equal({ - type: 'aggregate.cosignature', - payload: { - version: [4283782196, 3083603706], - signerPublicKey: Buffer.alloc(test.constants.sizes.signerPublicKey, 33), - signature: Buffer.alloc(test.constants.sizes.signature, 44), - parentHash: Buffer.alloc(test.constants.sizes.hash256, 55) - } - }); - }); - }); - - describe('register routes', () => { - it('registers aggregate PUT routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('put', routes); - - // Act: - aggregate.registerRoutes(server, {}, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/transactions/cosignature', - '/transactions/partial' - ]); - }); - }); -}); diff --git a/rest/test/plugins/empty_spec.js b/rest/test/plugins/empty_spec.js deleted file mode 100644 index 8f8048729..000000000 --- a/rest/test/plugins/empty_spec.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const pluginTest = require('./utils/pluginTestUtils'); -const empty = require('../../src/plugins/empty'); -const { test } = require('../routes/utils/routeTestUtils'); - -describe('transfer plugin', () => { - pluginTest.assertThat.pluginDoesNotCreateDb(empty); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(empty); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(empty); - - describe('register routes', () => { - it('does not register routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - empty.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, []); - }); - }); -}); diff --git a/rest/test/plugins/lockHash/LockHashDb_spec.js b/rest/test/plugins/lockHash/LockHashDb_spec.js deleted file mode 100644 index c19f09f71..000000000 --- a/rest/test/plugins/lockHash/LockHashDb_spec.js +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const CatapultDb = require('../../../src/db/CatapultDb'); -const HashLocksDb = require('../../../src/plugins/lockHash/LockHashDb'); -const test = require('../../db/utils/dbTestUtils'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -describe('hash locks db', () => { - const ownerAddressTest1 = test.random.address(); - const ownerAddressTest2 = test.random.address(); - const ownerAddressTest3 = test.random.address(); - const hashTest01 = test.random.hash(); - const hashTest02 = test.random.hash(); - - const { createObjectId } = test.db; - - const runHashLocksDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => - test.db.runDbTest(dbEntities, 'hashLocks', db => new HashLocksDb(db), issueDbCommand, assertDbCommandResult); - - const createHashLock = (objectId, ownerAddress, hash) => ({ - _id: createObjectId(objectId), - lock: { - ownerAddress: ownerAddress ? Buffer.from(ownerAddress) : undefined, - mosaicId: '', - amount: '', - endHeight: '', - status: '', - hash: hash || undefined - } - }); - - describe('hashLocks', () => { - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const runTestAndVerifyIds = (dbHashLocks, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runHashLocksDbTest( - dbHashLocks, - dbQuery, - page => { - const returnedIds = page.data.map(t => t.id); - expect(page.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbHashLocks = [createHashLock(10, ownerAddressTest1)]; - - // Act + Assert: - return runHashLocksDbTest( - dbHashLocks, - db => db.hashLocks([ownerAddressTest1], paginationOptions), - page => { - const expected_keys = ['id', 'lock']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns empty array for unknown address', () => { - // Arrange: - const dbHashLocks = [ - createHashLock(10, ownerAddressTest1), - createHashLock(20, ownerAddressTest1) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbHashLocks, db => db.hashLocks([ownerAddressTest2], paginationOptions), []); - }); - - it('returns filtered hash locks by owner address', () => { - // Arrange: - const dbHashLocks = [ - createHashLock(10, ownerAddressTest1), - createHashLock(20, ownerAddressTest2) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbHashLocks, db => db.hashLocks([ownerAddressTest2], paginationOptions), [20]); - }); - - it('returns filtered hash locks by owner address, multiple addresses', () => { - // Arrange: - const dbHashLocks = [ - createHashLock(10, ownerAddressTest1), - createHashLock(20, ownerAddressTest2), - createHashLock(30, ownerAddressTest3) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbHashLocks, - db => db.hashLocks([ownerAddressTest1, ownerAddressTest2], paginationOptions), - [10, 20] - ); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbHashLocks = () => [ - createHashLock(10, ownerAddressTest1), - createHashLock(20, ownerAddressTest1), - createHashLock(30, ownerAddressTest1) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runHashLocksDbTest( - dbHashLocks(), - db => db.hashLocks([ownerAddressTest1], options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runHashLocksDbTest( - dbHashLocks(), - db => db.hashLocks([ownerAddressTest1], options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runHashLocksDbTest( - dbHashLocks(), - db => db.hashLocks([ownerAddressTest1], options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbHashLocks = () => [ - createHashLock(10, ownerAddressTest1), - createHashLock(20, ownerAddressTest1), - createHashLock(30, ownerAddressTest1) - ]; - - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbHashLocks(), db => db.hashLocks([ownerAddressTest1], options), [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbHashLocks(), db => db.hashLocks([ownerAddressTest1], options), [10]); - }); - }); - }); - - describe('hashLockByHash', () => { - it('returns undefined for unknown hash', () => { - // Arrange: - const dbHashLocks = [createHashLock(10, ownerAddressTest1, hashTest01)]; - - // Assert: - return runHashLocksDbTest( - dbHashLocks, - db => db.hashLockByHash([hashTest02]), - hashLock => { expect(hashLock.length).to.equal(0); } - ); - }); - - it('returns matching hash lock', () => { - // Arrange: - const dbHashLocks = [ - createHashLock(10, ownerAddressTest1, hashTest01), - createHashLock(20, ownerAddressTest1, hashTest02), - createHashLock(30, ownerAddressTest1, hashTest01) - ]; - - // Assert: - return runHashLocksDbTest( - dbHashLocks, - db => db.hashLockByHash([hashTest02]), - hashLocks => { - expect(hashLocks.length).to.equal(1); - const hashLock = hashLocks[0]; - expect(hashLock.id).to.deep.equal(createObjectId(20)); - expect(hashLock.lock.ownerAddress.buffer).to.deep.equal(ownerAddressTest1); - expect(hashLock.lock.hash.buffer).to.deep.equal(hashTest02); - } - ); - }); - }); -}); diff --git a/rest/test/plugins/lockHash/lockHashRoutes_spec.js b/rest/test/plugins/lockHash/lockHashRoutes_spec.js deleted file mode 100644 index 08f32fbe1..000000000 --- a/rest/test/plugins/lockHash/lockHashRoutes_spec.js +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const lockHashRoutes = require('../../../src/plugins/lockHash/lockHashRoutes'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; - -describe('lock hash routes', () => { - describe('hash locks', () => { - const testAddress = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - const testAddressNoLocks = 'A34B57B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ45AB'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: 'random1', - lock: { - ownerAddress: '', - mosaicId: '', - amount: '', - endHeight: '', - status: '', - hash: '' - } - }, - { - id: 'random2', - lock: { - ownerAddress: '', - mosaicId: '', - amount: '', - endHeight: '', - status: '', - hash: '' - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbHashLocksFake = sinon.fake(addresses => - (Buffer.from(addresses[0]).equals(Buffer.from(address.stringToAddress(testAddress))) - ? Promise.resolve(pageSample) - : Promise.resolve(emptyPageSample))); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { hashLocks: dbHashLocksFake }; - lockHashRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbHashLocksFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/account/:address/lock/hash').get(); - - describe('by address', () => { - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - expect(dbHashLocksFake.calledOnce).to.equal(true); - expect(dbHashLocksFake.firstCall.args[1]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: { address: testAddress } }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('forwards address', () => { - // Arrange: - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbHashLocksFake.calledOnce).to.equal(true); - expect(dbHashLocksFake.firstCall.args[0]).to.deep.equal([address.stringToAddress(testAddress)]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns empty if no hash locks found', () => { - // Arrange: - const req = { params: { address: testAddressNoLocks } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbHashLocksFake.calledOnce).to.equal(true); - expect(dbHashLocksFake.firstCall.args[0]).to.deep.equal([address.stringToAddress(testAddressNoLocks)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'hashLockInfo', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbHashLocksFake.calledOnce).to.equal(true); - expect(dbHashLocksFake.firstCall.args[0]).to.deep.equal([address.stringToAddress(testAddress)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'hashLockInfo', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('throws error if address is invalid', () => { - // Arrange: - const req = { params: { address: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('address has an invalid format'); - }); - }); - }); - - describe('by hash', () => { - const hashes = ['C54AFD996DF1F52748EBC5B40F8D0DC242A6A661299149F5F96A0C21ECCB653F']; - const uint64Hashes = hashes.map(routeUtils.namedParserMap.hash256); - test.route.document.addGetPostDocumentRouteTests(lockHashRoutes.register, { - routes: { singular: '/lock/hash/:hash', plural: '/lock/hash' }, - - inputs: { - valid: { object: { hash: hashes[0] }, parsed: [uint64Hashes[0]], printable: hashes[0] }, - validMultiple: { object: { hashes }, parsed: uint64Hashes }, - invalid: { object: { hash: '12345' }, error: 'hash has an invalid format' }, - invalidMultiple: { - object: { hashes: [hashes[0], '12345'] }, - error: 'element in array hashes has an invalid format' - } - }, - - dbApiName: 'hashLockByHash', - type: 'hashLockInfo' - }); - }); - }); -}); diff --git a/rest/test/plugins/lockHash/lockHash_spec.js b/rest/test/plugins/lockHash/lockHash_spec.js deleted file mode 100644 index d88214fc5..000000000 --- a/rest/test/plugins/lockHash/lockHash_spec.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const LockHashDb = require('../../../src/plugins/lockHash/LockHashDb'); -const lockHash = require('../../../src/plugins/lockHash/lockHash'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('lock hash plugin', () => { - pluginTest.assertThat.pluginCreatesDb(lockHash, LockHashDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(lockHash); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(lockHash); - - describe('register routes', () => { - it('registers lock hash GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - lockHash.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/account/:address/lock/hash', - '/lock/hash', - '/lock/hash/:hash', - '/lock/hash/:hash/merkle' - ]); - }); - - it('registers POST routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - lockHash.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/lock/hash' - ]); - }); - }); -}); diff --git a/rest/test/plugins/lockSecret/LockSecretDb_spec.js b/rest/test/plugins/lockSecret/LockSecretDb_spec.js deleted file mode 100644 index 3c6b429b5..000000000 --- a/rest/test/plugins/lockSecret/LockSecretDb_spec.js +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const CatapultDb = require('../../../src/db/CatapultDb'); -const SecretLocksDb = require('../../../src/plugins/lockSecret/LockSecretDb'); -const test = require('../../db/utils/dbTestUtils'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -describe('secret locks db', () => { - const ownerAddressTest1 = test.random.address(); - const ownerAddressTest2 = test.random.address(); - const ownerAddressTest3 = test.random.address(); - const secretTest01 = test.random.hash(); - const secretTest02 = test.random.hash(); - - const { createObjectId } = test.db; - - const runSecretLocksDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => - test.db.runDbTest(dbEntities, 'secretLocks', db => new SecretLocksDb(db), issueDbCommand, assertDbCommandResult); - - const createSecretLock = (objectId, ownerAddress, secret) => ({ - _id: createObjectId(objectId), - lock: { - ownerAddress: ownerAddress ? Buffer.from(ownerAddress) : undefined, - mosaicId: '', - amount: '', - endHeight: '', - status: '', - hashAlgorithm: '', - secret: secret || undefined, - recipientAddress: '', - compositeHash: '' - } - }); - - describe('secretLocks', () => { - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const runTestAndVerifyIds = (dbSecretLocks, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runSecretLocksDbTest( - dbSecretLocks, - dbQuery, - page => { - const returnedIds = page.data.map(t => t.id); - expect(page.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbSecretLocks = [createSecretLock(10, ownerAddressTest1)]; - - // Act + Assert: - return runSecretLocksDbTest( - dbSecretLocks, - db => db.secretLocks([ownerAddressTest1], undefined, paginationOptions), - page => { - const expected_keys = ['id', 'lock']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns empty array for unknown address', () => { - // Arrange: - const dbSecretLocks = [ - createSecretLock(10, ownerAddressTest1), - createSecretLock(20, ownerAddressTest1) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbSecretLocks, db => db.secretLocks([ownerAddressTest2], undefined, paginationOptions), []); - }); - - it('returns filtered lock secret by owner address', () => { - // Arrange: - const dbSecretLocks = [ - createSecretLock(10, ownerAddressTest1), - createSecretLock(20, ownerAddressTest2) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbSecretLocks, db => db.secretLocks([ownerAddressTest2], undefined, paginationOptions), [20]); - }); - - it('returns filtered lock secret by owner address, multiple addresses', () => { - // Arrange: - const dbSecretLocks = [ - createSecretLock(10, ownerAddressTest1), - createSecretLock(20, ownerAddressTest2), - createSecretLock(30, ownerAddressTest3) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbSecretLocks, - db => db.secretLocks([ownerAddressTest1, ownerAddressTest2], undefined, paginationOptions), - [10, 20] - ); - }); - - it('returns filtered lock secret by secret', () => { - // Arrange: - const dbSecretLocks = [ - createSecretLock(10, ownerAddressTest1, secretTest01), - createSecretLock(20, ownerAddressTest2, secretTest02) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbSecretLocks, db => db.secretLocks([ownerAddressTest2], secretTest02, paginationOptions), [20]); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbSecretLocks = () => [ - createSecretLock(10, ownerAddressTest1), - createSecretLock(20, ownerAddressTest1), - createSecretLock(30, ownerAddressTest1) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runSecretLocksDbTest( - dbSecretLocks(), - db => db.secretLocks([ownerAddressTest1], undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runSecretLocksDbTest( - dbSecretLocks(), - db => db.secretLocks([ownerAddressTest1], undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runSecretLocksDbTest( - dbSecretLocks(), - db => db.secretLocks([ownerAddressTest1], undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbSecretLocks = () => [ - createSecretLock(10, ownerAddressTest1), - createSecretLock(20, ownerAddressTest1), - createSecretLock(30, ownerAddressTest1) - ]; - - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbSecretLocks(), db => db.secretLocks([ownerAddressTest1], undefined, options), [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbSecretLocks(), db => db.secretLocks([ownerAddressTest1], undefined, options), [10]); - }); - }); - }); -}); diff --git a/rest/test/plugins/lockSecret/lockSecretRoutes_spec.js b/rest/test/plugins/lockSecret/lockSecretRoutes_spec.js deleted file mode 100644 index 189eb6c96..000000000 --- a/rest/test/plugins/lockSecret/lockSecretRoutes_spec.js +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const lockSecretRoutes = require('../../../src/plugins/lockSecret/lockSecretRoutes'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; -const { convert } = catapult.utils; - -describe('lock secret routes', () => { - describe('secret locks', () => { - const testAddress = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - const testAddressNoLocks = 'A34B57B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ45AB'; - const testSecret = '5994471ABB01112AFCC18159F6CC74B4F511B99806DA59B3CAF5A9C173CACFC5'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: 'random1', - lock: { - ownerAddress: '', - mosaicId: '', - amount: '', - endHeight: '', - status: '', - hashAlgorithm: '', - secret: '', - recipientAddress: '', - compositeHash: '' - } - }, - { - id: 'random2', - lock: { - ownerAddress: '', - mosaicId: '', - amount: '', - endHeight: '', - status: '', - hashAlgorithm: '', - secret: '', - recipientAddress: '', - compositeHash: '' - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbSecretLocksFake = sinon.fake(addresses => - (Buffer.from(addresses[0]).equals(Buffer.from(address.stringToAddress(testAddress))) - ? Promise.resolve(pageSample) - : Promise.resolve(emptyPageSample))); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { secretLocks: dbSecretLocksFake }; - lockSecretRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbSecretLocksFake.resetHistory(); - }); - - const aliases = ['/account/:address/lock/secret', '/lock/secret']; - aliases.forEach(alias => { - describe(`GET ${alias}`, () => { - const route = mockServer.getRoute(alias).get(); - - describe('by address', () => { - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - expect(dbSecretLocksFake.calledOnce).to.equal(true); - expect(dbSecretLocksFake.firstCall.args[2]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: { address: testAddress } }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('forwards address', () => { - // Arrange: - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbSecretLocksFake.calledOnce).to.equal(true); - expect(dbSecretLocksFake.firstCall.args[0]).to.deep.equal([address.stringToAddress(testAddress)]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards secret', () => { - // Arrange: - const req = { params: { address: testAddress, secret: testSecret } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbSecretLocksFake.calledOnce).to.equal(true); - expect(dbSecretLocksFake.firstCall.args[1]).to.deep.equal(convert.hexToUint8(testSecret)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns empty if no secret locks found', () => { - // Arrange: - const req = { params: { address: testAddressNoLocks } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbSecretLocksFake.calledOnce).to.equal(true); - expect(dbSecretLocksFake.firstCall.args[0]).to.deep.equal([address.stringToAddress(testAddressNoLocks)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'secretLockInfo', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbSecretLocksFake.calledOnce).to.equal(true); - expect(dbSecretLocksFake.firstCall.args[0]).to.deep.equal([address.stringToAddress(testAddress)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'secretLockInfo', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('throws error if address is invalid', () => { - // Arrange: - const req = { params: { address: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('address has an invalid format'); - }); - }); - }); - }); - - describe('by compositeHash', () => { - const compositeHashes = ['C54AFD996DF1F52748EBC5B40F8D0DC242A6A661299149F5F96A0C21ECCB653F']; - const uint64Hashes = compositeHashes.map(routeUtils.namedParserMap.hash256); - test.route.document.addGetPostDocumentRouteTests(lockSecretRoutes.register, { - routes: { singular: '/lock/secret/:compositeHash', plural: '/lock/secret' }, - - inputs: { - valid: { object: { compositeHash: compositeHashes[0] }, parsed: [uint64Hashes[0]], printable: compositeHashes[0] }, - validMultiple: { object: { compositeHashes }, parsed: uint64Hashes }, - invalid: { object: { compositeHash: '12345' }, error: 'compositeHash has an invalid format' }, - invalidMultiple: { - object: { compositeHashes: [compositeHashes[0], '12345'] }, - error: 'element in array compositeHashes has an invalid format' - } - }, - - dbApiName: 'secretLocksByCompositeHash', - type: 'secretLockInfo' - }); - }); - }); -}); diff --git a/rest/test/plugins/lockSecret/lockSecret_spec.js b/rest/test/plugins/lockSecret/lockSecret_spec.js deleted file mode 100644 index 6bc0a2829..000000000 --- a/rest/test/plugins/lockSecret/lockSecret_spec.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const LockSecretDb = require('../../../src/plugins/lockSecret/LockSecretDb'); -const lockSecret = require('../../../src/plugins/lockSecret/lockSecret'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('lock secret plugin', () => { - pluginTest.assertThat.pluginCreatesDb(lockSecret, LockSecretDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(lockSecret); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(lockSecret); - - describe('register routes', () => { - it('registers lock secret GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - lockSecret.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/account/:address/lock/secret', - '/lock/secret', - '/lock/secret/:compositeHash', - '/lock/secret/:compositeHash/merkle' - ]); - }); - - it('registers POST routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - lockSecret.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/lock/secret' - ]); - }); - }); -}); diff --git a/rest/test/plugins/metadata/MetadataDb_spec.js b/rest/test/plugins/metadata/MetadataDb_spec.js deleted file mode 100644 index d3a19b3ad..000000000 --- a/rest/test/plugins/metadata/MetadataDb_spec.js +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const CatapultDb = require('../../../src/db/CatapultDb'); -const { convertToLong } = require('../../../src/db/dbUtils'); -const MetadataDb = require('../../../src/plugins/metadata/MetadataDb'); -const test = require('../../db/utils/dbTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; - -describe('metadata db', () => { - const { createObjectId } = test.db; - - const runMetadataDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => - test.db.runDbTest(dbEntities, 'metadata', db => new MetadataDb(db), issueDbCommand, assertDbCommandResult); - - describe('metadata', () => { - const testAddress1 = address.stringToAddress('SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'); - const testAddress2 = address.stringToAddress('NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const createMetadata = (objectId, sourceAddress, targetAddress, scopedMetadataKey, targetId, metadataType) => ({ - _id: createObjectId(objectId), - metadataEntry: { - sourceAddress: sourceAddress ? Buffer.from(sourceAddress) : undefined, - targetAddress: targetAddress ? Buffer.from(targetAddress) : undefined, - scopedMetadataKey: scopedMetadataKey ? convertToLong(scopedMetadataKey) : undefined, - targetId: targetId ? convertToLong(targetId) : undefined, - metadataType: undefined !== metadataType ? metadataType : undefined - } - }); - - const runTestAndVerifyIds = (dbMetadata, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runMetadataDbTest( - dbMetadata, - dbQuery, - metadataPage => { - const returnedIds = metadataPage.data.map(t => t.id); - expect(metadataPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbMetadata = [createMetadata(10)]; - - // Act + Assert: - return runMetadataDbTest( - dbMetadata, - db => db.metadata(undefined, undefined, undefined, undefined, undefined, paginationOptions), - page => { - const expected_keys = ['id', 'metadataEntry']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns filtered metadata by sourceAddress', () => { - // Arrange: - const dbMetadata = [ - createMetadata(10, testAddress1), - createMetadata(20, testAddress2) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata, - db => db.metadata(testAddress2, undefined, undefined, undefined, undefined, paginationOptions), [20] - ); - }); - - it('returns filtered metadata by targetAddress', () => { - // Arrange: - const dbMetadata = [ - createMetadata(10, undefined, testAddress1), - createMetadata(20, undefined, testAddress2) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata, - db => db.metadata(undefined, testAddress2, undefined, undefined, undefined, paginationOptions), [20] - ); - }); - - it('returns filtered metadata by scopedMetadataKey', () => { - // Arrange: - const dbMetadata = [ - createMetadata(10, undefined, undefined, [0x1CAD29E3, 0x0DC67FBE]), - createMetadata(20, undefined, undefined, [0xAAAD29AA, 0xAAC67FAA]) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata, - db => db.metadata(undefined, undefined, [0x1CAD29E3, 0x0DC67FBE], undefined, undefined, paginationOptions), [10] - ); - }); - - it('returns filtered metadata by targetId', () => { - // Arrange: - const dbMetadata = [ - createMetadata(10, undefined, undefined, undefined, [0xAAAD29AA, 0xAAC67FAA]), - createMetadata(20, undefined, undefined, undefined, [0x1CAD29E3, 0x0DC67FBE]) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata, - db => db.metadata(undefined, undefined, undefined, [0xAAAD29AA, 0xAAC67FAA], undefined, paginationOptions), [10] - ); - }); - - it('returns filtered metadata by metadataType', () => { - // Arrange: - const dbMetadata = [ - createMetadata(10, undefined, undefined, undefined, undefined, 45), - createMetadata(20, undefined, undefined, undefined, undefined, 87) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata, - db => db.metadata(undefined, undefined, undefined, undefined, 87, paginationOptions), [20] - ); - }); - - it('returns all the metadata if no filters provided', () => { - // Arrange: - const dbMetadata = [ - createMetadata(10), - createMetadata(20) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata, - db => db.metadata(undefined, undefined, undefined, undefined, undefined, paginationOptions), [10, 20] - ); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbMetadata = () => [ - createMetadata(10), - createMetadata(20), - createMetadata(30) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runMetadataDbTest( - dbMetadata(), - db => db.metadata(undefined, undefined, undefined, undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runMetadataDbTest( - dbMetadata(), - db => db.metadata(undefined, undefined, undefined, undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runMetadataDbTest( - dbMetadata(), - db => db.metadata(undefined, undefined, undefined, undefined, undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbMetadata = () => [ - createMetadata(10), - createMetadata(20), - createMetadata(30) - ]; - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata(), db => db.metadata(undefined, undefined, undefined, undefined, undefined, options), [30] - ); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds( - dbMetadata(), db => db.metadata(undefined, undefined, undefined, undefined, undefined, options), [10] - ); - }); - }); - }); -}); diff --git a/rest/test/plugins/metadata/metadataRoutes_spec.js b/rest/test/plugins/metadata/metadataRoutes_spec.js deleted file mode 100644 index 70d3061b2..000000000 --- a/rest/test/plugins/metadata/metadataRoutes_spec.js +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const metadataRoutes = require('../../../src/plugins/metadata/metadataRoutes'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; - -describe('metadata routes', () => { - describe('metadata', () => { - const testAddress = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: '', - metadataEntry: { - compositeHash: 'random1', - sourceAddress: 1, - targetAddress: '', - scopedMetadataKey: '', - targetId: 1, - metadataType: 3, - valueSize: 3, - value: '' - } - }, - { - id: '', - metadataEntry: { - compositeHash: 'random2', - sourceAddress: 1, - targetAddress: '', - scopedMetadataKey: '', - targetId: 1, - metadataType: 3, - valueSize: 3, - value: '' - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbMetadataFake = sinon.fake(sourceAddress => - (sourceAddress ? Promise.resolve(emptyPageSample) : Promise.resolve(pageSample))); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { metadata: dbMetadataFake }; - metadataRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbMetadataFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/metadata').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[5]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty page if no metadata found', () => { - // Arrange: - const req = { params: { sourceAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'metadata', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards sourceAddress', () => { - // Arrange: - const req = { params: { sourceAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[0]).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards targetAddress', () => { - // Arrange: - const req = { params: { targetAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[1]).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards scopedMetadataKey', () => { - // Arrange: - const req = { params: { scopedMetadataKey: '0DC67FBE1CAD29E3' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[2]).to.deep.equal([0x1CAD29E3, 0x0DC67FBE]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards targetId', () => { - // Arrange: - const req = { params: { targetId: '0DC67FBE1CAD29E3' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[3]).to.deep.equal([0x1CAD29E3, 0x0DC67FBE]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards metadataType', () => { - // Arrange: - const req = { params: { metadataType: '1' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[4]).to.equal(1); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMetadataFake.calledOnce).to.equal(true); - expect(dbMetadataFake.firstCall.args[0]).to.deep.equal(undefined); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'metadata', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - }); -}); diff --git a/rest/test/plugins/metadata/metadata_spec.js b/rest/test/plugins/metadata/metadata_spec.js deleted file mode 100644 index faa804e7c..000000000 --- a/rest/test/plugins/metadata/metadata_spec.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MetadataDb = require('../../../src/plugins/metadata/MetadataDb'); -const metadata = require('../../../src/plugins/metadata/metadata'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('metadata plugin', () => { - pluginTest.assertThat.pluginCreatesDb(metadata, MetadataDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(metadata); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(metadata); - - describe('register routes', () => { - it('registers GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - const registeredRoutes = ['/metadata', - '/metadata/:compositeHash', - '/metadata/:compositeHash/merkle']; - - // Act: - metadata.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, registeredRoutes); - }); - - it('registers POST routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - metadata.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/metadata' - ]); - }); - }); -}); diff --git a/rest/test/plugins/mosaic/MosaicDb_spec.js b/rest/test/plugins/mosaic/MosaicDb_spec.js deleted file mode 100644 index dba7e21f2..000000000 --- a/rest/test/plugins/mosaic/MosaicDb_spec.js +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const CatapultDb = require('../../../src/db/CatapultDb'); -const MosaicDb = require('../../../src/plugins/mosaic/MosaicDb'); -const test = require('../../db/utils/dbTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { Binary, Long } = MongoDb; -const { address } = catapult.model; - -describe('mosaic db', () => { - const { createObjectId } = test.db; - - const runMosaicsDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => - test.db.runDbTest(dbEntities, 'mosaics', db => new MosaicDb(db), issueDbCommand, assertDbCommandResult); - - describe('mosaics', () => { - const ownerAddressTest1 = address.stringToAddress('SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'); - const ownerAddressTest2 = address.stringToAddress('NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const createMosaic = (objectId, mosaicId, ownerAddress) => ({ - _id: createObjectId(objectId), - mosaic: { id: mosaicId, ownerAddress: ownerAddress ? Buffer.from(ownerAddress) : undefined } - }); - - const runTestAndVerifyIds = (dbMosaics, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runMosaicsDbTest( - dbMosaics, - dbQuery, - mosaicsPage => { - const returnedIds = mosaicsPage.data.map(t => t.id); - expect(mosaicsPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbMosaics = [createMosaic(10, 100, ownerAddressTest1)]; - - // Act + Assert: - return runMosaicsDbTest( - dbMosaics, - db => db.mosaics(undefined, paginationOptions), - page => { - const expected_keys = ['id', 'mosaic']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns empty array for unknown ownerAddress', () => { - // Arrange: - const dbMosaics = [ - createMosaic(10, 1, ownerAddressTest1), - createMosaic(20, 2, ownerAddressTest1) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbMosaics, db => db.mosaics(ownerAddressTest2, paginationOptions), []); - }); - - it('returns filtered mosaics by ownerAddress', () => { - // Arrange: - const dbMosaics = [ - createMosaic(10, 1, ownerAddressTest1), - createMosaic(20, 2, ownerAddressTest2) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbMosaics, db => db.mosaics(ownerAddressTest2, paginationOptions), [20]); - }); - - it('returns all the mosaics if no ownerAddress provided', () => { - // Arrange: - const dbMosaics = [ - createMosaic(10, 1, ownerAddressTest1), - createMosaic(20, 2, ownerAddressTest2) - ]; - - // Act + Assert: - return runTestAndVerifyIds(dbMosaics, db => db.mosaics(undefined, paginationOptions), [10, 20]); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbMosaics = () => [ - createMosaic(10, 20), - createMosaic(20, 30), - createMosaic(30, 10) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runMosaicsDbTest( - dbMosaics(), - db => db.mosaics(undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runMosaicsDbTest( - dbMosaics(), - db => db.mosaics(undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runMosaicsDbTest( - dbMosaics(), - db => db.mosaics(undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbMosaics = () => [ - createMosaic(10, 20), - createMosaic(20, 30), - createMosaic(30, 10) - ]; - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbMosaics(), db => db.mosaics(undefined, options), [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbMosaics(), db => db.mosaics(undefined, options), [10]); - }); - }); - }); - - describe('mosaics by ids', () => { - const createMosaic = (id, mosaicId, ownerAddress, parentId) => { - const mosaic = { - ownerAddress: new Binary(ownerAddress), - id: Long.fromNumber(mosaicId), - namespaceId: Long.fromNumber(parentId) - }; - - return { _id: createObjectId(id), mosaic }; - }; - - /* - * Creates mosaics with ids in the 1000s range, whereas namespace ids will be in the 2000s range - */ - const createMosaics = (numNamespaces, numMosaicsPerNamespace) => { - const ownerAddress = test.random.address(); - const mosaics = []; - let dbId = 0; - let id = 10000; - for (let namespaceId = 0; namespaceId < numNamespaces; ++namespaceId) { - for (let i = 0; i < numMosaicsPerNamespace; ++i) - mosaics.push(createMosaic(dbId++, id++, ownerAddress, 20000 + namespaceId)); - } - - return mosaics; - }; - - it('returns empty array for unknown mosaic ids', () => { - // Arrange: - const mosaics = createMosaics(3, 4); - - // Assert: - return runMosaicsDbTest( - mosaics, - db => db.mosaicsByIds([[123, 456]]), - entities => { expect(entities).to.deep.equal([]); } - ); - }); - - it('returns single matching mosaic', () => { - // Arrange: - const mosaics = createMosaics(3, 4); - - // Assert: - return runMosaicsDbTest( - mosaics, - db => db.mosaicsByIds([[10010, 0]]), - entities => { - expect(entities).to.deep.equal([{ id: createObjectId(10), ...mosaics[10] }]); - } - ); - }); - - it('returns multiple matching mosaics', () => { - // Arrange: - const mosaics = createMosaics(3, 4); - - // Assert: - return runMosaicsDbTest( - mosaics, - db => db.mosaicsByIds([[10010, 0], [10007, 0], [10003, 0]]), - entities => { - expect(entities).to.deep.equal([ - { id: createObjectId(10), ...mosaics[10] }, - { id: createObjectId(7), ...mosaics[7] }, - { id: createObjectId(3), ...mosaics[3] } - ]); - } - ); - }); - - it('returns only known mosaics', () => { - // Arrange: - const mosaics = createMosaics(3, 4); - - // Assert: - return runMosaicsDbTest( - mosaics, - db => db.mosaicsByIds([[10010, 0], [10021, 0], [10003, 0]]), - entities => expect(entities).to.deep.equal([ - { id: createObjectId(10), ...mosaics[10] }, - { id: createObjectId(3), ...mosaics[3] } - ]) - ); - }); - }); -}); diff --git a/rest/test/plugins/mosaic/mosaicRoutes_spec.js b/rest/test/plugins/mosaic/mosaicRoutes_spec.js deleted file mode 100644 index e3bce581e..000000000 --- a/rest/test/plugins/mosaic/mosaicRoutes_spec.js +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const mosaicRoutes = require('../../../src/plugins/mosaic/mosaicRoutes'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; - -describe('mosaic routes', () => { - describe('mosaics', () => { - const testAddress = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: '', - mosaic: { - id: 'random1', - supply: 1, - startHeight: '', - ownerAddress: '', - revision: 1, - flags: 3, - divisibility: 3, - duration: '' - } - }, - { - id: '', - mosaic: { - id: 'random2', - supply: 1, - startHeight: '', - ownerAddress: '', - revision: 1, - flags: 3, - divisibility: 3, - duration: '' - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbMosaicsFake = sinon.fake(ownerAddress => - (ownerAddress ? Promise.resolve(emptyPageSample) : Promise.resolve(pageSample))); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { mosaics: dbMosaicsFake }; - mosaicRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbMosaicsFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/mosaics').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbMosaicsFake.calledOnce).to.equal(true); - expect(dbMosaicsFake.firstCall.args[1]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty page if no mosaics found', () => { - // Arrange: - const req = { params: { ownerAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'mosaicDescriptor', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards query without ownerAddress if not provided', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicsFake.calledOnce).to.equal(true); - expect(dbMosaicsFake.firstCall.args[0]).to.deep.equal(undefined); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards ownerAddress', () => { - // Arrange: - const req = { params: { ownerAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicsFake.calledOnce).to.equal(true); - expect(dbMosaicsFake.firstCall.args[0]).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicsFake.calledOnce).to.equal(true); - expect(dbMosaicsFake.firstCall.args[0]).to.deep.equal(undefined); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'mosaicDescriptor', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('throws error if ownerAddress is invalid', () => { - // Arrange: - const req = { params: { ownerAddress: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('ownerAddress has an invalid format'); - }); - }); - }); - - describe('mosaics by id', () => { - const mosaicIds = ['1234567890ABCDEF', 'ABCDEF0123456789']; - const uint64MosaicIds = [[0x90ABCDEF, 0x12345678], [0x23456789, 0xABCDEF01]]; - const errorMessage = 'has an invalid format'; - test.route.document.addGetPostDocumentRouteTests(mosaicRoutes.register, { - routes: { singular: '/mosaics/:mosaicId', plural: '/mosaics' }, - inputs: { - valid: { object: { mosaicId: mosaicIds[0] }, parsed: [uint64MosaicIds[0]], printable: mosaicIds[0] }, - validMultiple: { object: { mosaicIds }, parsed: uint64MosaicIds }, - invalid: { object: { mosaicId: '12345' }, error: `mosaicId ${errorMessage}` }, - invalidMultiple: { - object: { mosaicIds: [mosaicIds[0], '12345', mosaicIds[1]] }, - error: `element in array mosaicIds ${errorMessage}` - } - }, - dbApiName: 'mosaicsByIds', - type: 'mosaicDescriptor' - }); - }); -}); diff --git a/rest/test/plugins/mosaic/mosaic_spec.js b/rest/test/plugins/mosaic/mosaic_spec.js deleted file mode 100644 index c7170c77e..000000000 --- a/rest/test/plugins/mosaic/mosaic_spec.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MosaicDb = require('../../../src/plugins/mosaic/MosaicDb'); -const mosaic = require('../../../src/plugins/mosaic/mosaic'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('mosaic plugin', () => { - pluginTest.assertThat.pluginCreatesDb(mosaic, MosaicDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(mosaic); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(mosaic); - - describe('register routes', () => { - it('registers GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - mosaic.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/mosaics', - '/mosaics/:mosaicId', - '/mosaics/:mosaicId/merkle', - '/network/currency/supply/circulating', - '/network/currency/supply/total', - '/network/currency/supply/max' - ]); - }); - - it('registers POST routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - mosaic.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/mosaics' - ]); - }); - }); -}); diff --git a/rest/test/plugins/mosaic/supplyRoutes_spec.js b/rest/test/plugins/mosaic/supplyRoutes_spec.js deleted file mode 100644 index 28adcb7bc..000000000 --- a/rest/test/plugins/mosaic/supplyRoutes_spec.js +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong } = require('../../../src/db/dbUtils'); -const supplyRoutes = require('../../../src/plugins/mosaic/supplyRoutes'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); -const fs = require('fs'); - -describe('supply routes', () => { - describe('network currency supply', () => { - const maxSupply = 9000000000000000; - const xymSupply = 8998999998000000; - - const currencyMosaicId = '0x1234\'5678\'ABCD\'EF01'; - const nemesisSignerPublicKey = 'AF1B9DCF4FAD2CDC2C04B4F9CBDF3C9C884A9F05B40A59E233681E282DC824D9'; - const uncirculatingAccountPublicKey1 = 'D4912C4CA33F608E95B9C3ABAE59263B99E2DF6E87252D61F8DEFADF7DFFC455'; - const uncirculatingAccountPublicKey2 = '3BF1E1F3072E3BE0CD851E4741E101E33DB19C163895F69AA890E7CF177C878C'; - const circulatingAccountPublicKey1 = '346AA758B2ED98923204D7361A5A47C7B569C594C7904461C67459703D7B5874'; - - const mosaicsSample = [{ - id: '', - mosaic: { - id: convertToLong([0xABCDEF01, 0x12345678]), - supply: convertToLong(xymSupply), - startHeight: '', - ownerAddress: '', - revision: 1, - flags: 3, - divisibility: 3, - duration: '' - } - }]; - - const createAccountSample = (publicKey, currencyAmount, otherAmount) => ({ - address: '', - addressHeight: '', - publicKey: catapult.utils.convert.hexToUint8(publicKey), - publicKeyHeight: '', - supplementalPublicKeys: {}, - importance: '', - importanceHeight: '', - activityBuckets: [], - mosaics: [ - { id: convertToLong([0xABCDEF01, 0x22222222]), amount: convertToLong(otherAmount) }, - { id: convertToLong([0xABCDEF01, 0x12345678]), amount: convertToLong(currencyAmount) } - ] - }); - - const accountsSample = [ - { id: 'random1', account: createAccountSample(nemesisSignerPublicKey, 1000000, 9000000) }, - { id: 'random2', account: createAccountSample(uncirculatingAccountPublicKey1, 2000000, 9000000) }, - { id: 'random3', account: createAccountSample(circulatingAccountPublicKey1, 4000000, 9000000) }, - { id: 'random4', account: createAccountSample(uncirculatingAccountPublicKey2, 8000000, 9000000) } - ]; - - const dbMosaicsFake = sinon.fake(() => Promise.resolve(mosaicsSample)); - const dbAccountsFake = sinon.fake(accountIds => { - const filteredAccountsSample = accountsSample.filter(accountSample => - accountIds.some(accountId => catapult.utils.array.deepEqual(accountId.publicKey, accountSample.account.publicKey))); - return Promise.resolve(filteredAccountsSample); - }); - - const mockServer = new MockServer(); - - const db = { - mosaicsByIds: dbMosaicsFake, - catapultDb: { - accountsByIds: dbAccountsFake - } - }; - - const services = { - config: { - apiNode: {}, - uncirculatingAccountPublicKeys: [uncirculatingAccountPublicKey1, uncirculatingAccountPublicKey2] - } - }; - supplyRoutes.register(mockServer.server, db, services); - - const req = { params: {} }; - - afterEach(() => { - mockServer.resetStats(); - dbMosaicsFake.resetHistory(); - fs.readFile.restore(); - }); - - describe('GET', () => { - // Arrange: - it('network currency supply circulating (without burns)', () => { - sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, [ - '[network]', - `nemesisSignerPublicKey=${nemesisSignerPublicKey}`, - '', - '[chain]', - 'currencyMosaicId = 0x1234\'5678\'ABCD\'EF02' - ].join('\n'))); - const route = mockServer.getRoute('/network/currency/supply/circulating').get(); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.equal('8998999998000.000'); - }); - }); - - it('network currency supply circulating (with burns)', () => { - // Arrange: - sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, [ - '[network]', - `nemesisSignerPublicKey=${nemesisSignerPublicKey}`, - '', - '[chain]', - `currencyMosaicId = ${currencyMosaicId}` - ].join('\n'))); - const route = mockServer.getRoute('/network/currency/supply/circulating').get(); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.equal('8998999987000.000'); - }); - }); - - it('network currency supply total', () => { - // Arrange: - sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, `[chain]\ncurrencyMosaicId = ${currencyMosaicId}`)); - - const route = mockServer.getRoute('/network/currency/supply/total').get(); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.equal('8998999998000.000'); - }); - }); - - it('network currency supply max', () => { - // Arrange: - sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, `[chain]\ncurrencyMosaicId = ${currencyMosaicId}\nmaxMosaicAtomicUnits = ${maxSupply}`)); - - const route = mockServer.getRoute('/network/currency/supply/max').get(); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.equal('9000000000000.000'); - }); - }); - }); - }); -}); diff --git a/rest/test/plugins/multisig/MultisigDb_spec.js b/rest/test/plugins/multisig/MultisigDb_spec.js deleted file mode 100644 index 96baf6908..000000000 --- a/rest/test/plugins/multisig/MultisigDb_spec.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const entitiesByAccounts = require('./entriesByAccountsTestUtils'); -const test = require('./multisigDbTestUtils'); - -describe('multisig db', () => { - describe('multisigs by addresses', () => - entitiesByAccounts.addTests({ - createEntry: (id, account) => test.db.createMultisigEntry(id, account), - toDbApiId: owner => owner.address, - runDbTest: (entries, accountsToQuery, assertDbCommandResult) => test.db.runDbTest( - entries, - db => db.multisigsByAddresses(accountsToQuery), - assertDbCommandResult - ) - })); -}); diff --git a/rest/test/plugins/multisig/entriesByAccountsTestUtils.js b/rest/test/plugins/multisig/entriesByAccountsTestUtils.js deleted file mode 100644 index bc7e46b9e..000000000 --- a/rest/test/plugins/multisig/entriesByAccountsTestUtils.js +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const test = require('../../testUtils'); -const { expect } = require('chai'); - -const createOwner = test.random.account; - -const createEntries = (createEntry, knownOwner, numRandomEntries) => { - const entries = []; - - // add random entries (with even ids) - const randomAccount = createOwner(); - for (let dbId = 0; dbId < numRandomEntries; ++dbId) { - randomAccount[0] = dbId; - entries.push(createEntry(2 * dbId, randomAccount)); - } - - // add entry for known owner (with odd id) - entries.push(createEntry(3, knownOwner)); - - return entries; -}; - -const addTests = traits => { - const runEntriesByAccountsTest = (additionalOwners, accountsToQuery, expectedIndexes) => { - // Arrange: - const entries = createEntries(traits.createEntry, createOwner(), 4); - let i = 0; - additionalOwners.forEach(account => { - entries.push(traits.createEntry(10 + i++, account)); - }); - - // Assert: - return traits.runDbTest( - entries, - accountsToQuery, - entities => expect(entities).to.deep.equal(expectedIndexes.map(index => entries[index])) - ); - }; - - it('returns empty array if there are no entries', () => - // Assert: - runEntriesByAccountsTest([], [createOwner(), createOwner(), createOwner()].map(owner => traits.toDbApiId(owner)), [])); - - it('returns single matching entry', () => { - // Arrange: - const account = createOwner(); - - // Assert: first five entries are the seeds - return runEntriesByAccountsTest([account], [traits.toDbApiId(account)], [5]); - }); - - it('returns multiple matching entries (of a single account)', () => { - // Arrange: - const account = createOwner(); - - // Assert: first five entries are the seeds - const accountId = traits.toDbApiId(account); - return runEntriesByAccountsTest([account, account, account], [accountId], [5, 6, 7]); - }); - - it('returns multiple matching entries (one per account)', () => { - // Arrange: - const accounts = []; - for (let i = 0; 6 > i; ++i) - accounts.push(createOwner()); - - // Assert: first five entries are the seeds - const queriedIds = [0, 3, 5].map(index => traits.toDbApiId(accounts[index])); - return runEntriesByAccountsTest(accounts, queriedIds, [5, 8, 10]); - }); - - it('returns only matching entries', () => { - // Arrange: - const accounts = [createOwner(), createOwner()]; - - // Assert: first five entries are the seeds - const queriedIds = [accounts[0], createOwner(), accounts[1], createOwner()].map(owner => traits.toDbApiId(owner)); - return runEntriesByAccountsTest(accounts, queriedIds, [5, 6]); - }); -}; - -module.exports = { addTests }; diff --git a/rest/test/plugins/multisig/multisigDbTestUtils.js b/rest/test/plugins/multisig/multisigDbTestUtils.js deleted file mode 100644 index c9f1e11ee..000000000 --- a/rest/test/plugins/multisig/multisigDbTestUtils.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MultisigDb = require('../../../src/plugins/multisig/MultisigDb'); -const dbTestUtils = require('../../db/utils/dbTestUtils'); -const test = require('../../testUtils'); -const MongoDb = require('mongodb'); - -const { Binary } = MongoDb; - -const createMultisigEntry = (id, owner) => ({ - // simulated account is multisig with two cosigners and cosigns one multisig account - _id: dbTestUtils.db.createObjectId(id), - multisig: { - accountAddress: new Binary(owner.address), - cosignatoryAddresses: [new Binary(test.random.address()), new Binary(test.random.address())], - multisigAddresses: [new Binary(test.random.address())] - } -}); - -const multisigDbTestUtils = { - db: { - createMultisigEntry, - runDbTest: (dbEntities, issueDbCommand, assertDbCommandResult) => - dbTestUtils.db.runDbTest(dbEntities, 'multisigs', db => new MultisigDb(db), issueDbCommand, assertDbCommandResult) - } -}; -Object.assign(multisigDbTestUtils, test); - -module.exports = multisigDbTestUtils; diff --git a/rest/test/plugins/multisig/multisigRoutes_spec.js b/rest/test/plugins/multisig/multisigRoutes_spec.js deleted file mode 100644 index e2d557d21..000000000 --- a/rest/test/plugins/multisig/multisigRoutes_spec.js +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeAddressGetTestUtils = require('./routeAddressGetTestUtils'); -const multisigRoutes = require('../../../src/plugins/multisig/multisigRoutes'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -describe('multisig routes', () => { - describe('get by account', () => { - routeAddressGetTestUtils.addDefaultTests({ - registerRoutes: multisigRoutes.register, - route: '/account/:address/multisig', - dbApiName: 'multisigsByAddresses', - dbType: 'multisigEntry' - }); - }); - - describe('get multisig graph by account', () => { - const createRouteDescriptor = routeAddressGetTestUtils.routeDescriptorFactory({ - registerRoutes: multisigRoutes.register, - route: '/account/:address/multisig/graph', - dbApiName: 'multisigsByAddresses', - dbType: 'multisigGraph' - }); - - const addGetTests = dataTraits => { - const routeDescriptor = createRouteDescriptor(dataTraits); - routeDescriptor.extendDb = db => { - (originalMultisigsByAddresses => { - db.multisigsByAddresses = (...args) => originalMultisigsByAddresses(...args) - .then(result => (undefined === result ? [] : result)); - })(db.multisigsByAddresses); - }; - const getDocumentRouteTests = test.route.document.prepareGetDocumentRouteTests(multisigRoutes.register, routeDescriptor); - getDocumentRouteTests.addNotFoundInputTest(routeDescriptor.inputs.valid); - getDocumentRouteTests.addInvalidKeyTest(routeDescriptor.inputs.invalid); - }; - - // note: multisig/graph has complicated "valid" tests (below), so instead of using - // addDefaultTests, use addGetDocumentTests to run only invalid tests. - routeAddressGetTestUtils.addGetDocumentTests(addGetTests); - - const createMultisigEntry = (marker, upstreamCount, downstreamCount) => { - const upstreamArray = []; - for (let i = 0; i < upstreamCount; ++i) { - const address = test.random.address(); - address[0] = marker - 1; - upstreamArray.push({ buffer: address }); - } - - const downstreamArray = []; - for (let i = 0; i < downstreamCount; ++i) { - const address = test.random.address(); - address[0] = marker + 1; - downstreamArray.push({ buffer: address }); - } - - return { - multisig: { - accountAddress: { buffer: test.random.address() }, - multisigAddresses: upstreamArray, - cosignatoryAddresses: downstreamArray - } - }; - }; - - const extractAddresses = (multisigEntryArray, fieldname) => { - const addresses = []; - multisigEntryArray.forEach(multisigEntry => multisigEntry.multisig[fieldname].forEach(address => { - addresses.push(address.buffer); - })); - - return addresses; - }; - - const createAddressWithMarker = marker => { - const address = new Uint8Array(test.random.address()); - address[0] = marker; - return address; - }; - - const runTest = (accountAddress, multisigEntriesArray, expectedParams) => { - // Arrange: - // Note that the first byte of each address is used as index into the multisigEntriesArray - const multisigsByAddressesParams = []; - const db = { - multisigsByAddresses: addresses => { - multisigsByAddressesParams.push(addresses); - if (0 === addresses.length) - return Promise.resolve([]); - - return Promise.resolve(multisigEntriesArray[addresses[0][0]]); - } - }; - - // Act: - return test.route.executeSingle( - multisigRoutes.register, - '/account/:address/multisig/graph', - 'get', - { address: catapult.model.address.addressToString(accountAddress) }, - - db, - undefined, - response => { - // Assert: parameters passed to db functions are correct - // note that sort is needed since the upstream and downstream operations run concurrently resulting in - // indeterminate call order of the db function - expect(multisigsByAddressesParams.sort()).to.deep.equal(expectedParams.sort()); - - // check response (accountAddress[0] is index, which is negative of level) - let level = 0 - accountAddress[0]; - const expectedPayload = multisigEntriesArray.map(multisigEntries => ({ level: level++, multisigEntries })); - - expect(response).to.deep.equal({ payload: expectedPayload, type: 'multisigGraph' }); - } - ); - }; - - it('returns correct graph if multisig account has neither upstream nor downstream accounts', () => { - // Arrange: - const multisigEntriesArray = [[createMultisigEntry(0, 0, 0)]]; - const address = createAddressWithMarker(0); - const expectedParams = [[address], [], []]; - - // Act + Assert: - return runTest(address, multisigEntriesArray, expectedParams); - }); - - it('returns correct graph if multisig account has only upstream accounts', () => { - // Arrange: - // A1 - B1 - // \ - // A2 - B2- C - const multisigEntriesArray = [ - [createMultisigEntry(0, 0, 1), createMultisigEntry(0, 0, 1)], - [createMultisigEntry(1, 1, 1), createMultisigEntry(1, 1, 1)], - [createMultisigEntry(2, 2, 0)] - ]; - const address = createAddressWithMarker(2); - const expectedParams = [ - [address], - extractAddresses(multisigEntriesArray[2], 'multisigAddresses'), - extractAddresses(multisigEntriesArray[1], 'multisigAddresses'), - extractAddresses(multisigEntriesArray[0], 'multisigAddresses'), - []]; - - // Act + Assert: - return runTest(address, multisigEntriesArray, expectedParams); - }); - - it('returns correct graph if multisig account has only downstream accounts', () => { - // Arrange: - // D1 - E1 - // / - // C - D2 - E2 - const multisigEntriesArray = [ - [createMultisigEntry(0, 0, 2)], - [createMultisigEntry(1, 1, 1), createMultisigEntry(1, 1, 1)], - [createMultisigEntry(1, 1, 0), createMultisigEntry(1, 1, 0)] - ]; - const address = createAddressWithMarker(0); - const expectedParams = [ - [address], - [], - extractAddresses(multisigEntriesArray[0], 'cosignatoryAddresses'), - extractAddresses(multisigEntriesArray[1], 'cosignatoryAddresses'), - extractAddresses(multisigEntriesArray[2], 'cosignatoryAddresses')]; - - // Act + Assert: - return runTest(address, multisigEntriesArray, expectedParams); - }); - - it('returns correct graph if multisig account has upstream and downstream accounts', () => { - // Arrange: - // B1 D1 - // / \ / - // A - B2- C - D2 - const multisigEntriesArray = [ - [createMultisigEntry(0, 0, 2)], - [createMultisigEntry(1, 1, 1), createMultisigEntry(1, 1, 1)], - [createMultisigEntry(2, 2, 2)], - [createMultisigEntry(3, 1, 0), createMultisigEntry(3, 1, 0)] - ]; - const address = createAddressWithMarker(2); - const expectedParams = [ - [address], - extractAddresses(multisigEntriesArray[2], 'multisigAddresses'), - extractAddresses(multisigEntriesArray[1], 'multisigAddresses'), - [], - extractAddresses(multisigEntriesArray[2], 'cosignatoryAddresses'), - []]; - - // Act + Assert: - return runTest(address, multisigEntriesArray, expectedParams); - }); - }); -}); diff --git a/rest/test/plugins/multisig/multisig_spec.js b/rest/test/plugins/multisig/multisig_spec.js deleted file mode 100644 index b2cfa2693..000000000 --- a/rest/test/plugins/multisig/multisig_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MultisigDb = require('../../../src/plugins/multisig/MultisigDb'); -const multisig = require('../../../src/plugins/multisig/multisig'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('multisig plugin', () => { - pluginTest.assertThat.pluginCreatesDb(multisig, MultisigDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(multisig); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(multisig); - - describe('register routes', () => { - it('registers multisig GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - multisig.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/account/:address/multisig', - '/account/:address/multisig/graph', - '/account/:address/multisig/merkle' - ]); - }); - }); -}); diff --git a/rest/test/plugins/multisig/routeAddressGetTestUtils.js b/rest/test/plugins/multisig/routeAddressGetTestUtils.js deleted file mode 100644 index b813d1ef6..000000000 --- a/rest/test/plugins/multisig/routeAddressGetTestUtils.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); - -const Valid_Address = test.sets.addresses.valid[0]; - -const routeAddressGetTestUtils = { - routeDescriptorFactory: traits => - dataTraits => ({ - route: traits.route, - inputs: { - valid: { - object: { address: dataTraits.valid }, - parsed: dataTraits.expected, - printable: dataTraits.valid - }, - invalid: { object: { address: '12345' }, error: 'address has an invalid format' } - }, - dbApiName: traits.dbApiName, - type: traits.dbType - }), - - addGetDocumentTests: addTests => { - const Valid_Address_Traits = { - valid: Valid_Address, - expected: [[catapult.model.address.stringToAddress(Valid_Address)]] - }; - - describe('by address', () => addTests(Valid_Address_Traits)); - }, - - addDefaultTests: traits => { - const createRouteDescriptor = routeAddressGetTestUtils.routeDescriptorFactory(traits); - const addGetTests = dataTraits => { - const routeDescriptor = createRouteDescriptor(dataTraits); - - // Assert: - test.route.document.addGetDocumentRouteTests(traits.registerRoutes, routeDescriptor); - }; - - routeAddressGetTestUtils.addGetDocumentTests(addGetTests); - } -}; - -module.exports = routeAddressGetTestUtils; diff --git a/rest/test/plugins/namespace/NamespaceDb_spec.js b/rest/test/plugins/namespace/NamespaceDb_spec.js deleted file mode 100644 index 8d300a0c5..000000000 --- a/rest/test/plugins/namespace/NamespaceDb_spec.js +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const test = require('./namespaceDbTestUtils'); -const CatapultDb = require('../../../src/db/CatapultDb'); -const dbUtils = require('../../../src/db/dbUtils'); -const NamespaceDb = require('../../../src/plugins/namespace/NamespaceDb'); -const dbTestUtils = require('../../db/utils/dbTestUtils'); -const testDbOptions = require('../../db/utils/testDbOptions'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { address } = catapult.model; -const { uint64 } = catapult.utils; -const { convertToLong } = dbUtils; -const { Binary } = MongoDb; - -describe('namespace db', () => { - describe('namespaces', () => { - const { createObjectId } = dbTestUtils.db; - - const runNamespacesDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => - dbTestUtils.db.runDbTest(dbEntities, 'namespaces', db => new NamespaceDb(db), issueDbCommand, assertDbCommandResult); - - const level0Test1 = uint64.fromHex('85BBEA6CC462B244'); - const level0Test2 = uint64.fromHex('3C2437767AF232DC'); - const ownerAddressTest1 = address.stringToAddress('SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'); - const ownerAddressTest2 = address.stringToAddress('NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const createNamespace = (objectId, aliasType, level0, ownerAddress, registrationType, - latest = true, expirationHeight = { start: 1, end: 1000 }) => ({ - _id: createObjectId(objectId), - meta: { latest }, - namespace: { - alias: { type: aliasType }, - level0: convertToLong(level0), - ownerAddress: ownerAddress ? Buffer.from(ownerAddress) : undefined, - registrationType, - startHeight: convertToLong(expirationHeight.start), - endHeight: convertToLong(expirationHeight.end) - } - }); - - const runTestAndVerifyIds = (dbNamespaces, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => [createObjectId(id[0]), id[1]]); - - return runNamespacesDbTest( - dbNamespaces, - dbQuery, - namespacesPage => { - const returnedIds = namespacesPage.data.map(t => [t.id, t.meta.active]); - expect(namespacesPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbNamespaces = [createNamespace(10, 1, level0Test1, ownerAddressTest1, 0)]; - - // Act + Assert: - return runNamespacesDbTest( - dbNamespaces, - db => db.namespaces(undefined, undefined, undefined, undefined, paginationOptions), - page => { - const expected_keys = ['id', 'meta', 'namespace']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - describe('return empty array for unknown param', () => { - // Arrange: - const dbNamespaces = () => [createNamespace(10, 1, level0Test1, ownerAddressTest1, 0)]; - - it('aliasType', () => - runTestAndVerifyIds(dbNamespaces(), db => db.namespaces(2, undefined, undefined, undefined, paginationOptions), [], [])); - - it('level0', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(undefined, level0Test2, undefined, undefined, paginationOptions), [], [] - )); - - it('ownerAddress', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(undefined, undefined, ownerAddressTest2, undefined, paginationOptions), [], [] - )); - - it('registrationType', () => - runTestAndVerifyIds(dbNamespaces(), db => db.namespaces(undefined, undefined, undefined, 1, paginationOptions), [], [])); - }); - - describe('returns filtered namespaces by param', () => { - // Arrange: - const dbNamespaces = () => [ - createNamespace(10, 2, level0Test1, ownerAddressTest1, 0), - createNamespace(11, 2, level0Test1, ownerAddressTest1, 0, false), - createNamespace(12, 2, level0Test1, ownerAddressTest1, 0, true, { start: 0, end: 9 }), - createNamespace(20, 1, level0Test2, ownerAddressTest1, 0), - createNamespace(30, 1, level0Test1, ownerAddressTest2, 0), - createNamespace(40, 1, level0Test1, ownerAddressTest1, 1), - createNamespace(50, 1, level0Test1, ownerAddressTest1, 0, false), - createNamespace(60, 1, level0Test1, ownerAddressTest1, 0, true, { start: 0, end: 9 }) - ]; - - it('aliasType', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(2, undefined, undefined, undefined, paginationOptions), [[10, true], [12, false]] - )); - - it('level0', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(undefined, level0Test2, undefined, undefined, paginationOptions), [[20, true]] - )); - - it('ownerAddress', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(undefined, undefined, ownerAddressTest2, undefined, paginationOptions), [[30, true]] - )); - - it('registrationType', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, 1, paginationOptions), [[40, true]] - )); - - it('all', () => - runTestAndVerifyIds( - dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, undefined, paginationOptions), - [[10, true], [12, false], [20, true], [30, true], [40, true], [60, false]] - )); - }); - - it('returns all namepsaces if no params are provided', () => { - // Arrange: - const dbNamespaces = [ - createNamespace(10, 2, level0Test1, ownerAddressTest1, 0), - createNamespace(20, 1, level0Test2, ownerAddressTest2, 0), - createNamespace(30, 1, level0Test2, ownerAddressTest1, 1) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbNamespaces, - db => db.namespaces(undefined, undefined, undefined, undefined, paginationOptions), - [[10, true], [20, true], [30, true]] - ); - }); - - it('only returns active namespaces', () => { - // Arrange: - const dbNamespaces = [ - createNamespace(10, 1, level0Test1, ownerAddressTest1, 0, false), - createNamespace(20, 1, level0Test2, ownerAddressTest1, 0, true) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbNamespaces, - db => db.namespaces(undefined, undefined, undefined, undefined, paginationOptions), - [[20, true]] - ); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbNamespaces = () => [ - createNamespace(10, 1, level0Test1, ownerAddressTest1, 0), - createNamespace(20, 2, level0Test1, ownerAddressTest1, 0), - createNamespace(30, 0, level0Test1, ownerAddressTest1, 0) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runNamespacesDbTest( - dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runNamespacesDbTest( - dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runNamespacesDbTest( - dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbNamespaces = () => [ - createNamespace(10, 1, level0Test1, ownerAddressTest1, 0), - createNamespace(20, 2, level0Test1, ownerAddressTest1, 0), - createNamespace(30, 0, level0Test1, ownerAddressTest1, 0) - ]; - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, undefined, options), [[30, true]]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbNamespaces(), - db => db.namespaces(undefined, undefined, undefined, undefined, options), [[10, true]]); - }); - }); - }); - - const createOwner = test.random.account; - - describe('namespace by id', () => { - const { createObjectId } = dbTestUtils.db; - - it('returns undefined for unknown namespace id', () => { - // Arrange: create 5 namespaces and 5 inactive namespaces - const owner = createOwner(); - const namespaces = test.db.createNamespaces(5, owner); - - // Assert: - return test.db.runDbTest( - namespaces, - db => db.namespaceById([123, 456]), - entity => { expect(entity).to.equal(undefined); } - ); - }); - - it('returns root namespace for known level 0 namespace id', () => { - // Arrange: create 5 namespaces and 5 inactive namespaces - const owner = createOwner(); - const namespaces = test.db.createNamespaces(5, owner); - - // Assert: - return test.db.runDbTest( - namespaces, - db => db.namespaceById([12303, 0]), - entity => { - expect(entity.id).to.deep.equal(createObjectId(3)); - expect(entity.meta.active).to.equal(true); - expect(entity.namespace).to.deep.equal(namespaces[3].namespace); - } - ); - }); - - it('returns level 1 child namespace for known level 1 namespace id', () => { - // Arrange: create 5 namespaces and 5 inactive namespaces - const owner = createOwner(); - const namespaces = test.db.createNamespaces(5, owner); - - // Assert: - return test.db.runDbTest( - namespaces, - db => db.namespaceById([12301, 0]), - entity => { - expect(entity.id).to.deep.equal(createObjectId(1)); - expect(entity.meta.active).to.equal(true); - expect(entity.namespace).to.deep.equal(namespaces[1].namespace); - } - ); - }); - - it('returns level 2 child namespace for known level 2 namespace id', () => { - // Arrange: create 5 namespaces and 5 inactive namespaces - const owner = createOwner(); - const namespaces = test.db.createNamespaces(5, owner); - - // Assert: - return test.db.runDbTest( - namespaces, - db => db.namespaceById([12302, 0]), - entity => { - expect(entity.id).to.deep.equal(createObjectId(2)); - expect(entity.meta.active).to.equal(true); - expect(entity.namespace).to.deep.equal(namespaces[2].namespace); - } - ); - }); - }); - - const sanitizeDbEntities = entities => entities.forEach(item => delete item._id); - - const populateCollection = (db, collectionName, entities) => - db.database.collection(collectionName) - .drop() - .catch(() => Promise.resolve()) - .then(() => db.database.collection(collectionName)[Array.isArray(entities) ? 'insertMany' : 'insertOne'](entities)); - - describe('activeNamespacesWithAlias', () => { - const aliasTypeMosaic = catapult.model.namespace.aliasType.mosaic; - const aliasTypeAddress = catapult.model.namespace.aliasType.address; - const testAddress = { - one: 'SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ', - two: 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA', - three: 'SAAAIBC7AM65HOFDLYGFUT46H44TROZ7MUWCW6I' - }; - const lifetime = { start: 0, end: 100 }; - const createNamespace = (namespaceId, aliasTarget, aliasType, depth, expirationHeight) => ({ - meta: { - latest: true - }, - namespace: { - depth, - level0: 1 >= depth ? convertToLong(namespaceId) : '', - level1: 2 === depth ? convertToLong(namespaceId) : '', - level2: 3 === depth ? convertToLong(namespaceId) : '', - alias: { - type: aliasType, - mosaicId: aliasType === catapult.model.namespace.aliasType.mosaic ? convertToLong(aliasTarget) : null, - address: aliasType === catapult.model.namespace.aliasType.address - ? new Binary(Buffer.from(address.stringToAddress(aliasTarget))) - : null - }, - startHeight: convertToLong(expirationHeight.start), - endHeight: convertToLong(expirationHeight.end) - } - }); - - it('returns namespaces by mosaic ids', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const namespace1 = createNamespace(12345, 76756, aliasTypeMosaic, 1, lifetime); - const namespace2 = createNamespace(67891, 87823, aliasTypeMosaic, 2, lifetime); - const namespace3 = createNamespace(34567, 57231, aliasTypeMosaic, 3, lifetime); - const namespace4 = createNamespace(67556, testAddress.one, aliasTypeAddress, 1, lifetime); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: 1 } })) - .then(() => populateCollection(db, 'namespaces', [namespace1, namespace2, namespace3, namespace4])) - .then(() => sanitizeDbEntities([namespace1, namespace2, namespace3, namespace4])) - .then(() => dbFacade.activeNamespacesWithAlias(aliasTypeMosaic, [76756, 87823])) - .then(entities => { - expect(entities).to.deep.equal([ - { ...namespace1, meta: { active: true, latest: true } }, - { ...namespace2, meta: { active: true, latest: true } } - ]); - }) - .then(() => db.close()); - }); - - it('returns namespaces by addresses', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const namespace1 = createNamespace(12345, testAddress.one, aliasTypeAddress, 1, lifetime); - const namespace2 = createNamespace(67891, testAddress.two, aliasTypeAddress, 2, lifetime); - const namespace3 = createNamespace(34567, testAddress.three, aliasTypeAddress, 3, lifetime); - const namespace4 = createNamespace(12345, 76756, aliasTypeMosaic, 1, lifetime); - const namespace5 = createNamespace(12345, 76756, aliasTypeMosaic, 1, { start: 0, end: 9 }); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: 10 } })) - .then(() => populateCollection(db, 'namespaces', [namespace1, namespace2, namespace3, namespace4, namespace5])) - .then(() => sanitizeDbEntities([namespace1, namespace2, namespace3, namespace4, namespace5])) - .then(() => dbFacade.activeNamespacesWithAlias( - aliasTypeAddress, - [ - address.stringToAddress(testAddress.one), - address.stringToAddress(testAddress.two) - ] - )) - .then(entities => { - expect(entities).to.deep.equal([ - { ...namespace1, meta: { active: true, latest: true } }, - { ...namespace2, meta: { active: true, latest: true } } - ]); - }) - .then(() => db.close()); - }); - - it('returns empty for no namespaces with mosaic id', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const namespace1 = createNamespace(12345, 76756, aliasTypeMosaic, 1, lifetime); - const namespace2 = createNamespace(67891, 87823, aliasTypeMosaic, 2, lifetime); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: 10000 } })) - .then(() => populateCollection(db, 'namespaces', [namespace1, namespace2])) - .then(() => sanitizeDbEntities([namespace1, namespace2])) - .then(() => dbFacade.activeNamespacesWithAlias(aliasTypeMosaic, [12121])) - .then(entities => { expect(entities).to.deep.equal([]); }) - .then(() => db.close()); - }); - - it('returns empty for no namespaces with address id', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const namespace1 = createNamespace(12345, testAddress.one, aliasTypeAddress, 1, lifetime); - const namespace2 = createNamespace(67891, testAddress.two, aliasTypeAddress, 2, lifetime); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: 10000 } })) - .then(() => populateCollection(db, 'namespaces', [namespace1, namespace2])) - .then(() => sanitizeDbEntities([namespace1, namespace2])) - .then(() => dbFacade.activeNamespacesWithAlias( - aliasTypeAddress, - [ - address.stringToAddress(testAddress.three) - ] - )) - .then(entities => { expect(entities).to.deep.equal([]); }) - .then(() => db.close()); - }); - - it('does not return expired namespaces for mosaics', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const namespace1 = createNamespace(12345, 76756, aliasTypeMosaic, 1, { start: 0, end: 5 }); - const namespace2 = createNamespace(67891, 87823, aliasTypeMosaic, 2, { start: 0, end: 10 }); - const namespace3 = createNamespace(34567, 57231, aliasTypeMosaic, 3, { start: 0, end: 20 }); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: 10 } })) - .then(() => populateCollection(db, 'namespaces', [namespace1, namespace2, namespace3])) - .then(() => sanitizeDbEntities([namespace1, namespace2, namespace3])) - .then(() => dbFacade.activeNamespacesWithAlias(aliasTypeMosaic, [76756, 87823, 57231])) - .then(entities => { expect(entities).to.deep.equal([{ ...namespace3, meta: { active: true, latest: true } }]); }) - .then(() => db.close()); - }); - - it('does not return expired namespaces for addresses', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const namespace1 = createNamespace(12345, testAddress.one, aliasTypeAddress, 1, { start: 0, end: 5 }); - const namespace2 = createNamespace(67891, testAddress.two, aliasTypeAddress, 2, { start: 0, end: 10 }); - const namespace3 = createNamespace(34567, testAddress.three, aliasTypeAddress, 3, { start: 0, end: 20 }); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection(db, 'chainStatistic', { current: { height: 10 } })) - .then(() => populateCollection(db, 'namespaces', [namespace1, namespace2, namespace3])) - .then(() => sanitizeDbEntities([namespace1, namespace2, namespace3])) - .then(() => dbFacade.activeNamespacesWithAlias( - aliasTypeAddress, - [ - address.stringToAddress(testAddress.one), - address.stringToAddress(testAddress.two), - address.stringToAddress(testAddress.three) - ] - )) - .then(entities => { expect(entities).to.deep.equal([{ ...namespace3, meta: { active: true, latest: true } }]); }) - .then(() => db.close()); - }); - }); - - describe('register namespace transactions by namespace ids', () => { - const transactionType = catapult.model.EntityType.registerNamespace; - const createRegisterNamespaceTransaction = (namespaceId, type, name) => ({ - transaction: { type, id: convertToLong(namespaceId), name } - }); - - it('returns register namespace transactions by namespace ids', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const registerNamespaceTransaction1 = createRegisterNamespaceTransaction(12345, transactionType, 'alias_1'); - const registerNamespaceTransaction2 = createRegisterNamespaceTransaction(67891, transactionType, 'alias_2'); - const registerNamespaceTransaction3 = createRegisterNamespaceTransaction(67891, 123, 'alias_2'); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection( - db, - 'transactions', - [ - registerNamespaceTransaction1, - registerNamespaceTransaction2, - registerNamespaceTransaction3 - ] - )) - .then(() => sanitizeDbEntities([ - registerNamespaceTransaction1, registerNamespaceTransaction2, registerNamespaceTransaction3 - ])) - .then(() => dbFacade.registerNamespaceTransactionsByNamespaceIds([convertToLong(12345), convertToLong(67891)])) - .then(entities => { expect(entities).to.deep.equal([registerNamespaceTransaction1, registerNamespaceTransaction2]); }) - .then(() => db.close()); - }); - - it('returns empty for no register namespace transactions with namespaceId', () => { - // Arrange: - const db = new CatapultDb({ networkId: testDbOptions.networkId }); - const dbFacade = new NamespaceDb(db); - const registerNamespaceTransaction1 = createRegisterNamespaceTransaction(12345, transactionType, 'alias_1'); - const registerNamespaceTransaction2 = createRegisterNamespaceTransaction(67891, transactionType, 'alias_2'); - - // Act + Assert: - return db.connect(testDbOptions.url, 'test') - .then(() => populateCollection( - db, - 'transactions', - [ - registerNamespaceTransaction1, - registerNamespaceTransaction2 - ] - )) - .then(() => sanitizeDbEntities([ - registerNamespaceTransaction1, registerNamespaceTransaction2 - ])) - .then(() => dbFacade.registerNamespaceTransactionsByNamespaceIds([convertToLong(12121)])) - .then(entities => { expect(entities).to.deep.equal([]); }) - .then(() => db.close()); - }); - }); -}); diff --git a/rest/test/plugins/namespace/namespaceDbTestUtils.js b/rest/test/plugins/namespace/namespaceDbTestUtils.js deleted file mode 100644 index 1e2bef3af..000000000 --- a/rest/test/plugins/namespace/namespaceDbTestUtils.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const NamespaceDb = require('../../../src/plugins/namespace/NamespaceDb'); -const dbTestUtils = require('../../db/utils/dbTestUtils'); -const test = require('../../testUtils'); -const MongoDb = require('mongodb'); - -const { Binary, Long } = MongoDb; - -const Namespace_Types = { root: 0, child: 1 }; - -const createAlias = id => { - switch (id % 3) { - case 1: return { type: 1, mosaicId: 1000 }; - case 2: return { type: 2, address: new Binary(dbTestUtils.random.address()) }; - default: return { type: 0 }; - } -}; - -const createNamespace = (id, owner, namespaceType, parentIdOrDuration, path, lifetime, latest, alias) => { - // namespace data - const namespace = { - ownerAddress: new Binary(owner.address), - startHeight: Long.fromNumber(lifetime.start), - endHeight: Long.fromNumber(lifetime.end), - depth: path.length, - level0: Long.fromNumber(path[0]), - type: namespaceType, - name: namespaceType === Namespace_Types.root ? `root${id}` : `child${id}`, - alias - }; - - if (1 < path.length) - namespace.level1 = Long.fromNumber(path[1]); - - if (2 < path.length) - namespace.level2 = Long.fromNumber(path[2]); - - if (namespaceType === Namespace_Types.root) - namespace.duration = Long.fromNumber(parentIdOrDuration); - else - namespace.parentId = Long.fromNumber(parentIdOrDuration); - - return { _id: dbTestUtils.db.createObjectId(id), meta: { latest }, namespace }; -}; - -const createNamespaces = (numRounds, owner, startdId = 0) => { - // the depth is determined by id % 3: - // 0: root - // 1: child of depth 1 - // 2: child of depth 2 - let id = startdId; - const namespaces = []; - - const push = (namespaceOwner, i, active) => { - const namespaceType = 0 === i % 3 ? Namespace_Types.root : Namespace_Types.child; - const lifetime = { start: 10 * i, end: 10 * (i + 1) }; - // use a 12300 base for namespace id, to distinguish from id inside the tests - let nsId = 12300 + i; - const path = [nsId]; - - while (0 !== nsId % 3) - path.unshift(--nsId); - - namespaces.push(createNamespace(id++, namespaceOwner, namespaceType, id, path, lifetime, active, createAlias(i))); - }; - - for (let i = 0; i < numRounds; ++i) - push(owner, i, true); - - for (let i = 0; i < numRounds; ++i) - push(owner, i, false); - - return namespaces; -}; - -const namespaceDbTestUtils = { - db: { - createNamespace, - createNamespaces, - runDbTest: (dbEntities, issueDbCommand, assertDbCommandResult) => - dbTestUtils.db.runDbTest(dbEntities, 'namespaces', db => new NamespaceDb(db), issueDbCommand, assertDbCommandResult) - } -}; -Object.assign(namespaceDbTestUtils, test); - -module.exports = namespaceDbTestUtils; diff --git a/rest/test/plugins/namespace/namespaceRoutes_spec.js b/rest/test/plugins/namespace/namespaceRoutes_spec.js deleted file mode 100644 index e757f7fdf..000000000 --- a/rest/test/plugins/namespace/namespaceRoutes_spec.js +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong } = require('../../../src/db/dbUtils'); -const namespaceRoutes = require('../../../src/plugins/namespace/namespaceRoutes'); -const namespaceUtils = require('../../../src/plugins/namespace/namespaceUtils'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { Binary } = MongoDb; -const { uint64 } = catapult.utils; -const { address } = catapult.model; - -describe('namespace routes', () => { - describe('namespaces', () => { - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: '5EBA7BE8DA85166BB0545CF7', - meta: { - active: true, - index: 0 - }, - namespace: { - registrationType: 0, - depth: 1, - level0: 'B1497F5FBA651B4F', - alias: { - type: 0 - }, - parentId: '0000000000000000', - ownerAddress: '9022D031CAFB3993B57FEE5ADC0BD4033A431FBFA1010BF51C', - startHeight: '1', - endHeight: '18446744073709551615' - } - }, - { - id: '5EBA7BE8DA85166BB0545CF8', - meta: { - active: true, - index: 0 - }, - namespace: { - registrationType: 1, - depth: 2, - level0: 'B1497F5FBA651B4F', - level1: '941299B2B7E1291C', - alias: { - type: 1, - mosaicId: '4291ED23000A037A' - }, - parentId: 'B1497F5FBA651B4F', - ownerAddress: '9022D031CAFB3993B57FEE5ADC0BD4033A431FBFA1010BF51C', - startHeight: '1', - endHeight: '18446744073709551615' - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbNamespacesFake = sinon.fake((aliasType, level0, ownerAddress, registrationType) => { - if (aliasType || ownerAddress || registrationType) - return Promise.resolve(emptyPageSample); - - return Promise.resolve(pageSample); - }); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { namespaces: dbNamespacesFake }; - namespaceRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbNamespacesFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/namespaces').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbNamespacesFake.calledOnce).to.equal(true); - expect(dbNamespacesFake.firstCall.args[4]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty page if no namespaces found', () => { - // Arrange: - const req = { params: { aliasType: '2' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbNamespacesFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'namespaceDescriptor', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards query without params if not provided', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbNamespacesFake.calledOnce).to.equal(true); - expect(dbNamespacesFake.firstCall.args[0]).to.deep.equal(undefined); - expect(dbNamespacesFake.firstCall.args[1]).to.deep.equal(undefined); - expect(dbNamespacesFake.firstCall.args[2]).to.deep.equal(undefined); - expect(dbNamespacesFake.firstCall.args[3]).to.deep.equal(undefined); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards aliasType', () => { - // Arrange: - const aliasType = 2; - const req = { params: { aliasType: aliasType.toString() } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbNamespacesFake.calledOnce).to.equal(true); - expect(dbNamespacesFake.firstCall.args[0]).to.equal(aliasType); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards level0', () => { - // Arrange: - const level0 = '85BBEA6CC462B244'; - const req = { params: { level0 } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbNamespacesFake.calledOnce).to.equal(true); - expect(dbNamespacesFake.firstCall.args[1]).to.deep.equal(uint64.fromHex(level0)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards ownerAddress', () => { - // Arrange: - const ownerAddress = 'SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'; - const req = { params: { ownerAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbNamespacesFake.calledOnce).to.equal(true); - expect(dbNamespacesFake.firstCall.args[2]).to.deep.equal(address.stringToAddress(ownerAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards registrationType', () => { - // Arrange: - const registrationType = 1; - const req = { params: { registrationType: registrationType.toString() } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbNamespacesFake.calledOnce).to.equal(true); - expect(dbNamespacesFake.firstCall.args[3]).to.equal(registrationType); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'namespaceDescriptor', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('throws error if aliasType is invalid', () => { - // Arrange: - const req = { params: { aliasType: 'ABC' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('aliasType has an invalid format'); - }); - - it('throws error if level0 is invalid', () => { - // Arrange: - const req = { params: { level0: '12345678' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('level0 has an invalid format'); - }); - - it('throws error if ownerAddress is invalid', () => { - // Arrange: - const req = { params: { ownerAddress: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('ownerAddress has an invalid format'); - }); - - it('throws error if registrationType is invalid', () => { - // Arrange: - const req = { params: { registrationType: 'ABC' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('registrationType has an invalid format'); - }); - }); - }); - - describe('get by id', () => { - const namespaceId = '1234567890ABCDEF'; - test.route.document.addGetDocumentRouteTests(namespaceRoutes.register, { - route: '/namespaces/:namespaceId', - inputs: { - valid: { object: { namespaceId }, parsed: [[0x90ABCDEF, 0x12345678]], printable: namespaceId }, - invalid: { - object: { namespaceId: '12345' }, - error: 'namespaceId has an invalid format' - } - }, - dbApiName: 'namespaceById', - type: 'namespaceDescriptor' - }); - }); - - describe('get namespace names by ids', () => { - const createParentId = parentId => ({ high_: 0, low_: parentId }); - - const createNamespace = (parentId, namespaceId) => ({ - // 1. in db, parentId is only stored for child namespaces - // 2. db returns null instead of undefined when a document property is not present - parentId: undefined === parentId ? null : createParentId(parentId), - id: [0, namespaceId] - }); - - const Valid_Hex_String_Namespace_Ids = ['1234567890ABCDEF', 'ABCDEF0123456789']; - const Valid_Uint64_Namespace_Ids = [[0x90ABCDEF, 0x12345678], [0x23456789, 0xABCDEF01]]; - - const runTest = options => { - // Arrange: - const dbParamTuples = []; - const db = (() => { - let level = 0; - return { - catapultDb: { - findNamesByIds: (ids, transactionType, fieldsDescriptor) => { - dbParamTuples.push({ ids, transactionType, fieldsDescriptor }); - return Promise.resolve(options.dbEntitiesGroupedByLevel[level++]); - } - } - }; - })(); - - // Act: - return test.route.executeSingle( - namespaceRoutes.register, - '/namespaces/names', - 'post', - { namespaceIds: Valid_Hex_String_Namespace_Ids }, - db, - undefined, - response => { - // Assert: parameters passed to db function are correct - let level = 0; - expect(dbParamTuples.length).to.equal(options.expectedNumDbQueries); - dbParamTuples.forEach(dbParamTuple => { - expect(dbParamTuple.ids).to.deep.equal(options.queryIdsGroupedByLevel[level++]); - expect(dbParamTuple.transactionType).to.deep.equal(catapult.model.EntityType.registerNamespace); - expect(dbParamTuple.fieldsDescriptor).to.deep.equal({ id: 'id', name: 'name', parentId: 'parentId' }); - }); - - // check response - let expectedPayload = []; - options.dbEntitiesGroupedByLevel.forEach(dbEntities => { - expectedPayload = expectedPayload.concat(dbEntities); - }); - - expect(response).to.deep.equal({ payload: expectedPayload, type: 'namespaceNameTuple' }); - } - ); - }; - - it('returns empty array if no names are found', () => runTest({ - queryIdsGroupedByLevel: [ - Valid_Uint64_Namespace_Ids - ], - dbEntitiesGroupedByLevel: [ - [] - ], - expectedNumDbQueries: 1 - })); - - it('returns namespace names if found', () => runTest({ - queryIdsGroupedByLevel: [ - Valid_Uint64_Namespace_Ids - ], - dbEntitiesGroupedByLevel: [ - [createNamespace(undefined, 9), createNamespace(undefined, 5), createNamespace(undefined, 7)] - ], - expectedNumDbQueries: 1 - })); - - it('returns level1 (one ancestor) namespace names if found', () => runTest({ - queryIdsGroupedByLevel: [ - Valid_Uint64_Namespace_Ids, - [createParentId(12), createParentId(0), createParentId(16)] - ], - dbEntitiesGroupedByLevel: [ - [createNamespace(undefined, 9), createNamespace(12, 5), createNamespace(0, 3), createNamespace(16, 7)], - [createNamespace(undefined, 12), createNamespace(undefined, 0), createNamespace(undefined, 16)] - ], - expectedNumDbQueries: 2 - })); - - it('returns level2 (two ancestor) namespace names if found', () => runTest({ - queryIdsGroupedByLevel: [ - Valid_Uint64_Namespace_Ids, - [createParentId(17), createParentId(12), createParentId(16)], - [createParentId(25), createParentId(25)] - ], - dbEntitiesGroupedByLevel: [ - [createNamespace(17, 9), createNamespace(12, 5), createNamespace(16, 7)], - [createNamespace(undefined, 12), createNamespace(25, 16), createNamespace(25, 17)], - [createNamespace(undefined, 25), createNamespace(undefined, 25)] - ], - expectedNumDbQueries: 3 - })); - }); - - describe('get mosaic names', () => { - describe('calls aliasNamesRoutesProcessor with correct params', () => { - it('is called once for each endpoint using it with correct parameters', () => { - // Arrange: - const aliasNamesRoutesProcessorSpy = sinon.spy(namespaceUtils, 'aliasNamesRoutesProcessor'); - const routes = {}; - const server = { - get: (path, handler) => { routes[path] = handler; }, - post: (path, handler) => { routes[path] = handler; } - }; - - // Act: - namespaceRoutes.register(server, {}, {}); - - // Assert: - expect(aliasNamesRoutesProcessorSpy.calledTwice).to.equal(true); - expect(aliasNamesRoutesProcessorSpy.firstCall.args[1]).to.equal(catapult.model.namespace.aliasType.mosaic); - expect(aliasNamesRoutesProcessorSpy.firstCall.args[4]).to.equal('mosaicId'); - expect(aliasNamesRoutesProcessorSpy.firstCall.args[5]).to.equal('mosaicNames'); - - aliasNamesRoutesProcessorSpy.restore(); - }); - - describe('getParams parses mosaic ids correctly', () => { - const aliasNamesRoutesProcessorSpy = sinon.spy(namespaceUtils, 'aliasNamesRoutesProcessor'); - const routes = {}; - const server = { - get: (path, handler) => { routes[path] = handler; }, - post: (path, handler) => { routes[path] = handler; } - }; - - namespaceRoutes.register(server, {}, {}); - const getParams = aliasNamesRoutesProcessorSpy.firstCall.args[2]; - aliasNamesRoutesProcessorSpy.restore(); - - it('parses mosaic ids correctly', () => { - // Arrange: - const req = { params: { mosaicIds: ['78A4895CB6653DE4', '56AB67FF45468988'] } }; - const parsedValues = [[0xB6653DE4, 0x78A4895C], [0x45468988, 0x56AB67FF]].map(convertToLong); - - // Act + Assert: - expect(getParams(req)).to.deep.equal(parsedValues); - }); - - it('parses empty mosaic ids list correctly', () => { - // Arrange: - const req = { params: { mosaicIds: [] } }; - - // Act + Assert: - expect(getParams(req)).to.deep.equal([]); - }); - - it('returns 409 if provided mosaic id is invalid', () => { - // Arrange: - const req = { params: { mosaicIds: ['78A4895CB6653DE4', '123XXX', '56AB67FF45468988'] } }; - - // Act + Assert: - expect(() => { getParams(req); }) - .to.throw('element in array mosaicIds has an invalid format'); - }); - }); - - describe('namespaceFilter filters namespaces correctly', () => { - const aliasNamesRoutesProcessorSpy = sinon.spy(namespaceUtils, 'aliasNamesRoutesProcessor'); - const routes = {}; - const server = { - get: (path, handler) => { routes[path] = handler; }, - post: (path, handler) => { routes[path] = handler; } - }; - - namespaceRoutes.register(server, {}, {}); - const namespaceFilter = aliasNamesRoutesProcessorSpy.firstCall.args[3]; - aliasNamesRoutesProcessorSpy.restore(); - - it('filters namespaces aliasing mosaicId correctly', () => { - // Arrange: - const id = 12345; - const namespace1 = { - namespace: { alias: { mosaicId: convertToLong(id) } } - }; - - // Act + Assert: - expect(namespaceFilter(namespace1, convertToLong(id))).to.equal(true); - expect(namespaceFilter(namespace1, convertToLong(id + 1))).to.equal(false); - }); - }); - }); - }); - - describe('get account names', () => { - describe('calls aliasNamesRoutesProcessor with correct params', () => { - const testAddress = { - one: 'SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ', - two: 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA' - }; - - it('is called once for each endpoint using it with correct parameters', () => { - // Arrange: - const aliasNamesRoutesProcessorSpy = sinon.spy(namespaceUtils, 'aliasNamesRoutesProcessor'); - const routes = {}; - const server = { - get: (path, handler) => { routes[path] = handler; }, - post: (path, handler) => { routes[path] = handler; } - }; - - // Act: - namespaceRoutes.register(server, {}); - - // Assert: - expect(aliasNamesRoutesProcessorSpy.calledTwice).to.equal(true); - expect(aliasNamesRoutesProcessorSpy.secondCall.args[1]).to.equal(catapult.model.namespace.aliasType.address); - expect(aliasNamesRoutesProcessorSpy.secondCall.args[4]).to.equal('address'); - expect(aliasNamesRoutesProcessorSpy.secondCall.args[5]).to.equal('accountNames'); - - aliasNamesRoutesProcessorSpy.restore(); - }); - - describe('getParams parses addresses correctly', () => { - const aliasNamesRoutesProcessorSpy = sinon.spy(namespaceUtils, 'aliasNamesRoutesProcessor'); - const routes = {}; - const server = { - get: (path, handler) => { routes[path] = handler; }, - post: (path, handler) => { routes[path] = handler; } - }; - - namespaceRoutes.register(server, {}); - const getParams = aliasNamesRoutesProcessorSpy.secondCall.args[2]; - aliasNamesRoutesProcessorSpy.restore(); - - it('parses addresses correctly', () => { - // Arrange: - const req = { params: { addresses: [testAddress.one, testAddress.two] } }; - - // Act + Assert: - expect(getParams(req)).to.deep.equal([ - address.stringToAddress(testAddress.one), - address.stringToAddress(testAddress.two) - ]); - }); - - it('parses empty addresses list correctly', () => { - // Arrange: - const req = { params: { addresses: [] } }; - - // Act + Assert: - expect(getParams(req)).to.deep.equal([]); - }); - - it('returns 409 if addresses are invalid', () => { - // Arrange: - const req = { params: { addresses: [testAddress.one, '12345ABCDE'] } }; - - // Act + Assert: - expect(() => { getParams(req); }) - .to.throw('element in array addresses has an invalid format'); - }); - }); - - describe('namespaceFilter filters namespaces correctly', () => { - const aliasNamesRoutesProcessorSpy = sinon.spy(namespaceUtils, 'aliasNamesRoutesProcessor'); - const routes = {}; - const server = { - get: (path, handler) => { routes[path] = handler; }, - post: (path, handler) => { routes[path] = handler; } - }; - - namespaceRoutes.register(server, {}); - const namespaceFilter = aliasNamesRoutesProcessorSpy.secondCall.args[3]; - aliasNamesRoutesProcessorSpy.restore(); - - it('filters namespaces aliasing addresses correctly', () => { - // Arrange: - const id = address.stringToAddress(testAddress.one); - const namespace1 = { - namespace: { alias: { address: new Binary(Buffer.from(id)) } } - }; - const namespace2 = { - namespace: { alias: { address: new Binary(Buffer.from(id)) } } - }; - - // Act + Assert: - expect(namespaceFilter(namespace1, address.stringToAddress(testAddress.one))).to.equal(true); - expect(namespaceFilter(namespace2, address.stringToAddress(testAddress.two))).to.equal(false); - }); - }); - }); - }); -}); diff --git a/rest/test/plugins/namespace/namespaceUtils_spec.js b/rest/test/plugins/namespace/namespaceUtils_spec.js deleted file mode 100644 index edcff4b88..000000000 --- a/rest/test/plugins/namespace/namespaceUtils_spec.js +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { convertToLong } = require('../../../src/db/dbUtils'); -const namespaceUtils = require('../../../src/plugins/namespace/namespaceUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { aliasNamesRoutesProcessor } = namespaceUtils; - -describe('namespace utils', () => { - describe('aliasNamesRoutesProcessor', () => { - const createNamespace = (level0, level1, level2, depth) => ({ - namespace: { - depth, - level0: convertToLong(level0), - level1: convertToLong(level1), - level2: convertToLong(level2) - } - }); - const activeNamespacesWithAliasFake = sinon.fake(() => { - const namespaces = [ - createNamespace(12345, 0, 0, 1), - createNamespace(67891, 38467, 0, 2), - createNamespace(23456, 89876, 33437, 3), - createNamespace(88448, 10001, 99999, 1) - ]; - return Promise.resolve(namespaces); - }); - - const createRegisterNamespaceTransaction = (namespaceId, height, index, name) => ({ - meta: { - height: convertToLong(height), - index - }, - transaction: { - type: catapult.model.EntityType.registerNamespace, - id: convertToLong(namespaceId), - name: { value: () => name } - } - }); - const registerNamespaceTransactionsFromNamespaceIdsFake = sinon.fake(() => { - const transactions = [ - createRegisterNamespaceTransaction(12345, 1, 1, 'a'), - createRegisterNamespaceTransaction(33437, 1, 1, 'a'), - createRegisterNamespaceTransaction(12345, 1, 1, 'a'), - createRegisterNamespaceTransaction(67891, 1, 1, 'b'), - createRegisterNamespaceTransaction(38467, 1, 1, 'c'), - createRegisterNamespaceTransaction(23456, 1, 1, 'd'), - createRegisterNamespaceTransaction(89876, 1, 1, 'e'), - createRegisterNamespaceTransaction(33437, 1, 1, 'f'), - createRegisterNamespaceTransaction(33437, 2, 2, 'g'), - createRegisterNamespaceTransaction(33437, 2, 1, 'h') - ]; - return Promise.resolve(transactions); - }); - - const sendFake = sinon.fake(); - const nextFake = sinon.fake(); - - const db = { - activeNamespacesWithAlias: activeNamespacesWithAliasFake, - registerNamespaceTransactionsByNamespaceIds: registerNamespaceTransactionsFromNamespaceIdsFake - }; - - const aliasType = 1; - const getParamsFake = sinon.fake(() => [1, 2]); - const namespaceFilterFake = sinon.fake(() => true); - const fieldName = 'testAliasFieldName'; - const schemaName = 'testSchemaName'; - const processorFunction = aliasNamesRoutesProcessor( - db, - aliasType, - getParamsFake, - namespaceFilterFake, - fieldName, - schemaName - ); - - beforeEach(() => { - sendFake.resetHistory(); - nextFake.resetHistory(); - activeNamespacesWithAliasFake.resetHistory(); - registerNamespaceTransactionsFromNamespaceIdsFake.resetHistory(); - getParamsFake.resetHistory(); - namespaceFilterFake.resetHistory(); - }); - - it('calls activeNamespacesWithAlias', () => { - // Arrange: - const req = {}; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(activeNamespacesWithAliasFake.calledOnce).to.equal(true); - - expect(activeNamespacesWithAliasFake.firstCall.args[0]).to.equal(aliasType); - - expect(activeNamespacesWithAliasFake.firstCall.args[1]).to.deep.equal([1, 2]); - }); - }); - - it('calls registerNamespaceTransactionsByNamespaceIds', () => { - // Arrange: - const req = {}; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(registerNamespaceTransactionsFromNamespaceIdsFake.calledOnce).to.equal(true); - - expect(registerNamespaceTransactionsFromNamespaceIdsFake.firstCall.args[0]) - .to.deep.equal([12345, 67891, 38467, 23456, 89876, 33437, 88448].map(convertToLong)); - }); - }); - - it('calls get params', () => { - // Arrange: - const req = { params: { ids: [1, 2, 3] } }; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(getParamsFake.calledOnce).to.equal(true); - - expect(getParamsFake.firstCall.args[0]).to.deep.equal(req); - }); - }); - - it('returns alias names', () => { - // Arrange: - const req = {}; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(sendFake.firstCall.args[0]).to.deep.equal({ - payload: { - testSchemaName: [ - { - [fieldName]: 1, - names: [ - 'a', - 'b.c', - 'd.e.g' - ] - }, - { - [fieldName]: 2, - names: [ - 'a', - 'b.c', - 'd.e.g' - ] - } - ] - }, - type: schemaName - }); - - expect(nextFake.calledOnce).to.equal(true); - }); - }); - }); -}); diff --git a/rest/test/plugins/namespace/namespace_spec.js b/rest/test/plugins/namespace/namespace_spec.js deleted file mode 100644 index c7da02d40..000000000 --- a/rest/test/plugins/namespace/namespace_spec.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const NamespaceDb = require('../../../src/plugins/namespace/NamespaceDb'); -const namespace = require('../../../src/plugins/namespace/namespace'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('namespace plugin', () => { - pluginTest.assertThat.pluginCreatesDb(namespace, NamespaceDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(namespace); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(namespace); - - describe('register routes', () => { - it('registers GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - namespace.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/namespaces', - '/namespaces/:namespaceId', - '/namespaces/:namespaceId/merkle' - ]); - }); - - it('registers POST routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - namespace.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/namespaces/names', - '/namespaces/mosaic/names', - '/namespaces/account/names' - ]); - }); - }); -}); diff --git a/rest/test/plugins/receipts/ReceiptsDb_spec.js b/rest/test/plugins/receipts/ReceiptsDb_spec.js deleted file mode 100644 index 7376de890..000000000 --- a/rest/test/plugins/receipts/ReceiptsDb_spec.js +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const CatapultDb = require('../../../src/db/CatapultDb'); -const { convertToLong, uniqueLongList } = require('../../../src/db/dbUtils'); -const ReceiptsDb = require('../../../src/plugins/receipts/ReceiptsDb'); -const test = require('../../db/utils/dbTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { Binary, Long } = MongoDb; -const { address } = catapult.model; -const { uint64 } = catapult.utils; - -describe('receipts db', () => { - const { createObjectId } = test.db; - - const testAddress1 = address.stringToAddress('SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'); - const testAddress2 = address.stringToAddress('NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const runReceiptsDbTest = async (dbEntities, collection, issueDbCommand, assertDbCommandResult) => { - const blockHeights = uniqueLongList(dbEntities.map(data => data.statement.height)); - const dbBlocks = blockHeights.map(blockHeight => - test.db.createDbBlock(parseInt(blockHeight.toString(), 10))); - await test.db.insertEntities(dbBlocks, 'blocks'); - return test.db.runDbTest(dbEntities, collection, db => new ReceiptsDb(db), issueDbCommand, assertDbCommandResult); - }; - - const runTestAndVerifyIds = (dbReceipts, collectionName, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - return runReceiptsDbTest( - dbReceipts, - collectionName, - dbQuery, - receiptsPage => { - const returnedIds = receiptsPage.data.map(t => t.id); - expect(receiptsPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - describe('transactionStatements', () => { - const collectionName = 'transactionStatements'; - - const createTransactionStatement = (objectId, height, receipts) => ({ - _id: createObjectId(objectId), - statement: { - height: Long.fromNumber(height), - source: { primaryId: 0, secondaryId: 0 }, - receipts - } - }); - - const createReceipt = fields => ({ - version: 1, - type: fields.type, - recipientAddress: fields.recipientAddress ? Buffer.from(fields.recipientAddress) : undefined, - senderAddress: fields.senderAddress ? Buffer.from(fields.senderAddress) : undefined, - targetAddress: fields.targetAddress ? Buffer.from(fields.targetAddress) : undefined, - namespaceId: fields.namespaceId ? convertToLong(fields.namespaceId) : undefined, - mosaicId: fields.mosaicId ? convertToLong(fields.mosaicId) : undefined - }); - - it('returns expected structure', () => { - // Arrange: - const sampleReceipt = createReceipt({ type: 1 }); - const dbReceipts = [createTransactionStatement(10, 100, [sampleReceipt])]; - const filters = {}; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - page => { - const expected_keys = ['id', 'meta', 'statement']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - expect(Object.keys(sampleReceipt).sort()).to.deep.equal( - Object.keys(page.data[0].statement.receipts[0]).sort() - ); - } - ); - }); - - it('returns empty array for empty height', () => { - // Arrange: - const dbReceipts = [createTransactionStatement(10, 100)]; - const filters = { height: 20 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [] - ); - }); - - it('returns all the receipts if no filters are provided', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100), - createTransactionStatement(20, 101), - createTransactionStatement(30, 102) - ]; - const filters = {}; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [10, 20, 30] - ); - }); - - describe('all the provided filters are taken into account', () => { - it('height', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100), - createTransactionStatement(20, 110), - createTransactionStatement(30, 120) - ]; - const filters = { height: 110 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [20] - ); - }); - - it('receiptType', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100, [createReceipt({ type: 1 }), createReceipt({ type: 2 })]), - createTransactionStatement(20, 110, [createReceipt({ type: 2 }), createReceipt({ type: 3 })]), - createTransactionStatement(30, 120, [createReceipt({ type: 4 }), createReceipt({ type: 4 })]), - createTransactionStatement(40, 120, [createReceipt({ type: 5 })]), - createTransactionStatement(50, 130, []) - ]; - const filters = { receiptType: [2, 5] }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [10, 20, 40] - ); - }); - - it('recipientAddress', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100, [createReceipt({ recipientAddress: testAddress1 })]), - createTransactionStatement(20, 110, [ - createReceipt({ recipientAddress: testAddress1 }), - createReceipt({ recipientAddress: testAddress2 }) - ]), - createTransactionStatement(30, 120, [createReceipt({ recipientAddress: testAddress2 })]), - createTransactionStatement(40, 130, []) - ]; - const filters = { recipientAddress: testAddress2 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [20, 30] - ); - }); - - it('senderAddress', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100, [createReceipt({ senderAddress: testAddress1 })]), - createTransactionStatement(20, 110, [ - createReceipt({ senderAddress: testAddress1 }), - createReceipt({ senderAddress: testAddress2 }) - ]), - createTransactionStatement(30, 120, [createReceipt({ senderAddress: testAddress2 })]), - createTransactionStatement(40, 130, []) - ]; - const filters = { senderAddress: testAddress2 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [20, 30] - ); - }); - - it('targetAddress', () => { - // Arrange: - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100, [createReceipt({ targetAddress: testAddress1 })]), - createTransactionStatement(20, 110, [ - createReceipt({ targetAddress: testAddress1 }), - createReceipt({ targetAddress: testAddress2 }) - ]), - createTransactionStatement(30, 120, [createReceipt({ targetAddress: testAddress2 })]), - createTransactionStatement(40, 130, []) - ]; - const filters = { targetAddress: testAddress2 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [20, 30] - ); - }); - - describe('artifactId', () => { - // NamespaceIds examples: 941299B2B7E1291C, 85BBEA6CC462B244, CB9F84B545BA480C - // MosaicIds examples: 1D9CDC7E218CA88D, 24F426B8D5493D4B, 49F6C0F0163730A9 - - const namespaceId1 = uint64.fromHex('941299B2B7E1291C'); - const namespaceId2 = uint64.fromHex('85BBEA6CC462B244'); - const mosaicId1 = uint64.fromHex('1D9CDC7E218CA88D'); - const mosaicId2 = uint64.fromHex('24F426B8D5493D4B'); - - it('namespaceId', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100, [createReceipt({ namespaceId: namespaceId1, mosaicId: namespaceId2 })]), - createTransactionStatement(20, 110, [ - createReceipt({ namespaceId: namespaceId1 }), - createReceipt({ namespaceId: namespaceId2 }) - ]), - createTransactionStatement(30, 120, [createReceipt({ namespaceId: namespaceId2 })]), - createTransactionStatement(40, 130, []) - ]; - const filters = { artifactId: namespaceId2 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [20, 30] - ); - }); - - it('mosaicId', () => { - // Arrange: - const dbReceipts = [ - createTransactionStatement(10, 100, [createReceipt({ namespaceId: mosaicId2, mosaicId: mosaicId1 })]), - createTransactionStatement(20, 110, [ - createReceipt({ mosaicId: mosaicId1 }), - createReceipt({ mosaicId: mosaicId2 }) - ]), - createTransactionStatement(30, 120, [createReceipt({ mosaicId: mosaicId2 })]), - createTransactionStatement(40, 130, []) - ]; - const filters = { artifactId: mosaicId2 }; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.transactionStatements(filters, paginationOptions), - [20, 30] - ); - }); - }); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbReceipts = () => ([ - createTransactionStatement(10, 30), - createTransactionStatement(20, 20), - createTransactionStatement(30, 10) - ]); - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts(), - collectionName, - db => db.transactionStatements({}, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts(), - collectionName, - db => db.transactionStatements({}, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts(), - collectionName, - db => db.transactionStatements({}, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbReceipts = () => ([ - createTransactionStatement(10, 30), - createTransactionStatement(20, 20), - createTransactionStatement(30, 10) - ]); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds(dbReceipts(), collectionName, db => db.transactionStatements({}, options), [30]); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds(dbReceipts(), collectionName, db => db.transactionStatements({}, options), [10]); - }); - }); - }); - - describe('artifactStatements', () => { - const artifactTypes = [ - { - type: 'address', - createResolutionStatement: (objectId, height) => ({ - _id: createObjectId(objectId), - statement: { - height: Long.fromNumber(height), - unresolved: new Binary(Buffer.from(testAddress1)), - resolutionEntries: [] - } - }) - }, - { - type: 'mosaic', - createResolutionStatement: (objectId, height) => ({ - _id: createObjectId(objectId), - statement: { height: Long.fromNumber(height), unresolved: Long.fromNumber(5432), resolutionEntries: [] } - }) - } - ]; - - artifactTypes.forEach(artifact => { - const collectionName = `${artifact.type}ResolutionStatements`; - - describe(`${artifact.type}ResolutionStatements`, () => { - it('returns expected structure', () => { - // Arrange: - const sampleResolutionStatement = artifact.createResolutionStatement(10, 100); - const dbReceipts = [sampleResolutionStatement]; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts, - collectionName, - db => db.artifactStatements(100, artifact.type, paginationOptions), - page => { - const expected_keys = ['id', 'meta', 'statement']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - expect(page.data[0].statement).to.deep.equal(sampleResolutionStatement.statement); - expect(page.data[0].meta).to.deep.equal({ timestamp: convertToLong(23456) }); - } - ); - }); - - it('returns empty array for empty height', () => { - // Arrange: - const dbReceipts = [artifact.createResolutionStatement(10, 100)]; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.artifactStatements(200, artifact.type, paginationOptions), - [] - ); - }); - - it('returns all the statements if no height is provided', () => { - // Arrange: - const dbReceipts = [ - artifact.createResolutionStatement(10, 100), - artifact.createResolutionStatement(20, 110), - artifact.createResolutionStatement(30, 120) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.artifactStatements(undefined, artifact.type, paginationOptions), - [10, 20, 30] - ); - }); - - it('returns filtered statements by height', () => { - // Arrange: - const dbReceipts = [ - artifact.createResolutionStatement(10, 100), - artifact.createResolutionStatement(20, 110), - artifact.createResolutionStatement(30, 120) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts, - collectionName, - db => db.artifactStatements(110, artifact.type, paginationOptions), - [20] - ); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbReceipts = () => ([ - artifact.createResolutionStatement(10, 30), - artifact.createResolutionStatement(20, 20), - artifact.createResolutionStatement(30, 10) - ]); - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts(), - collectionName, - db => db.artifactStatements(undefined, artifact.type, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts(), - collectionName, - db => db.artifactStatements(undefined, artifact.type, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runReceiptsDbTest( - dbReceipts(), - collectionName, - db => db.artifactStatements(undefined, artifact.type, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbReceipts = () => ([ - artifact.createResolutionStatement(10, 30), - artifact.createResolutionStatement(20, 20), - artifact.createResolutionStatement(30, 10) - ]); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts(), - collectionName, - db => db.artifactStatements(undefined, artifact.type, options), - [30] - ); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds( - dbReceipts(), - collectionName, - db => db.artifactStatements(undefined, artifact.type, options), - [10] - ); - }); - }); - }); - }); - }); -}); diff --git a/rest/test/plugins/receipts/receiptsRoutes_spec.js b/rest/test/plugins/receipts/receiptsRoutes_spec.js deleted file mode 100644 index 666cc1988..000000000 --- a/rest/test/plugins/receipts/receiptsRoutes_spec.js +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const receiptsRoutes = require('../../../src/plugins/receipts/receiptsRoutes'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; - -describe('receipts routes', () => { - describe('transaction statements', () => { - const testAddress = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: '', - statement: { - height: '', - source: { - primaryId: 0, - secondaryId: 0 - }, - receipts: [ - { - version: 1, - type: 8515, - targetAddress: '', - mosaicId: '', - amount: '' - }, - { - version: 1, - type: 8515, - targetAddress: '', - mosaicId: '', - amount: '' - }, - { - version: 1, - type: 20803, - mosaicId: '', - amount: '' - } - ] - } - }, - { - id: '', - statement: { - height: '', - source: { - primaryId: 0, - secondaryId: 0 - }, - receipts: [ - { - version: 1, - type: 8515, - targetAddress: '', - mosaicId: '', - amount: '' - }, - { - version: 1, - type: 8515, - targetAddress: '', - mosaicId: '', - amount: '' - }, - { - version: 1, - type: 20803, - mosaicId: '', - amount: '' - } - ] - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbTransactionStatementsFake = sinon.fake(filters => { - if (filters.height && 666 === filters.height[0]) - return Promise.resolve(emptyPageSample); - - return Promise.resolve(pageSample); - }); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { transactionStatements: dbTransactionStatementsFake }; - receiptsRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbTransactionStatementsFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/statements/transaction').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[1]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty page if no statements found', () => { - // Arrange: - const req = { params: { height: '666' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'transactionStatement', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards height', () => { - // Arrange: - const req = { params: { height: '123' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].height).to.deep.equal([123, 0]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards fromHeight', () => { - // Arrange: - const req = { params: { fromHeight: '123' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].fromHeight).to.deep.equal([123, 0]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards toHeight', () => { - // Arrange: - const req = { params: { toHeight: '123' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].toHeight).to.deep.equal([123, 0]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - describe('forwards receiptType', () => { - it('one element', () => { - // Arrange: - const req = { params: { receiptType: '456' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].receiptType).to.deep.equal([456]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('multiple elements', () => { - // Arrange: - const req = { params: { receiptType: ['456', '457'] } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].receiptType).to.deep.equal([456, 457]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - - it('forwards recipientAddress', () => { - // Arrange: - const req = { params: { recipientAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].recipientAddress) - .to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards senderAddress', () => { - // Arrange: - const req = { params: { senderAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].senderAddress).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards targetAddress', () => { - // Arrange: - const req = { params: { targetAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].targetAddress).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards artifactId', () => { - // Arrange: - const req = { params: { artifactId: '0DC67FBE1CAD29E3' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - expect(dbTransactionStatementsFake.firstCall.args[0].artifactId).to.deep.equal([0x1CAD29E3, 0x0DC67FBE]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with statement results', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionStatementsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'transactionStatement', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - }); - - describe('artifact resolution statements', () => { - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: '', - statement: { - height: '', - unresolved: '', - resolutionEntries: [ - { - source: { - primaryId: 2, - secondaryId: 0 - }, - resolved: '' - } - ] - } - }, - { - id: '', - statement: { - height: '', - unresolved: '', - resolutionEntries: [ - { - source: { - primaryId: 2, - secondaryId: 0 - }, - resolved: '' - } - ] - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbArtifactStatementsFake = sinon.fake(height => { - if (height && 666 === height[0]) - return Promise.resolve(emptyPageSample); - - return Promise.resolve(pageSample); - }); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { artifactStatements: dbArtifactStatementsFake }; - receiptsRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbArtifactStatementsFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/statements/resolutions/:artifact').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: { artifact: 'address' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - expect(dbArtifactStatementsFake.firstCall.args[2]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: { artifact: 'address' } }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty address statements page if no statements found', () => { - // Arrange: - const req = { params: { artifact: 'address', height: '666' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'addressResolutionStatement', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns empty mosaic statements page if no statements found', () => { - // Arrange: - const req = { params: { artifact: 'mosaic', height: '666' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: 'mosaicResolutionStatement', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards height', () => { - // Arrange: - const req = { params: { artifact: 'address', height: '123' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - expect(dbArtifactStatementsFake.firstCall.args[0]).to.deep.equal([123, 0]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards address artifact', () => { - // Arrange: - const req = { params: { artifact: 'address' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - expect(dbArtifactStatementsFake.firstCall.args[1]).to.equal('address'); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards mosaic artifact', () => { - // Arrange: - const req = { params: { artifact: 'mosaic' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - expect(dbArtifactStatementsFake.firstCall.args[1]).to.equal('mosaic'); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('fails for invalid artifact', () => { - // Arrange: - const req = { params: { artifact: 'namespace' } }; - - // Act: - mockServer.callRoute(route, req); - - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - - it('fails if no artifact provided', () => { - // Arrange: - const req = { params: {} }; - - // Act: - mockServer.callRoute(route, req); - - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: { artifact: 'address' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbArtifactStatementsFake.calledOnce).to.equal(true); - expect(dbArtifactStatementsFake.firstCall.args[0]).to.deep.equal(undefined); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: 'addressResolutionStatement', - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - }); - - describe('get receipts merkle path', () => { - it('calls blockRouteMerkleProcessor with correct params', () => { - // Arrange: - const mockServer = new MockServer(); - const blockRouteMerkleProcessorSpy = sinon.spy(routeUtils, 'blockRouteMerkleProcessor'); - - // Act: - receiptsRoutes.register(mockServer.server, {}, {}); - - // Assert: - expect(blockRouteMerkleProcessorSpy.calledOnce).to.equal(true); - expect(blockRouteMerkleProcessorSpy.firstCall.args[1]).to.equal('statementsCount'); - expect(blockRouteMerkleProcessorSpy.firstCall.args[2]).to.equal('statementMerkleTree'); - blockRouteMerkleProcessorSpy.restore(); - }); - }); -}); diff --git a/rest/test/plugins/receipts/receipts_spec.js b/rest/test/plugins/receipts/receipts_spec.js deleted file mode 100644 index 074fcfff2..000000000 --- a/rest/test/plugins/receipts/receipts_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const ReceiptsDb = require('../../../src/plugins/receipts/ReceiptsDb'); -const receipts = require('../../../src/plugins/receipts/receipts'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('receipts plugin', () => { - pluginTest.assertThat.pluginCreatesDb(receipts, ReceiptsDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(receipts); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(receipts); - - describe('register routes', () => { - it('registers receipts GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - receipts.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/statements/transaction', - '/statements/resolutions/:artifact', - '/blocks/:height/statements/:hash/merkle' - ]); - }); - }); -}); diff --git a/rest/test/plugins/restrictions/RestrictionsDb_spec.js b/rest/test/plugins/restrictions/RestrictionsDb_spec.js deleted file mode 100644 index f6422fdff..000000000 --- a/rest/test/plugins/restrictions/RestrictionsDb_spec.js +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const test = require('./restrictionsDbTestUtils'); -const CatapultDb = require('../../../src/db/CatapultDb'); -const { convertToLong } = require('../../../src/db/dbUtils'); -const RestrictionsDb = require('../../../src/plugins/restrictions/RestrictionsDb'); -const dbTestUtils = require('../../db/utils/dbTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -describe('restrictions db', () => { - describe('account restrictions', () => { - const removeMongoId = entity => { - delete entity.meta.id; - return entity; - }; - - it('returns undefined for unknown account', () => { - // Arrange: - const { address } = test.random.account(); - const accountRestrictions1 = test.accountDb.createAccountRestrictions( - address, { numAddresses: 3, numMosaics: 3, numOperations: 3 } - ); - - // Assert: - return test.accountDb.runDbTest( - accountRestrictions1, - db => db.accountRestrictionsByAddresses([[123, 456]]), - entities => { expect(entities).to.deep.equal([]); } - ); - }); - - it('returns found empty account restrictions for single account', () => { - // Arrange: - const { address } = test.random.account(); - const randomAddress1 = test.random.account().address; - const randomAddress2 = test.random.account().address; - const accountRestrictions1 = test.accountDb.createAccountRestrictions( - randomAddress1, - { numAddresses: 0, numMosaics: 0, numOperations: 0 } - ); - const accountRestrictions2 = test.accountDb.createAccountRestrictions( - address, - { numAddresses: 0, numMosaics: 0, numOperations: 0 } - ); - const accountRestrictions3 = test.accountDb.createAccountRestrictions( - randomAddress2, - { numAddresses: 0, numMosaics: 0, numOperations: 0 } - ); - - // Assert: - return test.accountDb.runDbTest( - [accountRestrictions1, accountRestrictions2, accountRestrictions3], - db => db.accountRestrictionsByAddresses([address]), - entities => { expect(entities).to.deep.equal([removeMongoId(accountRestrictions2)]); } - ); - }); - - it('returns found populated account restrictions for single account', () => { - // Arrange: - const { address } = test.random.account(); - const randomAddress1 = test.random.account().address; - const randomAddress2 = test.random.account().address; - const accountRestrictions1 = test.accountDb.createAccountRestrictions( - randomAddress1, - { numAddresses: 3, numMosaics: 6, numOperations: 2 } - ); - const accountRestrictions2 = test.accountDb.createAccountRestrictions( - address, - { numAddresses: 3, numMosaics: 6, numOperations: 2 } - ); - const accountRestrictions3 = test.accountDb.createAccountRestrictions( - randomAddress2, - { numAddresses: 3, numMosaics: 6, numOperations: 2 } - ); - - // Assert: - return test.accountDb.runDbTest( - [accountRestrictions1, accountRestrictions2, accountRestrictions3], - db => db.accountRestrictionsByAddresses([address]), - entities => { expect(entities[0]).to.deep.equal(removeMongoId(accountRestrictions2)); } - ); - }); - - it('returns found populated account restrictions for multiple accounts', () => { - // Arrange: - const { address } = test.random.account(); - const randomAddress1 = test.random.account().address; - const accountRestrictions1 = test.accountDb.createAccountRestrictions( - address, - { numAddresses: 3, numMosaics: 6, numOperations: 2 } - ); - const accountRestrictions2 = test.accountDb.createAccountRestrictions( - randomAddress1, - { numAddresses: 3, numMosaics: 6, numOperations: 2 } - ); - const accountRestrictions3 = test.accountDb.createAccountRestrictions( - address, - { numAddresses: 1, numMosaics: 4, numOperations: 3 } - ); - - // Assert: - return test.accountDb.runDbTest( - [accountRestrictions1, accountRestrictions2, accountRestrictions3], - db => db.accountRestrictionsByAddresses([address]), - entities => { expect(entities).to.deep.equal([removeMongoId(accountRestrictions1), removeMongoId(accountRestrictions3)]); } - ); - }); - }); - - describe('mosaic restrictions', () => { - const { address } = catapult.model; - const { createObjectId } = dbTestUtils.db; - const testAddress1 = address.stringToAddress('SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'); - const testAddress2 = address.stringToAddress('NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'); - - const paginationOptions = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - const createMosaicRestriction = (objectId, mosaicId, entryType, targetAddress) => ({ - _id: createObjectId(objectId), - mosaicRestrictionEntry: { - compositeHash: '', - entryType, - mosaicId: mosaicId ? convertToLong(mosaicId) : undefined, - targetAddress: targetAddress ? Buffer.from(targetAddress) : undefined, - restrictions: [] - } - }); - - const runMosaicRestrictionsDbTest = (dbEntities, issueDbCommand, assertDbCommandResult) => - dbTestUtils.db.runDbTest(dbEntities, 'mosaicRestrictions', db => new RestrictionsDb(db), issueDbCommand, assertDbCommandResult); - - const runTestAndVerifyIds = (dbRestrictions, dbQuery, expectedIds) => { - const expectedObjectIds = expectedIds.map(id => createObjectId(id)); - - return runMosaicRestrictionsDbTest( - dbRestrictions, - dbQuery, - mosaicRestrictionsPage => { - const returnedIds = mosaicRestrictionsPage.data.map(t => t.id); - expect(mosaicRestrictionsPage.data.length).to.equal(expectedObjectIds.length); - expect(returnedIds.sort()).to.deep.equal(expectedObjectIds.sort()); - } - ); - }; - - it('returns expected structure', () => { - // Arrange: - const dbMosaicRestrictions = [createMosaicRestriction(10)]; - - // Act + Assert: - return runMosaicRestrictionsDbTest( - dbMosaicRestrictions, - db => db.mosaicRestrictions(undefined, undefined, undefined, paginationOptions), - page => { - const expected_keys = ['id', 'mosaicRestrictionEntry']; - expect(Object.keys(page.data[0]).sort()).to.deep.equal(expected_keys.sort()); - } - ); - }); - - it('returns filtered mosaic restrictions by mosaicId', () => { - // Arrange: - const dbMosaicRestrictions = [ - createMosaicRestriction(10, [0xAAAD29AA, 0xAAC67FAA]), - createMosaicRestriction(20, [0x1CAD29E3, 0x0DC67FBE]) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMosaicRestrictions, - db => db.mosaicRestrictions([0xAAAD29AA, 0xAAC67FAA], undefined, undefined, paginationOptions), [10] - ); - }); - - it('returns filtered mosaic restrictions by entry type', () => { - // Arrange: - const dbMosaicRestrictions = [ - createMosaicRestriction(10, undefined, 0), - createMosaicRestriction(20, undefined, 1) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMosaicRestrictions, - db => db.mosaicRestrictions(undefined, 0, undefined, paginationOptions), [10] - ); - }); - - it('returns filtered mosaic restrictions by targetAddress', () => { - // Arrange: - const dbMosaicRestrictions = [ - createMosaicRestriction(10, undefined, undefined, testAddress1), - createMosaicRestriction(20, undefined, undefined, testAddress2) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMosaicRestrictions, - db => db.mosaicRestrictions(undefined, undefined, testAddress2, paginationOptions), [20] - ); - }); - - it('returns all mosaic restrictions if no filters provided', () => { - // Arrange: - const dbMosaicRestrictions = [ - createMosaicRestriction(10), - createMosaicRestriction(20), - createMosaicRestriction(30) - ]; - - // Act + Assert: - return runTestAndVerifyIds( - dbMosaicRestrictions, - db => db.mosaicRestrictions(undefined, undefined, undefined, paginationOptions), [10, 20, 30] - ); - }); - - describe('respects sort conditions', () => { - // Arrange: - const dbMosaicRestrictions = () => [ - createMosaicRestriction(10), - createMosaicRestriction(20), - createMosaicRestriction(30) - ]; - - it('direction ascending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runMosaicRestrictionsDbTest( - dbMosaicRestrictions(), - db => db.mosaicRestrictions(undefined, undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(10)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(30)); - } - ); - }); - - it('direction descending', () => { - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: -1 - }; - - // Act + Assert: - return runMosaicRestrictionsDbTest( - dbMosaicRestrictions(), - db => db.mosaicRestrictions(undefined, undefined, undefined, options), - page => { - expect(page.data[0].id).to.deep.equal(createObjectId(30)); - expect(page.data[1].id).to.deep.equal(createObjectId(20)); - expect(page.data[2].id).to.deep.equal(createObjectId(10)); - } - ); - }); - - it('sort field', () => { - const queryPagedDocumentsSpy = sinon.spy(CatapultDb.prototype, 'queryPagedDocuments'); - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }; - - // Act + Assert: - return runMosaicRestrictionsDbTest( - dbMosaicRestrictions(), - db => db.mosaicRestrictions(undefined, undefined, undefined, options), - () => { - expect(queryPagedDocumentsSpy.calledOnce).to.equal(true); - expect(Object.keys(queryPagedDocumentsSpy.firstCall.args[2])[0]).to.equal('_id'); - queryPagedDocumentsSpy.restore(); - } - ); - }); - }); - - describe('respects offset', () => { - // Arrange: - const dbMosaicRestrictions = () => [ - createMosaicRestriction(10), - createMosaicRestriction(20), - createMosaicRestriction(30) - ]; - const options = { - pageSize: 10, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset: createObjectId(20) - }; - - it('gt', () => { - options.sortDirection = 1; - - // Act + Assert: - return runTestAndVerifyIds( - dbMosaicRestrictions(), db => db.mosaicRestrictions(undefined, undefined, undefined, options), [30] - ); - }); - - it('lt', () => { - options.sortDirection = -1; - - // Act + Assert: - return runTestAndVerifyIds( - dbMosaicRestrictions(), db => db.mosaicRestrictions(undefined, undefined, undefined, options), [10] - ); - }); - }); - }); -}); diff --git a/rest/test/plugins/restrictions/restrictionsDbTestUtils.js b/rest/test/plugins/restrictions/restrictionsDbTestUtils.js deleted file mode 100644 index 64e7d5f03..000000000 --- a/rest/test/plugins/restrictions/restrictionsDbTestUtils.js +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const RestrictionsDb = require('../../../src/plugins/restrictions/RestrictionsDb'); -const dbTestUtils = require('../../db/utils/dbTestUtils'); -const test = require('../../testUtils'); -const catapult = require('catapult-sdk'); -const MongoDb = require('mongodb'); - -const { EntityType, restriction } = catapult.model; -const { Binary, ObjectId, Long } = MongoDb; - -const createRestrictions = restrictions => { - const restrictionsObject = []; - - let values = []; - for (let i = 0; i < restrictions.numAddresses; ++i) - values.push(new Binary(test.random.address())); - - restrictionsObject.push({ - restrictionType: 0.5 > Math.random() ? 1 : 129, - values - }); - - values = []; - for (let i = 0; i < restrictions.numMosaics; ++i) - values.push(Math.floor(Math.random() * 1000)); - - restrictionsObject.push({ - restrictionType: 0.5 > Math.random() ? 2 : 130, - values - }); - - values = []; - for (let i = 0; i < restrictions.numOperations; ++i) { - const operationTypes = Object.keys(EntityType); - values.push(EntityType[operationTypes[Math.floor(operationTypes.length * Math.random())]]); - } - - restrictionsObject.push({ - restrictionType: 0.5 > Math.random() ? 4 : 132, - values - }); - - return restrictionsObject; -}; - -const createObjectId = id => new ObjectId(`${'00'.repeat(12)}${id}`.slice(-24)); - -const restrictionsDbTestUtils = { - accountDb: { - createAccountRestrictions: (address, restrictionsDescriptor) => { - const accountRestrictions = { - address: new Binary(address), - restrictions: createRestrictions(restrictionsDescriptor) - }; - return { _id: dbTestUtils.db.createObjectId(Math.floor(Math.random() * 10000)), meta: {}, accountRestrictions }; - }, - - runDbTest: (dbEntities, issueDbCommand, assertDbCommandResult) => dbTestUtils.db.runDbTest( - dbEntities, - 'accountRestrictions', - db => new RestrictionsDb(db), - issueDbCommand, - assertDbCommandResult - ) - }, - - mosaicDb: { - sanitizeId: entity => { delete entity._id; return entity; }, - - createGlobalMosaicRestriction: mosaicId => ({ - _id: createObjectId(Math.floor(Math.random() * 100000)), - mosaicRestrictionEntry: { - compositeHash: '', - entryType: restriction.mosaicRestriction.restrictionType.global, - mosaicId: new Long(mosaicId[0], mosaicId[1]), - restrictions: [{ key: '', restriction: { referenceMosaicId: '', restrictionValue: '', restrictionType: 0 } }] - } - }), - - createAddressMosaicRestriction: (mosaicId, targetAddress) => ({ - _id: createObjectId(Math.floor(Math.random() * 100000)), - mosaicRestrictionEntry: { - compositeHash: '', - entryType: restriction.mosaicRestriction.restrictionType.address, - mosaicId: new Long(mosaicId[0], mosaicId[1]), - targetAddress: new Binary(Buffer.from(targetAddress)), - restrictions: [{ key: '', value: '' }] - } - }), - - runDbTest: (dbEntities, issueDbCommand, assertDbCommandResult) => dbTestUtils.db.runDbTest( - dbEntities, - 'mosaicRestrictions', - db => new RestrictionsDb(db), - issueDbCommand, - assertDbCommandResult - ) - } -}; - -Object.assign(restrictionsDbTestUtils, test); - -module.exports = restrictionsDbTestUtils; diff --git a/rest/test/plugins/restrictions/restrictionsRoutes_spec.js b/rest/test/plugins/restrictions/restrictionsRoutes_spec.js deleted file mode 100644 index b02cecdb3..000000000 --- a/rest/test/plugins/restrictions/restrictionsRoutes_spec.js +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const restrictionsRoutes = require('../../../src/plugins/restrictions/restrictionsRoutes'); -const routeResultTypes = require('../../../src/routes/routeResultTypes'); -const routeUtils = require('../../../src/routes/routeUtils'); -const { MockServer } = require('../../routes/utils/routeTestUtils'); -const { test } = require('../../routes/utils/routeTestUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; -const { addresses } = test.sets; - -describe('restrictions routes', () => { - describe('account restrictions', () => { - describe('by address', () => { - const parsedAddresses = addresses.valid.map(address.stringToAddress); - test.route.document.addGetPostDocumentRouteTests(restrictionsRoutes.register, { - routes: { singular: '/restrictions/account/:address', plural: '/restrictions/account' }, - inputs: { - valid: { object: { address: addresses.valid[0] }, parsed: [parsedAddresses[0]], printable: addresses.valid[0] }, - validMultiple: { object: { addresses: addresses.valid }, parsed: parsedAddresses }, - invalid: { object: { address: '12345' }, error: 'address has an invalid format' }, - invalidMultiple: { - object: { addresses: [addresses.valid[0], '12345'] }, - error: 'element in array addresses has an invalid format' - } - }, - - dbApiName: 'accountRestrictionsByAddresses', - type: 'accountRestrictions' - }); - }); - }); - - describe('mosaic restrictions', () => { - const testMosaicId = '0DC67FBE1CAD29E3'; - const testMosaicIdParsed = [0x1CAD29E3, 0x0DC67FBE]; - const testAddress = 'SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: '', - mosaicRestrictionEntry: { - compositeHash: '', - entryType: 0, - mosaicId: '', - targetAddress: '', - restrictions: [] - } - }, - { - id: '', - mosaicRestrictionEntry: { - compositeHash: '', - entryType: 1, - mosaicId: '', - restrictions: [] - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbMosaicRestrictionsFake = sinon.fake(mosaicId => - (mosaicId ? Promise.resolve(emptyPageSample) : Promise.resolve(pageSample))); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { mosaicRestrictions: dbMosaicRestrictionsFake }; - restrictionsRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbMosaicRestrictionsFake.resetHistory(); - }); - - describe('GET', () => { - const route = mockServer.getRoute('/restrictions/mosaic').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbMosaicRestrictionsFake.calledOnce).to.equal(true); - expect(dbMosaicRestrictionsFake.firstCall.args[3]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty page if no restrictions found', () => { - // Arrange: - const req = { params: { mosaicId: testMosaicId } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicRestrictionsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: routeResultTypes.mosaicRestrictions, - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards mosaicId', () => { - // Arrange: - const req = { params: { mosaicId: testMosaicId } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicRestrictionsFake.calledOnce).to.equal(true); - expect(dbMosaicRestrictionsFake.firstCall.args[0]).to.deep.equal(testMosaicIdParsed); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards entryType', () => { - // Arrange: - const req = { params: { entryType: '0' } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicRestrictionsFake.calledOnce).to.equal(true); - expect(dbMosaicRestrictionsFake.firstCall.args[1]).to.equal(0); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards targetAddress', () => { - // Arrange: - const req = { params: { targetAddress: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicRestrictionsFake.calledOnce).to.equal(true); - expect(dbMosaicRestrictionsFake.firstCall.args[2]).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbMosaicRestrictionsFake.calledOnce).to.equal(true); - expect(dbMosaicRestrictionsFake.firstCall.args[0]).to.deep.equal(undefined); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: routeResultTypes.mosaicRestrictions, - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('throws error if mosaicId is invalid', () => { - // Arrange: - const req = { params: { mosaicId: '12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('mosaicId has an invalid format'); - }); - - it('throws error if entryType is invalid', () => { - // Arrange: - const req = { params: { entryType: '-1' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('entryType has an invalid format'); - }); - - it('throws error if targetAddress is invalid', () => { - // Arrange: - const req = { params: { targetAddress: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('targetAddress has an invalid format'); - }); - - describe('by compositeHash', () => { - const compositeHashes = ['C54AFD996DF1F52748EBC5B40F8D0DC242A6A661299149F5F96A0C21ECCB653F']; - const parsedCompositeHashes = compositeHashes.map(routeUtils.namedParserMap.hash256); - test.route.document.addGetPostDocumentRouteTests(restrictionsRoutes.register, { - routes: { singular: '/restrictions/mosaic/:compositeHash', plural: '/restrictions/mosaic' }, - inputs: { - valid: { - object: { compositeHash: compositeHashes[0] }, - parsed: [parsedCompositeHashes[0]], - printable: compositeHashes[0] - }, - validMultiple: { object: { compositeHashes }, parsed: parsedCompositeHashes }, - invalid: { object: { compositeHash: '12345' }, error: 'compositeHash has an invalid format' }, - invalidMultiple: { - object: { compositeHashes: [compositeHashes[0], '12345'] }, - error: 'element in array compositeHashes has an invalid format' - } - }, - - dbApiName: 'mosaicRestrictionByCompositeHash', - type: 'mosaicRestrictions' - }); - }); - }); - }); -}); diff --git a/rest/test/plugins/restrictions/restrictions_spec.js b/rest/test/plugins/restrictions/restrictions_spec.js deleted file mode 100644 index 06c817fbc..000000000 --- a/rest/test/plugins/restrictions/restrictions_spec.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const RestrictionsDb = require('../../../src/plugins/restrictions/RestrictionsDb'); -const restrictions = require('../../../src/plugins/restrictions/restrictions'); -const { test } = require('../../routes/utils/routeTestUtils'); -const pluginTest = require('../utils/pluginTestUtils'); - -describe('restrictions plugin', () => { - pluginTest.assertThat.pluginCreatesDb(restrictions, RestrictionsDb); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalTransactionStates(restrictions); - pluginTest.assertThat.pluginDoesNotRegisterAdditionalMessageChannels(restrictions); - - describe('register routes', () => { - it('registers restrictions GET routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - restrictions.registerRoutes(server, {}, { network: { name: 'testnet' } }); - - // Assert: - test.assert.assertRoutes(routes, [ - '/restrictions/account', - '/restrictions/account/:address', - '/restrictions/account/:address/merkle', - '/restrictions/mosaic', - '/restrictions/mosaic/:compositeHash', - '/restrictions/mosaic/:compositeHash/merkle' - ]); - }); - - it('registers POST routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - restrictions.registerRoutes(server, {}); - - // Assert: - test.assert.assertRoutes(routes, [ - '/restrictions/account', - '/restrictions/mosaic' - ]); - }); - }); -}); diff --git a/rest/test/plugins/routeSystem_spec.js b/rest/test/plugins/routeSystem_spec.js deleted file mode 100644 index 08db93438..000000000 --- a/rest/test/plugins/routeSystem_spec.js +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeSystem = require('../../src/plugins/routeSystem'); -const { test } = require('../routes/utils/routeTestUtils'); -const { expect } = require('chai'); - -describe('route system', () => { - const servicesTemplate = { config: { websocket: {}, network: { name: 'testnet' } }, connections: {} }; - const configureTrailingParameters = [{ put: () => {} }, {}, servicesTemplate]; - - it('cannot register unknown extension', () => { - // Act: - expect(() => routeSystem.configure(['transfer', 'foo', 'namespace'], {}, {}, servicesTemplate)) - .to.throw('plugin \'foo\' not supported'); - }); - - it('has support for all extensions', () => { - // Act: - const supportedPluginNames = routeSystem.supportedPluginNames(); - - // Assert: - expect(supportedPluginNames).to.deep.equal([ - 'accountLink', - 'aggregate', - 'lockHash', - 'lockSecret', - 'metadata', - 'mosaic', - 'multisig', - 'namespace', - 'receipts', - 'restrictions', - 'transfer' - ]); - }); - - describe('routes', () => { - it('does not register default routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - routeSystem.configure([], server, {}, servicesTemplate); - - // Assert: - expect(routes.length).to.equal(0); - }); - - it('can register single extension', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - const db = { namespaceById: () => Promise.resolve({}) }; - - // Act: - routeSystem.configure(['namespace'], server, db, servicesTemplate); - - // Assert: - expect(routes).to.include('/namespaces/:namespaceId'); - }); - - it('can register multiple extensions', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - const db = { namespaceById: () => Promise.resolve({}) }; - - // Act: - routeSystem.configure(['namespace', 'transfer'], server, db, servicesTemplate); - - // Assert: - expect(routes).to.include('/namespaces/:namespaceId'); - }); - - it('can register single extension with service dependencies', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('put', routes); - - // Act: pass down required services too - routeSystem.configure(['aggregate'], server, {}, servicesTemplate); - - // Assert: - expect(routes).to.include('/transactions/partial'); - }); - }); - - describe('transaction states', () => { - it('can register single extension without custom transaction states', () => { - // Act: - const { transactionStates } = routeSystem.configure(['transfer'], ...configureTrailingParameters); - - // Assert: - expect(transactionStates.length).to.equal(0); - }); - - it('can register single extension with custom transaction states', () => { - // Act: - const { transactionStates } = routeSystem.configure(['aggregate'], ...configureTrailingParameters); - - // Assert: - expect(transactionStates.length).to.equal(1); - }); - }); - - describe('message channels', () => { - it('can register single extension without custom message channels', () => { - // Act: - const { messageChannelDescriptors } = routeSystem.configure(['transfer'], ...configureTrailingParameters); - - // Assert: - expect(Object.keys(messageChannelDescriptors)).to.deep.equal([ - 'block', 'finalizedBlock', 'confirmedAdded', 'unconfirmedAdded', 'unconfirmedRemoved', 'status' - ]); - }); - - it('can register single extension with custom message channels', () => { - // Act: - const { messageChannelDescriptors } = routeSystem.configure(['aggregate'], ...configureTrailingParameters); - - // Assert: - expect(Object.keys(messageChannelDescriptors)).to.deep.equal([ - 'block', 'finalizedBlock', 'confirmedAdded', 'unconfirmedAdded', 'unconfirmedRemoved', 'status', - 'partialAdded', 'partialRemoved', 'cosignature' - ]); - }); - - // following two tests are used to ensure configuration is passed down correctly to extension message channels - it('extension filter rejects marker without topic param', () => { - // Arrange: - const { messageChannelDescriptors } = routeSystem.configure(['aggregate'], ...configureTrailingParameters); - const { filter } = messageChannelDescriptors.partialAdded; - - // Act: - expect(() => filter('')).to.throw('address param missing from address subscription'); - }); - - it('extension filter accepts marker without topic param with allowOptionalAddress', () => { - // Arrange: - const services = { config: { websocket: { allowOptionalAddress: true }, network: { name: 'testnet' } }, connections: {} }; - const { messageChannelDescriptors } = routeSystem.configure(['aggregate'], { put: () => {} }, {}, services); - const { filter } = messageChannelDescriptors.partialAdded; - - // Act: - const topic = filter(''); - - // Assert: - expect(topic.length).to.equal(1); - expect(topic[0]).to.equal(0x70); - }); - }); -}); diff --git a/rest/test/plugins/utils/pluginTestUtils.js b/rest/test/plugins/utils/pluginTestUtils.js deleted file mode 100644 index 03ee359fd..000000000 --- a/rest/test/plugins/utils/pluginTestUtils.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { expect } = require('chai'); - -const wrapCreateDbTest = (resultName, action) => { - describe('create db', () => { - it(`returns ${resultName}`, action); - }); -}; - -module.exports = { - assertThat: { - pluginDoesNotCreateDb: plugin => { - wrapCreateDbTest('undefined', () => { - // Act: - const db = plugin.createDb(); - - // Assert: - expect(db).to.equal(undefined); - }); - }, - - pluginCreatesDb: (plugin, expectedDbType) => { - wrapCreateDbTest('db', () => { - // Act: - const db = plugin.createDb(); - - // Assert: - expect(db).to.be.instanceOf(expectedDbType); - }); - }, - - pluginDoesNotRegisterAdditionalTransactionStates: plugin => { - describe('register transaction states', () => { - it('does not register states', () => { - // Arrange: - const states = []; - - // Act: - plugin.registerTransactionStates(states); - - // Assert: - expect(states.length).to.equal(0); - }); - }); - }, - - pluginDoesNotRegisterAdditionalMessageChannels: plugin => { - describe('register message channels', () => { - it('does not register channels', () => { - // Arrange: - let numAddCalls = 0; - const builder = { add: () => { ++numAddCalls; } }; - - // Act: - plugin.registerMessageChannels(builder); - - // Assert: - expect(numAddCalls).to.equal(0); - }); - }); - } - } -}; diff --git a/rest/test/routes/MerkleTree_spec.js b/rest/test/routes/MerkleTree_spec.js deleted file mode 100644 index acbb267d2..000000000 --- a/rest/test/routes/MerkleTree_spec.js +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ -const MerkleTree = require('../../src/routes/MerkelTree'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const fs = require('fs'); -const fsPath = require('path'); - -describe('MerkleTree', () => { - describe('merkle tree parse', () => { - let merkleTree = new MerkleTree(); - it('getBitsFromMask', () => { - let bits = merkleTree.getBitsFromMask(catapult.utils.convert.hexToUint8('0C46')); - expect(bits.length).to.equal(5); - expect(bits.join('')).to.equal('239AE'); - - bits = merkleTree.getBitsFromMask(catapult.utils.convert.hexToUint8('8062')); - expect(bits.length).to.equal(4); - expect(bits.join('')).to.equal('79DE'); - - bits = merkleTree.getBitsFromMask(catapult.utils.convert.hexToUint8('1002')); - expect(bits.length).to.equal(2); - expect(bits.join('')).to.equal('49'); - }); - - it('getPathLength', () => { - let pathLength = merkleTree.getPathLength(0); - expect(pathLength).to.equal(0); - - pathLength = merkleTree.getPathLength(3); - expect(pathLength).to.equal(2); - - pathLength = merkleTree.getPathLength(9); - expect(pathLength).to.equal(5); - }); - - it('isBranch', () => { - expect(merkleTree.isBranch(0)).to.equal(true); - expect(merkleTree.isBranch(1)).to.equal(false); - }); - - it('isLeaf', () => { - expect(merkleTree.isLeaf(255)).to.equal(true); - expect(merkleTree.isLeaf(1)).to.equal(false); - }); - - it('nibbleAt', () => { - const path = catapult.utils.convert.hexToUint8('B7BB382C56'); - expect(merkleTree.nibbleAt(path, 0)).to.equal(11); - expect(merkleTree.nibbleAt(path, 5)).to.equal(8); - expect(merkleTree.nibbleAt(path, 10)).to.equal(0); - }); - - it('encodePath', () => { - let path = catapult.utils.convert.hexToUint8('B7BB382C56'); - expect(catapult.utils.convert.uint8ToHex(merkleTree.encodePath(path, 10, false))).to.equal('00B7BB382C56'); - path = catapult.utils.convert.hexToUint8('3DC610D300'); - expect(catapult.utils.convert.uint8ToHex(merkleTree.encodePath(path, 9, false))).to.equal('13DC610D30'); - path = catapult.utils.convert.hexToUint8('02396A7E61AE1B1C4C66BD6850C2951C77044CFA5BD0'); - expect(catapult.utils.convert.uint8ToHex(merkleTree.encodePath(path, 43, true))) - .to.equal('302396A7E61AE1B1C4C66BD6850C2951C77044CFA5BD'); - }); - - it('parseBranch', () => { - const branch = '8080DA9B4AF63BE985715EA635AF98E3CF3B0A22F9A2BE1C7DD40B79948AA63E' - + '36586E5D2E9D0C089C1C64BC0D42A11ADBD1CD6CDB4B7C294062F55113525A64AE3C'; - merkleTree = new MerkleTree(); - const { tree } = merkleTree; - merkleTree.parseBranch(catapult.utils.convert.hexToUint8(branch), new Uint8Array(), 0); - expect(tree.length).to.equal(1); - expect(tree[0].type).to.equal(0); - expect(tree[0].linkMask).to.equal('8080'); - expect(tree[0].links.length).to.equal(2); - expect(tree[0].links[0].bit).to.equal('7'); - expect(tree[0].links[0].link).to.equal('DA9B4AF63BE985715EA635AF98E3CF3B0A22F9A2BE1C7DD40B79948AA63E3658'); - expect(tree[0].links[1].bit).to.equal('F'); - expect(tree[0].links[1].link).to.equal('6E5D2E9D0C089C1C64BC0D42A11ADBD1CD6CDB4B7C294062F55113525A64AE3C'); - }); - - it('getBranchHash', () => { - const encodedPath = '00'; - const links = [ - { - bit: '6', - link: '65DA42890A39521AF4F06A5C7A96AC14C3B70611C671FF7E00B401A0C7110ECB' - }, - { - bit: 'C', - link: 'D0E3CD07177472CC42C7DBB645C15854D06F150E11B7D3C73AB05A53AFB88C07' - }, - { - bit: 'D', - link: '1CB226DA02F7748A47D40798316418341991E4AF2D83E1EDDAECA55F1D00DD59' - } - ]; - merkleTree = new MerkleTree(); - const branchHash = merkleTree.getBranchHash(encodedPath, links); - expect(branchHash).to.equal('EA1E622F7655215A1A3D4C4FA112155BD8AE3AAF2E2C62899763A45D7E91C89C'); - }); - - it('getLeafHash', () => { - const encodedPath = '20B0D86F48CC652CA98B5A463EDF4849AC6D6CB431EDE4DFBA0698A26D4106D7'; - const value = 'EFB918C83096F8013736864B6914B95F8BB1892D448AED557BD852D18B261EE1'; - merkleTree = new MerkleTree(); - const leafHash = merkleTree.getLeafHash(encodedPath, value); - expect(leafHash).to.equal('65DA42890A39521AF4F06A5C7A96AC14C3B70611C671FF7E00B401A0C7110ECB'); - }); - - it('parseLeaf', () => { - const leaf = '0C3EAFF635F01BB3B474F0AF1BE99FBDA85EEFB209CC7BD158D3540DE3A3F2D1'; - merkleTree = new MerkleTree(); - const { tree } = merkleTree; - merkleTree.parseLeaf(catapult.utils.convert.hexToUint8(leaf), - catapult.utils.convert.hexToUint8('04A7F2A487B42EA89323C4408F82415223ACFEC7DFA7924EFC31A70778AB17A0'), 63); - expect(tree.length).to.equal(1); - expect(tree[0].type).to.equal(255); - expect(tree[0].linkMask).to.equal(undefined); - expect(tree[0].path).to.equal('04A7F2A487B42EA89323C4408F82415223ACFEC7DFA7924EFC31A70778AB17A0'); - expect(tree[0].value).to.equal('0C3EAFF635F01BB3B474F0AF1BE99FBDA85EEFB209CC7BD158D3540DE3A3F2D1'); - }); - - it('parseRaw', () => { - const raw = '00008080DA9B4AF63BE985715EA635AF98E3CF3B0A22F9A2BE1C7DD40B79948AA63E36586E5D2E9D0C089C' - + '1C64BC0D42A11ADBD1CD6CDB4B7C294062F55113525A64AE3CFF3F04A7F2A487B42EA89323C4408F82415223ACFEC7D' - + 'FA7924EFC31A70778AB17A00C3EAFF635F01BB3B474F0AF1BE99FBDA85EEFB209CC7BD158D3540DE3A3F2D1'; - merkleTree = new MerkleTree(); - const { tree } = merkleTree; - merkleTree.parseMerkleTreeFromRaw(catapult.utils.convert.hexToUint8(raw)); - expect(tree.length).to.equal(2); - expect(tree[0].type).to.equal(0); - expect(tree[0].linkMask).to.equal('8080'); - expect(tree[0].links.length).to.equal(2); - expect(tree[0].links[0].bit).to.equal('7'); - expect(tree[0].links[0].link).to.equal('DA9B4AF63BE985715EA635AF98E3CF3B0A22F9A2BE1C7DD40B79948AA63E3658'); - expect(tree[0].links[1].bit).to.equal('F'); - expect(tree[0].links[1].link).to.equal('6E5D2E9D0C089C1C64BC0D42A11ADBD1CD6CDB4B7C294062F55113525A64AE3C'); - - expect(tree[1].type).to.equal(255); - expect(tree[1].linkMask).to.equal(undefined); - expect(tree[1].path).to.equal('04A7F2A487B42EA89323C4408F82415223ACFEC7DFA7924EFC31A70778AB17A0'); - expect(tree[1].value).to.equal('0C3EAFF635F01BB3B474F0AF1BE99FBDA85EEFB209CC7BD158D3540DE3A3F2D1'); - }); - - it('parseRaw - multiple branches', () => { - const raw = '0000FFFF5EC7D52423FC5C8BC0F8F15FC79C16193A852B32232008D15B3CEDDD97FC1E9F62C6805349E0' - + 'C741E92D4693E98AA6D5CDE12ADE901E1B6E19FA5C55DA8B8628841F3802703D6B7B233542DFDBBC11F4DE72BCDE' - + '62BEDBD64D2D6BA220D232462422162DFE1D04C9E9272ECC9F2B8EB37BF09A6C12C2DA0FE588D045E6DDDFBE74CE' - + '2D046699B19A822AB233005596CCEF93989652B33ED7E909ADDDB33AD02886498B57680DBE4517257D5CF544D052' - + '67D1EC516035740AF3515346E80CEA4F7D195DAD3163B925B21C3AF60CC264300E4C339E6BCEF40CB7B39C214D4A' - + 'CE01666CEAC091FD1AEF8F14F6ABD861C32B07CB107B3EABDE088AF5E82D35D5F9437A08A4A30D0CA54C1308EA0E' - + '04E3203F20E5A741D8F37EAB21ED33C3DF23F9D7DCC385A12DF001EFA572DDE4E2F201C3DAC8F9FB33ABF05A9B6E' - + '07B46EB77B8BB762D14A56BEB17DF8DFA68B3A832AB364FC2885044727A09124C53D2EDD980B408AEE9E053F9D61' - + '8EA792B1BE7736668CFFD23FDA4DA3233403754F188CAAC88B5C5F699AA780DF6CD737059361E4B8E552C0A0C395' - + '973E4558425D60FF2B5B4C142D7A873258A04E7676A57110201600C50E4EF7A2D5F82C02E74B196924D5A5F7AC91' - + 'DDD27FB71DFE0C7DDED1FB639C1E6DEC2F207A334A0F5CD6F7834B1C20112E11042D501793B9EF93451C53FAB12C' - + '5D4A851349C2B288674C75994A4900006BEFDEC85B49EE58F3E2F16575386D82967D27D19657E4C60F17FAAD7B3B' - + '531DC58E51A04403B2067D2FC9F7CB114C8D42B01540134630B686698F18AE8A88BC961DF808CC6F52274BBFB930' - + '2E3720AA89DF5EC1743CE6B0406E57075B1C162D4DE824B940727BB626A9469322B91D5B3BB66A73711765A8C5C5' - + '8BF986EE9DE27B28F27055712854EF6FC0007C89D5EF913F65B2DE33B9644FEE6EB551BA19FACEA2AA54E994728A' - + '940664D2070D562A2C1A1717EEB895BE612BEBD3B43D2D61B88C599CD2E36DAC9EF6F95A628B8B12A82B0920D257' - + '1A2AAEA67EA87638BE1102915FED8D7A23CF23488FE3DC8CA646DBBA67924CB543A85728E2A8353CB829FC81971A' - + 'F7AD00F3AD44EF258BB4D93DD245BC9B53F9AB3E9C23DF688A0E076F7EC8D813BAB9C15503E53A8DF1C2BC68AEBD' - + 'DD29A136C5CC09367FD87F9C56B77A105AD006E6D43B72E552471BB4B13576A8A7448A6548BB5C03E9AAA0BE7591' - + 'A193EA95B6BDD4B78132DB94CC70389A62ADD291E5130CC09AFC3E5B5A58A655A14FFF3EDD0A830D85825627C194' - + 'FD126705843470B23E2B6A223A317BC385CE912E25E7158DBBF548B8B76BA4CD15E895DBA9429E9A4D6C1226AB9D' - + '53E91D911671A7'; - - merkleTree = new MerkleTree(); - const { tree } = merkleTree; - merkleTree.parseMerkleTreeFromRaw(catapult.utils.convert.hexToUint8(raw)); - expect(tree.length).to.equal(3); - expect(tree[0].type).to.equal(0); - expect(tree[0].linkMask).to.equal('FFFF'); - expect(tree[0].links.length).to.equal(16); - expect(tree[0].links[0].bit).to.equal('0'); - expect(tree[0].links[0].link).to.equal('5EC7D52423FC5C8BC0F8F15FC79C16193A852B32232008D15B3CEDDD97FC1E9F'); - expect(tree[0].links[1].bit).to.equal('1'); - expect(tree[0].links[1].link).to.equal('62C6805349E0C741E92D4693E98AA6D5CDE12ADE901E1B6E19FA5C55DA8B8628'); - expect(tree[0].links[2].bit).to.equal('2'); - expect(tree[0].links[2].link).to.equal('841F3802703D6B7B233542DFDBBC11F4DE72BCDE62BEDBD64D2D6BA220D23246'); - expect(tree[0].links[3].bit).to.equal('3'); - expect(tree[0].links[3].link).to.equal('2422162DFE1D04C9E9272ECC9F2B8EB37BF09A6C12C2DA0FE588D045E6DDDFBE'); - expect(tree[0].links[4].bit).to.equal('4'); - expect(tree[0].links[4].link).to.equal('74CE2D046699B19A822AB233005596CCEF93989652B33ED7E909ADDDB33AD028'); - expect(tree[0].links[5].bit).to.equal('5'); - expect(tree[0].links[5].link).to.equal('86498B57680DBE4517257D5CF544D05267D1EC516035740AF3515346E80CEA4F'); - expect(tree[0].links[6].bit).to.equal('6'); - expect(tree[0].links[6].link).to.equal('7D195DAD3163B925B21C3AF60CC264300E4C339E6BCEF40CB7B39C214D4ACE01'); - expect(tree[0].links[7].bit).to.equal('7'); - expect(tree[0].links[7].link).to.equal('666CEAC091FD1AEF8F14F6ABD861C32B07CB107B3EABDE088AF5E82D35D5F943'); - expect(tree[0].links[8].bit).to.equal('8'); - expect(tree[0].links[8].link).to.equal('7A08A4A30D0CA54C1308EA0E04E3203F20E5A741D8F37EAB21ED33C3DF23F9D7'); - expect(tree[0].links[9].bit).to.equal('9'); - expect(tree[0].links[9].link).to.equal('DCC385A12DF001EFA572DDE4E2F201C3DAC8F9FB33ABF05A9B6E07B46EB77B8B'); - expect(tree[0].links[10].bit).to.equal('A'); - expect(tree[0].links[10].link).to.equal('B762D14A56BEB17DF8DFA68B3A832AB364FC2885044727A09124C53D2EDD980B'); - expect(tree[0].links[11].bit).to.equal('B'); - expect(tree[0].links[11].link).to.equal('408AEE9E053F9D618EA792B1BE7736668CFFD23FDA4DA3233403754F188CAAC8'); - expect(tree[0].links[12].bit).to.equal('C'); - expect(tree[0].links[12].link).to.equal('8B5C5F699AA780DF6CD737059361E4B8E552C0A0C395973E4558425D60FF2B5B'); - expect(tree[0].links[13].bit).to.equal('D'); - expect(tree[0].links[13].link).to.equal('4C142D7A873258A04E7676A57110201600C50E4EF7A2D5F82C02E74B196924D5'); - expect(tree[0].links[14].bit).to.equal('E'); - expect(tree[0].links[14].link).to.equal('A5F7AC91DDD27FB71DFE0C7DDED1FB639C1E6DEC2F207A334A0F5CD6F7834B1C'); - expect(tree[0].links[15].bit).to.equal('F'); - expect(tree[0].links[15].link).to.equal('20112E11042D501793B9EF93451C53FAB12C5D4A851349C2B288674C75994A49'); - - expect(tree[1].type).to.equal(0); - expect(tree[1].linkMask).to.equal('EF6B'); - expect(tree[1].links.length).to.equal(12); - expect(tree[1].links[0].bit).to.equal('0'); - expect(tree[1].links[0].link).to.equal('DEC85B49EE58F3E2F16575386D82967D27D19657E4C60F17FAAD7B3B531DC58E'); - expect(tree[1].links[1].bit).to.equal('1'); - expect(tree[1].links[1].link).to.equal('51A04403B2067D2FC9F7CB114C8D42B01540134630B686698F18AE8A88BC961D'); - expect(tree[1].links[2].bit).to.equal('3'); - expect(tree[1].links[2].link).to.equal('F808CC6F52274BBFB9302E3720AA89DF5EC1743CE6B0406E57075B1C162D4DE8'); - expect(tree[1].links[3].bit).to.equal('5'); - expect(tree[1].links[3].link).to.equal('24B940727BB626A9469322B91D5B3BB66A73711765A8C5C58BF986EE9DE27B28'); - expect(tree[1].links[4].bit).to.equal('6'); - expect(tree[1].links[4].link).to.equal('F27055712854EF6FC0007C89D5EF913F65B2DE33B9644FEE6EB551BA19FACEA2'); - expect(tree[1].links[5].bit).to.equal('8'); - expect(tree[1].links[5].link).to.equal('AA54E994728A940664D2070D562A2C1A1717EEB895BE612BEBD3B43D2D61B88C'); - expect(tree[1].links[6].bit).to.equal('9'); - expect(tree[1].links[6].link).to.equal('599CD2E36DAC9EF6F95A628B8B12A82B0920D2571A2AAEA67EA87638BE110291'); - expect(tree[1].links[7].bit).to.equal('A'); - expect(tree[1].links[7].link).to.equal('5FED8D7A23CF23488FE3DC8CA646DBBA67924CB543A85728E2A8353CB829FC81'); - expect(tree[1].links[8].bit).to.equal('B'); - expect(tree[1].links[8].link).to.equal('971AF7AD00F3AD44EF258BB4D93DD245BC9B53F9AB3E9C23DF688A0E076F7EC8'); - expect(tree[1].links[9].bit).to.equal('D'); - expect(tree[1].links[9].link).to.equal('D813BAB9C15503E53A8DF1C2BC68AEBDDD29A136C5CC09367FD87F9C56B77A10'); - expect(tree[1].links[10].bit).to.equal('E'); - expect(tree[1].links[10].link).to.equal('5AD006E6D43B72E552471BB4B13576A8A7448A6548BB5C03E9AAA0BE7591A193'); - expect(tree[1].links[11].bit).to.equal('F'); - expect(tree[1].links[11].link).to.equal('EA95B6BDD4B78132DB94CC70389A62ADD291E5130CC09AFC3E5B5A58A655A14F'); - - expect(tree[2].type).to.equal(255); - expect(tree[2].linkMask).to.equal(undefined); - expect(tree[2].path).to.equal('DD0A830D85825627C194FD126705843470B23E2B6A223A317BC385CE912E25'); - expect(tree[2].value).to.equal('E7158DBBF548B8B76BA4CD15E895DBA9429E9A4D6C1226AB9D53E91D911671A7'); - }); - - it('parseRaw - non zero nibbles', () => { - const raw = '000AB7BB382C56806217BB7F07DD6E5ED7ED72441AC98FDDE6666476BC2DFD4C038BDE0A0FDF650309BBCB7268B70' - + 'EE39982B7BBC9ED4AA138A20C529B57A8483A7F4140CF2DD707C403B450D28E74BB0D0286E32BE4EAE0871DDDA0F666CA7C06' - + 'A948AB408D7D3759E0E1D7D8FAD9309D6468CD4D3D7CAE1CEB723F332C16935D3C1DC46120CE532A00093DC610D3001002625' - + 'F41387807712CDF81178B3311FD269F2D539E4FF8E119C1D9900083E0B8577D6F47C31E28BDADCD84330066B6771B8A666268' - + 'A0209A37E47525BEA3DFF3E9FF2B02396A7E61AE1B1C4C66BD6850C2951C77044CFA5BD04AAFD429BA7128AAA203D7F148DEE' - + '82F2D1068C95AB5AF53B27B9C336327E8AA'; - - merkleTree = new MerkleTree(); - const { tree } = merkleTree; - merkleTree.parseMerkleTreeFromRaw(catapult.utils.convert.hexToUint8(raw)); - expect(tree.length).to.equal(3); - expect(tree[0].type).to.equal(0); - expect(tree[0].linkMask).to.equal('6280'); - expect(tree[0].path).to.equal('B7BB382C56'); - expect(tree[0].links.length).to.equal(4); - expect(tree[0].links[0].bit).to.equal('7'); - expect(tree[0].links[0].link).to.equal('17BB7F07DD6E5ED7ED72441AC98FDDE6666476BC2DFD4C038BDE0A0FDF650309'); - expect(tree[0].links[1].bit).to.equal('9'); - expect(tree[0].links[1].link).to.equal('BBCB7268B70EE39982B7BBC9ED4AA138A20C529B57A8483A7F4140CF2DD707C4'); - expect(tree[0].links[2].bit).to.equal('D'); - expect(tree[0].links[2].link).to.equal('03B450D28E74BB0D0286E32BE4EAE0871DDDA0F666CA7C06A948AB408D7D3759'); - expect(tree[0].links[3].bit).to.equal('E'); - expect(tree[0].links[3].link).to.equal('E0E1D7D8FAD9309D6468CD4D3D7CAE1CEB723F332C16935D3C1DC46120CE532A'); - - expect(tree[1].type).to.equal(0); - expect(tree[1].linkMask).to.equal('0210'); - expect(tree[1].path).to.equal('3DC610D300'); - expect(tree[1].links.length).to.equal(2); - expect(tree[1].links[0].bit).to.equal('4'); - expect(tree[1].links[0].link).to.equal('625F41387807712CDF81178B3311FD269F2D539E4FF8E119C1D9900083E0B857'); - expect(tree[1].links[1].bit).to.equal('9'); - expect(tree[1].links[1].link).to.equal('7D6F47C31E28BDADCD84330066B6771B8A666268A0209A37E47525BEA3DFF3E9'); - - expect(tree[2].type).to.equal(255); - expect(tree[2].linkMask).to.equal(undefined); - expect(tree[2].path).to.equal('02396A7E61AE1B1C4C66BD6850C2951C77044CFA5BD0'); - expect(tree[2].value).to.equal('4AAFD429BA7128AAA203D7F148DEE82F2D1068C95AB5AF53B27B9C336327E8AA'); - }); - - describe('merkle tree parse from testnet examples', () => { - const treePath = fsPath.resolve(__dirname, '../merkle/trees.json'); - const trees = JSON.parse(fs.readFileSync(treePath, 'UTF-8').trim()); - trees.forEach(tree => { - const fieldName = Object.keys(tree).filter(n => 'raw' !== n)[0]; - it(`${fieldName} ${tree[fieldName]}`, () => { - const testnetTree = new MerkleTree(); - testnetTree.parseMerkleTreeFromRaw(catapult.utils.convert.hexToUint8(tree.raw)); - expect(testnetTree.tree.length).to.be.gt(0); - }); - }); - }); - }); -}); diff --git a/rest/test/routes/accountRoutes_spec.js b/rest/test/routes/accountRoutes_spec.js deleted file mode 100644 index cd141750f..000000000 --- a/rest/test/routes/accountRoutes_spec.js +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer } = require('./utils/routeTestUtils'); -const { test } = require('./utils/routeTestUtils'); -const MerkleTree = require('../../src/routes/MerkelTree'); -const accountRoutes = require('../../src/routes/accountRoutes'); -const routeResultTypes = require('../../src/routes/routeResultTypes'); -const routeUtils = require('../../src/routes/routeUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { PacketType } = catapult.packet; - -const { address } = catapult.model; -const { convert } = catapult.utils; - -describe('account routes', () => { - const testAddress = 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'; - const testPublicKey = '7DE16AEDF57EB9561D3E6EFA4AE66F27ABDA8AEC8BC020B6277360E31619DCE7'; - - describe('GET', () => { - describe('accounts', () => { - const testMosaicId = 'ABCDEF0123456789'; - - const emptyPageSample = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const pageSample = { - data: [ - { - id: 'random1', - account: { - address: '', - addressHeight: '', - publicKey: '', - publicKeyHeight: '', - supplementalPublicKeys: {}, - importance: '', - importanceHeight: '', - activityBuckets: [], - mosaics: [] - } - }, - { - id: 'random2', - account: { - address: '', - addressHeight: '', - publicKey: '', - publicKeyHeight: '', - supplementalPublicKeys: {}, - importance: '', - importanceHeight: '', - activityBuckets: [], - mosaics: [] - } - } - ], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - const dbAccountsFake = sinon.fake(accountAddress => - (accountAddress ? Promise.resolve(emptyPageSample) : Promise.resolve(pageSample))); - - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - - const mockServer = new MockServer(); - const db = { accounts: dbAccountsFake }; - accountRoutes.register(mockServer.server, db, services); - - beforeEach(() => { - mockServer.resetStats(); - dbAccountsFake.resetHistory(); - }); - - const route = mockServer.getRoute('/accounts').get(); - - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ - id: 'objectId', - balance: 'uint64' - }); - - expect(dbAccountsFake.calledOnce).to.equal(true); - expect(dbAccountsFake.firstCall.args[2]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId', balance: 'uint64' }; - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - - it('returns empty page if no accounts found', () => { - // Arrange: - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsFake.calledOnce).to.equal(true); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: emptyPageSample, - type: routeResultTypes.account, - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards query without address if not provided', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsFake.calledOnce).to.equal(true); - expect(dbAccountsFake.firstCall.args[0]).to.deep.equal(undefined); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards query without mosaicId if not provided', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsFake.calledOnce).to.equal(true); - expect(dbAccountsFake.firstCall.args[1]).to.deep.equal(undefined); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards address', () => { - // Arrange: - const req = { params: { address: testAddress } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsFake.calledOnce).to.equal(true); - expect(dbAccountsFake.firstCall.args[0]).to.deep.equal(address.stringToAddress(testAddress)); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards mosaicId', () => { - // Arrange: - const req = { params: { mosaicId: testMosaicId } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsFake.calledOnce).to.equal(true); - expect(dbAccountsFake.firstCall.args[1]).to.deep.equal([0x23456789, 0xABCDEF01]); - - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns page with results', () => { - // Arrange: - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsFake.calledOnce).to.equal(true); - expect(dbAccountsFake.firstCall.args[0]).to.deep.equal(undefined); - expect(dbAccountsFake.firstCall.args[1]).to.deep.equal(undefined); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: pageSample, - type: routeResultTypes.account, - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('throws error if address is invalid', () => { - // Arrange: - const req = { params: { address: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('address has an invalid format'); - }); - - it('throws error if mosaicId is invalid', () => { - // Arrange: - const req = { params: { mosaicId: 'AB12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('mosaicId has an invalid format'); - }); - - it('throws error if there is no mosaicId when sorting by balance', () => { - // Arrange: - const req = { params: { orderBy: 'balance' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('mosaicId must be provided when sorting by balance'); - }); - }); - - describe('by accountId', () => { - describe('by address', () => { - test.route.document.addGetDocumentRouteTests(accountRoutes.register, { - route: '/accounts/:accountId', - inputs: { - valid: { - object: { accountId: testAddress }, - parsed: [[{ address: address.stringToAddress(testAddress) }]], - printable: testAddress - }, - invalid: { - object: { accountId: '12345' }, - error: 'accountId has an invalid format' - } - }, - dbApiName: 'accountsByIds', - type: routeResultTypes.account - }); - }); - - describe('by publicKey', () => { - test.route.document.addGetDocumentRouteTests(accountRoutes.register, { - route: '/accounts/:accountId', - inputs: { - valid: { - object: { accountId: testPublicKey }, - parsed: [[{ publicKey: convert.hexToUint8(testPublicKey) }]], - printable: testPublicKey - }, - invalid: { - object: { accountId: '12345' }, - error: 'accountId has an invalid format' - } - }, - dbApiName: 'accountsByIds', - type: routeResultTypes.account - }); - }); - }); - }); - - describe('POST', () => { - describe('accounts', () => { - const fakeAccounts = [{ id: '', account: { address: '' } }]; - const dbAccountsByIds = sinon.fake.resolves(fakeAccounts); - const mockServer = new MockServer(); - const db = { accountsByIds: dbAccountsByIds }; - accountRoutes.register(mockServer.server, db, {}); - - const route = mockServer.getRoute('/accounts').post(); - - beforeEach(() => { - mockServer.resetStats(); - dbAccountsByIds.resetHistory(); - }); - - it('throws if both publicKeys and addresses are provided', () => { - // Arrange - const req = { params: { addresses: [], publicKeys: [] } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('publicKeys and addresses cannot both be provided'); - }); - - const runParseArgumentAsArrayParamTest = (paramValues, paramName, parserName) => { - // Arrange - const req = { params: { [paramName]: paramValues } }; - const parseArgumentsAsArraySpy = sinon.spy(routeUtils, 'parseArgumentAsArray'); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(parseArgumentsAsArraySpy.calledOnceWith( - { [paramName]: paramValues }, - paramName, - parserName - )).to.equal(true); - parseArgumentsAsArraySpy.restore(); - }); - }; - - it('calls parseArgumentAsArray with correct parser for addresses', () => - runParseArgumentAsArrayParamTest([testAddress, testAddress], 'addresses', 'address')); - - it('calls parseArgumentAsArray with correct parser for public keys', () => - runParseArgumentAsArrayParamTest([testPublicKey, testPublicKey], 'publicKeys', 'publicKey')); - - describe('calls correct accounts retriever with correct params', () => { - it('adress params', () => { - // Arrange - const req = { params: { addresses: [testAddress] } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsByIds.calledOnce).to.equal(true); - expect(dbAccountsByIds.firstCall.args[0]).to.deep.equal([{ address: address.stringToAddress(testAddress) }]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeAccounts, - type: routeResultTypes.account - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('publicKey params', () => { - // Arrange - const req = { params: { publicKeys: [testPublicKey] } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbAccountsByIds.calledOnce).to.equal(true); - expect(dbAccountsByIds.firstCall.args[0]).to.deep.equal([{ publicKey: convert.hexToUint8(testPublicKey) }]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeAccounts, - type: routeResultTypes.account - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - }); - }); - - const serviceCreator = packet => ({ - connections: { - singleUse: () => new Promise(resolve => { - resolve({ - pushPull: () => new Promise(innerResolve => innerResolve(packet)) - }); - }) - }, - config: { - apiNode: { timeout: 1000 } - } - }); - - describe('account state tree', () => { - describe('returns the requested tree with valid params', () => { - // Arrange: - const stateTree = '00008080DA9B4AF63BE985715EA635AF98E3CF3B0A22F9A2' - + 'BE1C7DD40B79948AA63E36586E5D2E9D0C089C1C64BC0D' - + '42A11ADBD1CD6CDB4B7C294062F55113525A64AE3CFF3F' - + '04A7F2A487B42EA89323C4408F82415223ACFEC7DFA7924' - + 'EFC31A70778AB17A00C3EAFF635F01BB3B474F0AF1BE99F' - + 'BDA85EEFB209CC7BD158D3540DE3A3F2D1'; - const stateTreeBytes = convert.hexToUint8(stateTree); - - const packetType = PacketType.accountStatePath; - const packet = { - type: PacketType.accountStatePath, - size: stateTreeBytes.length, - payload: stateTreeBytes - }; - const services = serviceCreator(packet); - const merkleTree = new MerkleTree(); - const tree = merkleTree.parseMerkleTreeFromRaw(stateTreeBytes); - - // Act: - it(`for ${packetType} state`, () => - test.route.prepareExecuteRoute( - accountRoutes.register, - '/accounts/:accountId/merkle', - 'get', - { accountId: testAddress }, - {}, services, routeContext => routeContext.routeInvoker().then(() => { - // Assert: - expect(routeContext.numNextCalls).to.equal(1); - expect(routeContext.responses.length).to.equal(1); - expect(routeContext.redirects.length).to.equal(0); - expect(routeContext.responses[0]).to.deep.equal({ - raw: stateTree, - tree - }); - }) - )); - }); - - it('returns error for invalid address', () => - // Act: - test.route.prepareExecuteRoute( - accountRoutes.register, - '/accounts/:accountId/merkle', - 'get', - { accountId: 'ABC' }, - {}, {}, routeContext => - test.assert.invokerThrowsError(routeContext.routeInvoker, { - statusCode: 409, - message: 'accountId has an invalid format' - }) - )); - }); -}); diff --git a/rest/test/routes/allRoutes_spec.js b/rest/test/routes/allRoutes_spec.js deleted file mode 100644 index e48ecc6fc..000000000 --- a/rest/test/routes/allRoutes_spec.js +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { test } = require('./utils/routeTestUtils'); -const allRoutes = require('../../src/routes/allRoutes'); - -describe('all routes', () => { - const registerAll = server => { - const config = { - pageSize: { min: 10, max: 100 }, - transactionStates: [], - apiNode: { timeout: 1000 } - }; - allRoutes.register(server, {}, { config }); - }; - - it('registers all get routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('get', routes); - - // Act: - registerAll(server); - - // Assert: - test.assert.assertRoutes(routes, [ - '/accounts', - '/accounts/:accountId', - '/accounts/:accountId/merkle', - - '/blocks', - '/blocks/:height', - '/blocks/:height/transactions/:hash/merkle', - - '/chain/info', - - '/finalization/proof/epoch/:epoch', - '/finalization/proof/height/:height', - - '/network', - '/network/properties', - '/network/fees/transaction', - '/network/fees/rental', - '/node/health', - '/node/info', - '/node/peers', - '/node/server', - '/node/storage', - '/node/time', - '/node/unlockedaccount', - - '/transactions/:group/:transactionId', - '/transactions/:group', - '/transactionStatus/:hash' - ]); - }); - - it('registers all post routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('post', routes); - - // Act: - registerAll(server); - - // Assert: - test.assert.assertRoutes(routes, [ - '/accounts', - '/transactions/:group', - '/transactionStatus' - ]); - }); - - it('registers all put routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('put', routes); - - // Act: - registerAll(server); - - // Assert: - test.assert.assertRoutes(routes, ['/transactions']); - }); - - it('registers all ws routes', () => { - // Arrange: - const routes = []; - const server = test.setup.createCapturingMockServer('ws', routes); - - // Act: - registerAll(server); - - // Assert: - test.assert.assertRoutes(routes, ['/ws']); - }); -}); diff --git a/rest/test/routes/blockRoutes_spec.js b/rest/test/routes/blockRoutes_spec.js deleted file mode 100644 index 95450962c..000000000 --- a/rest/test/routes/blockRoutes_spec.js +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer, test } = require('./utils/routeTestUtils'); -const { convertToLong } = require('../../src/db/dbUtils'); -const blockRoutes = require('../../src/routes/blockRoutes'); -const routeResultTypes = require('../../src/routes/routeResultTypes'); -const routeUtils = require('../../src/routes/routeUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; -const { convert } = catapult.utils; - -describe('block routes', () => { - const addChainStatisticToDb = db => { db.chainStatisticCurrent = () => Promise.resolve({ height: convertToLong(10) }); }; - const routeConfig = { pageSize: { min: 30, max: 80 } }; - - describe('blocks', () => { - describe('get', () => { - const testPublickeyString = '7DE16AEDF57EB9561D3E6EFA4AE66F27ABDA8AEC8BC020B6277360E31619DCE7'; - const testPublickey = convert.hexToUint8(testPublickeyString); - - const testAddressString = 'SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'; - const testAddress = address.stringToAddress(testAddressString); - - const fakeBlock = { id: 0, meta: { transactionsCount: 0 }, block: { type: 33091 } }; - const fakePaginatedBlock = { - data: [fakeBlock], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - const dbBlocksFake = sinon.fake.resolves(fakePaginatedBlock); - - const mockServer = new MockServer(); - const db = { blocks: dbBlocksFake }; - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - blockRoutes.register(mockServer.server, db, services); - - const route = mockServer.getRoute('/blocks').get(); - - beforeEach(() => { - mockServer.resetStats(); - dbBlocksFake.resetHistory(); - }); - - it('returns correct structure with blocks', () => { - const req = { params: {} }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakePaginatedBlock, - type: routeResultTypes.block, - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('forwards signerPublicKey filter', () => - mockServer.callRoute(route, { params: { signerPublicKey: testPublickeyString } }).then(() => { - expect(dbBlocksFake.firstCall.args[0]).to.deep.equal(testPublickey); - expect(dbBlocksFake.firstCall.args[1]).to.deep.equal(undefined); - })); - - it('forwards beneficiaryAddress filter', () => - mockServer.callRoute(route, { params: { beneficiaryAddress: testAddressString } }).then(() => { - expect(dbBlocksFake.firstCall.args[0]).to.deep.equal(undefined); - expect(dbBlocksFake.firstCall.args[1]).to.deep.equal(testAddress); - })); - - describe('parses paging', () => { - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - - // Act: - const req = { params: {} }; - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId', height: 'uint64' }); - - expect(dbBlocksFake.calledOnce).to.equal(true); - expect(dbBlocksFake.firstCall.args[2]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { - id: 'objectId', - height: 'uint64' - }; - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - }); - }); - }); - - describe('block at height', () => { - const builder = test.route.document.prepareGetDocumentRouteTests(blockRoutes.register, { - route: '/blocks/:height', - dbApiName: 'blockAtHeight', - type: 'blockHeaderWithMetadata', - extendDb: addChainStatisticToDb, - config: routeConfig - }); - builder.addDefault({ - valid: { object: { height: '3' }, parsed: [[3, 0]], printable: '3' }, - invalid: { object: { height: '10A' }, error: 'height has an invalid format' } - }); - builder.addNotFoundInputTest({ object: { height: '11' }, parsed: [[11, 0]], printable: '11' }, 'chain height is too small'); - }); - - describe('block with merkle tree', () => { - it('calls blockRouteMerkleProcessor with correct params', () => { - // Arrange: - const mockServer = new MockServer(); - const blockRouteMerkleProcessorSpy = sinon.spy(routeUtils, 'blockRouteMerkleProcessor'); - - // Act: - blockRoutes.register(mockServer.server, {}, { config: routeConfig }); - - // Assert: - expect(blockRouteMerkleProcessorSpy.calledOnce).to.equal(true); - expect(blockRouteMerkleProcessorSpy.firstCall.args[1]).to.equal('transactionsCount'); - expect(blockRouteMerkleProcessorSpy.firstCall.args[2]).to.equal('transactionMerkleTree'); - blockRouteMerkleProcessorSpy.restore(); - }); - }); -}); diff --git a/rest/test/routes/chainRoutes_spec.js b/rest/test/routes/chainRoutes_spec.js deleted file mode 100644 index 76a46dc53..000000000 --- a/rest/test/routes/chainRoutes_spec.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer, test } = require('./utils/routeTestUtils'); -const chainRoutes = require('../../src/routes/chainRoutes'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { Binary, Long } = MongoDb; - -describe('chain routes', () => { - describe('get', () => { - it('can retrieve info', () => { - // Arrange: - const chainStatisticData = { - height: Long.fromNumber(33), - scoreHigh: Long.fromNumber(44), - scoreLow: Long.fromNumber(55) - }; - const chainStatisticCurrentFake = sinon.fake(() => Promise.resolve(chainStatisticData)); - const finalizedBlockData = { - height: Long.fromNumber(222), - hash: new Binary(test.random.hash()), - finalizationEpoch: 777, - finalizationPoint: 111 - }; - const latestFinalizedBlockFake = sinon.fake(() => Promise.resolve(latestFinalizedBlockFake)); - - const mockServer = new MockServer(); - const db = { chainStatisticCurrent: chainStatisticCurrentFake, latestFinalizedBlock: latestFinalizedBlockFake }; - chainRoutes.register(mockServer.server, db, {}); - const route = mockServer.getRoute('/chain/info').get(); - - // Act: - return mockServer.callRoute(route, { params: {} }).then(() => { - expect(chainStatisticCurrentFake.calledOnce).to.equal(true); - expect(latestFinalizedBlockFake.calledOnce).to.equal(true); - - const expectedData = chainStatisticData; - expectedData.latestFinalizedBlock = finalizedBlockData; - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: expectedData, - type: 'chainInfo' - }); - }); - }); - }); -}); diff --git a/rest/test/routes/dbFacade_spec.js b/rest/test/routes/dbFacade_spec.js deleted file mode 100644 index 2f64a6261..000000000 --- a/rest/test/routes/dbFacade_spec.js +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const CatapultDb = require('../../src/db/CatapultDb'); -const { convertToLong } = require('../../src/db/dbUtils'); -const dbFacade = require('../../src/routes/dbFacade'); -const testDbOptions = require('../db/utils/testDbOptions'); -const { expect } = require('chai'); -const { Binary } = require('mongodb'); -const sinon = require('sinon'); - -const Testnet_Network = testDbOptions.networkId; - -describe('db facade', () => { - describe('run height dependent operation', () => { - const runHeightDependentOperationTest = (requestHeight, chainHeight, isRequestValid) => { - // Arrange: - const db = { chainStatisticCurrent: () => Promise.resolve({ height: convertToLong(chainHeight) }) }; - - // Act: - return dbFacade.runHeightDependentOperation(db, requestHeight, () => Promise.resolve(17)) - .then(result => { - expect(result).to.deep.equal({ - isRequestValid, - payload: isRequestValid ? 17 : undefined - }); - }); - }; - - it('returns operation result when request height is less than chain height', () => runHeightDependentOperationTest(3, 10, true)); - it('returns operation result when request height is equal to chain height', () => runHeightDependentOperationTest(10, 10, true)); - it('returns undefined when request height is greater than chain height', () => runHeightDependentOperationTest(11, 10, false)); - }); - - describe('transaction statuses by hashes', () => { - const addTransactionStatusesByHashesTest = traits => { - // Arrange: - const transactionsByHashesFailedStub = sinon.stub(CatapultDb.prototype, 'transactionsByHashesFailed') - .returns(Promise.resolve(traits.failed || [])); - const transactionsByHashesStub = sinon.stub(CatapultDb.prototype, 'transactionsByHashes') - .callsFake(group => Promise.resolve(traits[group] || [])); - - // Act: - const hashes = [1, 2, 3, 4]; - const transactionStates = [{ dbPostfix: 'Custom', friendlyName: 'custom' }]; - const db = new CatapultDb({ networkId: Testnet_Network }); - return dbFacade.transactionStatusesByHashes(db, hashes, transactionStates).then(result => { - expect(transactionsByHashesFailedStub.withArgs(hashes).callCount).to.equal(1); - expect(transactionsByHashesStub.withArgs('confirmed', hashes).callCount).to.equal(1); - expect(transactionsByHashesStub.withArgs('unconfirmed', hashes).callCount).to.equal(1); - expect(transactionsByHashesStub.withArgs('custom', hashes).callCount).to.equal(1); - - expect(result).to.deep.equal(traits.expected); - - transactionsByHashesFailedStub.restore(); - transactionsByHashesStub.restore(); - }); - }; - const toBinary = hash => new Binary(`${hash}`); - - const createFailed = (value, hash) => ({ status: { f: value, hash: toBinary(hash) } }); - const createUnwrappedFailedStatus = (value, hash) => ({ group: 'failed', f: value, hash: toBinary(hash) }); - const createTransaction = (hash, deadline, height) => ({ meta: { hash: toBinary(hash), height }, transaction: { deadline } }); - const createUnconfirmedStatus = (hash, deadline) => ({ - group: 'unconfirmed', code: 0, hash: toBinary(hash), deadline, height: 0 - }); - const createConfirmedStatus = (hash, deadline, height) => ({ - group: 'confirmed', code: 0, hash: toBinary(hash), deadline, height - }); - const createUnwrappedCustomStatus = (hash, deadline, height) => ({ - group: 'custom', code: 0, hash: toBinary(hash), deadline, height - }); - - it('unknown hashes are properly mapped', () => - addTransactionStatusesByHashesTest({ - expected: [] - })); - - it('failed transactions have type appended', () => - addTransactionStatusesByHashesTest({ - failed: [createFailed(123, 11111), createFailed(456, 22222)], - expected: [createUnwrappedFailedStatus(123, 11111), createUnwrappedFailedStatus(456, 22222)] - })); - - it('unconfirmed transactions are properly mapped', () => - addTransactionStatusesByHashesTest({ - unconfirmed: [createTransaction(111, 222, 0), createTransaction(333, 444, 0)], - expected: [createUnconfirmedStatus(111, 222), createUnconfirmedStatus(333, 444)] - })); - - it('confirmed transactions are properly mapped', () => - addTransactionStatusesByHashesTest({ - confirmed: [createTransaction(55, 66, 77), createTransaction(88, 99, 11)], - expected: [createConfirmedStatus(55, 66, 77), createConfirmedStatus(88, 99, 11)] - })); - - it('custom transactions are properly mapped', () => - addTransactionStatusesByHashesTest({ - custom: [createTransaction(87, 98, 43), createTransaction(34, 89, 22)], - expected: [createUnwrappedCustomStatus(87, 98, 43), createUnwrappedCustomStatus(34, 89, 22)] - })); - - it('mixed elements are properly mapped', () => - addTransactionStatusesByHashesTest({ - failed: [createFailed(123, 1111), createFailed(456, 88), createFailed(456, 22222)], - unconfirmed: [createTransaction(111, 222, 0), createTransaction(333, 444, 0), createTransaction(55, 444, 0)], - confirmed: [createTransaction(55, 66, 77), createTransaction(88, 99, 11)], - custom: [createTransaction(111, 98, 43), createTransaction(87, 98, 43)], - expected: [ - createConfirmedStatus(55, 66, 77), createConfirmedStatus(88, 99, 11), - createUnconfirmedStatus(111, 222), createUnconfirmedStatus(333, 444), - createUnwrappedCustomStatus(87, 98, 43), - createUnwrappedFailedStatus(123, 1111), createUnwrappedFailedStatus(456, 22222) - - ] - })); - }); -}); diff --git a/rest/test/routes/finalizationRoutes_spec.js b/rest/test/routes/finalizationRoutes_spec.js deleted file mode 100644 index 9d4d312d6..000000000 --- a/rest/test/routes/finalizationRoutes_spec.js +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer } = require('./utils/routeTestUtils'); -const finalizationRoutes = require('../../src/routes/finalizationRoutes'); -const routeResultTypes = require('../../src/routes/routeResultTypes'); -const { expect } = require('chai'); - -describe('finalization routes', () => { - describe('get', () => { - const size = Buffer.from([0x38, 0x00, 0x00, 0x00]); // 4b - const version = Buffer.from([0x64, 0x00, 0x00, 0x00]); // 4b - const finalizationEpoch = Buffer.from([0x02, 0x00, 0x00, 0x00]); // 4b - const finalizationPoint = Buffer.from([0x01, 0x00, 0x00, 0x00]); // 4b - const height = Buffer.from([0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); // 8b - const hash = Buffer.from([ // 32b - 0xC3, 0xC4, 0xDE, 0xA0, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0xBB, 0x00, 0xFF, 0x11, 0xFF, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0xF8, 0xF3 - ]); - - const serviceCreator = (resultPacket, assertSentPacket) => ({ - connections: { - singleUse: () => new Promise(resolve => { - resolve({ - pushPull: packet => { - assertSentPacket(packet); - return new Promise(innerResolve => innerResolve(resultPacket)); - } - }); - }) - }, - config: { - apiNode: { timeout: 1000 } - } - }); - - const createFinalizationProofResultPacket = () => { - const finalizationProof = [ - size, version, finalizationEpoch, finalizationPoint, height, hash - ]; - const finalizationProofBuffer = Buffer.concat(finalizationProof); - finalizationProofBuffer.writeInt32LE(finalizationProofBuffer.length, 0); - - return { packetSize: finalizationProofBuffer.length, packetPayload: finalizationProofBuffer }; - }; - - describe('finalization proof', () => { - describe('by epoch', () => { - const endpointUnderTest = '/finalization/proof/epoch/:epoch'; - - it('parses params and creates correct request packet', () => { - // Arrange: - const mockServer = new MockServer(); - const { packetSize, packetPayload } = createFinalizationProofResultPacket(); - const resultPacket = { - type: 0x133, - size: packetSize, - payload: packetPayload - }; - - const assertSentPacket = packet => { - // 0c 00 00 00 size => 12b - // 33 01 00 00 type => 307 - // 0b 00 00 00 epoch => 11 - - expect(packet).to.deep.equal(Buffer.from([ - 0x0c, 0x00, 0x00, 0x00, 0x33, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00 - ])); - }; - - finalizationRoutes.register(mockServer.server, {}, serviceCreator(resultPacket, assertSentPacket)); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - return mockServer.callRoute(route, { params: { epoch: '11' } }).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns correct finalization proof', () => { - // Arrange: - const mockServer = new MockServer(); - const { packetSize, packetPayload } = createFinalizationProofResultPacket(); - const resultPacket = { - type: 0x133, - size: packetSize, - payload: packetPayload - }; - - finalizationRoutes.register(mockServer.server, {}, serviceCreator(resultPacket, () => {})); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - return mockServer.callRoute(route, { params: { epoch: '11' } }).then(() => { - // Assert: - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: { - version: 100, - finalizationEpoch: 2, - finalizationPoint: 1, - height: [10, 0], - hash, - messageGroups: [] - }, - formatter: 'ws', - type: routeResultTypes.finalizationProof - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns not found if no payload is found', () => { - // Arrange: - const mockServer = new MockServer(); - const { packetSize } = createFinalizationProofResultPacket(); - const resultPacket = { - type: 0x133, - size: packetSize, - payload: Buffer.from([]) - }; - - finalizationRoutes.register(mockServer.server, {}, serviceCreator(resultPacket, () => {})); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - return mockServer.callRoute(route, { params: { epoch: '11' } }).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - }); - }); - - describe('by height', () => { - const endpointUnderTest = '/finalization/proof/height/:height'; - - it('parses params and creates correct request packet', () => { - // Arrange: - const mockServer = new MockServer(); - const { packetSize, packetPayload } = createFinalizationProofResultPacket(); - const resultPacket = { - type: 0x134, - size: packetSize, - payload: packetPayload - }; - - const assertSentPacket = packet => { - // 10 00 00 00 size => 16b - // 34 01 00 00 type => 308 - // 00 04 00 00 00 00 00 00 height => 1024 - - expect(packet).to.deep.equal(Buffer.from([ - 0x10, 0x00, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - ])); - }; - - finalizationRoutes.register(mockServer.server, {}, serviceCreator(resultPacket, assertSentPacket)); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - return mockServer.callRoute(route, { params: { height: '1024' } }).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns correct finalization proof', () => { - // Arrange: - const mockServer = new MockServer(); - const { packetSize, packetPayload } = createFinalizationProofResultPacket(); - const resultPacket = { - type: 0x134, - size: packetSize, - payload: packetPayload - }; - - finalizationRoutes.register(mockServer.server, {}, serviceCreator(resultPacket, () => {})); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - return mockServer.callRoute(route, { params: { height: '1024' } }).then(() => { - // Assert: - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: { - version: 100, - finalizationEpoch: 2, - finalizationPoint: 1, - height: [10, 0], - hash, - messageGroups: [] - }, - formatter: 'ws', - type: routeResultTypes.finalizationProof - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns not found if no payload is found', () => { - // Arrange: - const mockServer = new MockServer(); - const { packetSize } = createFinalizationProofResultPacket(); - const resultPacket = { - type: 0x134, - size: packetSize, - payload: Buffer.from([]) - }; - - finalizationRoutes.register(mockServer.server, {}, serviceCreator(resultPacket, () => {})); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - return mockServer.callRoute(route, { params: { height: '1024' } }).then(() => { - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - }); - }); - }); - }); -}); diff --git a/rest/test/routes/networkRoutes_spec.js b/rest/test/routes/networkRoutes_spec.js deleted file mode 100644 index 5ff378e47..000000000 --- a/rest/test/routes/networkRoutes_spec.js +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer, test } = require('./utils/routeTestUtils'); -const networkRoutes = require('../../src/routes/networkRoutes'); -const { expect } = require('chai'); -const sinon = require('sinon'); -const fs = require('fs'); - -describe('network routes', () => { - describe('get', () => { - describe('network', () => { - it('can retrieve network info', () => { - // Act: - const services = { config: { network: { name: 'foo', description: 'bar' } } }; - return test.route.prepareExecuteRoute(networkRoutes.register, '/network', 'get', {}, {}, services, routeContext => { - // - invoke route synchronously - routeContext.routeInvoker(); - - // Assert: - expect(routeContext.numNextCalls, 'next should be called once').to.equal(1); - expect(routeContext.responses.length, 'single response is expected').to.equal(1); - expect(routeContext.redirects.length, 'no redirects are expected').to.equal(0); - - // - no type information because formatting is completely bypassed - const response = routeContext.responses[0]; - expect(response).to.deep.equal({ - name: services.config.network.name, - description: services.config.network.description - }); - }); - }); - - it('skips network info not explicitly included', () => { - // Act: - const services = { config: { network: { name: 'foo', description: 'bar', head: 'fuu' } } }; - return test.route.prepareExecuteRoute(networkRoutes.register, '/network', 'get', {}, {}, services, routeContext => { - // - invoke route synchronously - routeContext.routeInvoker(); - - const response = routeContext.responses[0]; - expect(response).to.deep.equal({ - name: services.config.network.name, - description: services.config.network.description - }); - }); - }); - }); - - describe('network properties', () => { - it('can retrieve network properties', () => { - const readFileStub = sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, '[network]\n' - + 'identifier = testnet\n' - + '[chain]\n' - + 'enableVerifiableState = true\n' - + '[plugin:catapult.plugins.aggregate]\n' - + 'maxTransactionsPerAggregate = 1\'000')); - - const services = { config: { apiNode: { networkPropertyFilePath: 'wouldBeValidFilePath' } } }; - const mockServer = new MockServer(); - - networkRoutes.register(mockServer.server, {}, services); - - const route = mockServer.getRoute('/network/properties').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - network: { identifier: 'testnet' }, - chain: { enableVerifiableState: true }, - plugins: { aggregate: { maxTransactionsPerAggregate: '1\'000' } } - }); - readFileStub.restore(); - }); - }); - - it('skips non-explicit properties', () => { - const readFileStub = sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, '[network]\n' - + 'identifier = testnet\n' - + '[chain]\n' - + 'enableVerifiableState = true\n' - + '[private]\n' - + 'secretCode = 42\n' - + '[plugin:catapult.plugins.aggregate]\n' - + 'maxTransactionsPerAggregate = 1\'000')); - - const services = { config: { apiNode: { networkPropertyFilePath: 'wouldBeValidFilePath' } } }; - const mockServer = new MockServer(); - - networkRoutes.register(mockServer.server, {}, services); - - const route = mockServer.getRoute('/network/properties').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - network: { identifier: 'testnet' }, - chain: { enableVerifiableState: true }, - plugins: { aggregate: { maxTransactionsPerAggregate: '1\'000' } } - }); - readFileStub.restore(); - }); - }); - - it('errors if no file path specified', () => { - const mockServer = new MockServer(); - networkRoutes.register(mockServer.server, {}, { config: { apiNode: {} } }); - - const route = mockServer.getRoute('/network/properties').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.send.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.send.firstCall.args[0].message).to.equal('there was an error reading the network properties file'); - }); - }); - - it('errors when the file has an invalid format', () => { - const readFileStub = sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, '{ "not": "iniFormat" }')); - - const services = { config: { apiNode: {} } }; - const mockServer = new MockServer(); - - networkRoutes.register(mockServer.server, {}, services); - - const route = mockServer.getRoute('/network/properties').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.send.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.send.firstCall.args[0].message).to.equal('there was an error reading the network properties file'); - readFileStub.restore(); - }); - }); - - it('errors if the file does not exist', () => { - const mockServer = new MockServer(); - networkRoutes.register(mockServer.server, {}, { config: { apiNode: { networkPropertyFilePath: 'nowaythispath€xists' } } }); - - const route = mockServer.getRoute('/network/properties').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.send.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.send.firstCall.args[0].message).to.equal('there was an error reading the network properties file'); - }); - }); - }); - - describe('network fees transaction', () => { - let readFileStub = null; - afterEach(() => { - if (null !== readFileStub) { - readFileStub.restore(); - readFileStub = null; - } - }); - const runNetworkFeesTest = (testName, feeMultipliers, average, median, max, min) => { - const services = { - config: { - numBlocksTransactionFeeStats: feeMultipliers.length, - apiNode: { - nodePropertyFilePath: 'node.properties', - networkPropertyFilePath: 'network.properties' - } - } - }; - - const dbLatestBlocksFeeMultiplierFake = sinon.fake.resolves(feeMultipliers); - const db = { - latestBlocksFeeMultiplier: dbLatestBlocksFeeMultiplierFake - }; - - it(`${testName}: [${feeMultipliers}] average:${average}, median:${median}, max:${max}, min:${min}`, () => { - readFileStub = sinon.stub(fs, 'readFile'); - readFileStub.onFirstCall().callsFake((path, data, callback) => - callback(null, '[node]\n' - + 'minFeeMultiplier = 100')); - readFileStub.onSecondCall().callsFake((path, data, callback) => - callback(null, '[chain]\n' - + 'defaultDynamicFeeMultiplier = 1\'000')); - - // Arrange: - const mockServer = new MockServer(); - networkRoutes.register(mockServer.server, db, services); - const route = mockServer.getRoute('/network/fees/transaction').get(); - - // Act - return mockServer.callRoute(route, {}).then(() => { - // Assert - expect(dbLatestBlocksFeeMultiplierFake.calledOnce).to.equal(true); - expect(dbLatestBlocksFeeMultiplierFake.firstCall.args[0]).to.equal(feeMultipliers.length); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - averageFeeMultiplier: average, - medianFeeMultiplier: median, - highestFeeMultiplier: max, - lowestFeeMultiplier: min, - minFeeMultiplier: 100 - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }; - - describe('network fees are computed correctly for the following values', () => { - runNetworkFeesTest('One block', [0], 1000, 1000, 0, 0); - runNetworkFeesTest('All 0s', [0, 0, 0, 0, 0], 1000, 1000, 0, 0); - runNetworkFeesTest('With 0s', [10, 0, 0, 0, 10], 604, 1000, 10, 0); - runNetworkFeesTest('Big values', [999999999, 999999999, 999999999, 999999999], 999999999, 999999999, 999999999, 999999999); - runNetworkFeesTest('Correct average', [1, 1, 1, 1], 1, 1, 1, 1); - runNetworkFeesTest('Correct median', [90, 92, 93, 88, 95, 88, 97, 87, 98], 92, 92, 98, 87); - runNetworkFeesTest('Correct median even number', [35, 27, 31, 32, 30, 40, 29, 43], 33, 31, 43, 27); - runNetworkFeesTest('Correct decimals floor', [10, 11, 12, 13], 11, 11, 13, 10); - runNetworkFeesTest('Correct decimals floor', [23, 29, 31, 27], 27, 28, 31, 23); - }); - }); - - describe('network effective rental fees', () => { - let readFileStub = null; - afterEach(() => { - if (null !== readFileStub) { - readFileStub.restore(); - readFileStub = null; - } - }); - - it('can retrieve network properties needed for rental fees', () => { - readFileStub = sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, '[chain]\n' - + 'maxDifficultyBlocks = 5\n' - + 'defaultDynamicFeeMultiplier = 1\'000\n' - + '[plugin:catapult.plugins.namespace]\n' - + 'rootNamespaceRentalFeePerBlock = 1\'000\n' - + 'childNamespaceRentalFee = 100\n' - + '[plugin:catapult.plugins.mosaic]\n' - + 'mosaicRentalFee = 500')); - - const dbLatestBlocksFeeMultiplierFake = sinon.fake.resolves([0, 1, 2, 3, 4]); - const db = { - latestBlocksFeeMultiplier: dbLatestBlocksFeeMultiplierFake - }; - const services = { config: { apiNode: { networkPropertyFilePath: 'wouldBeValidFilePath' } } }; - const mockServer = new MockServer(); - - networkRoutes.register(mockServer.server, db, services); - - const route = mockServer.getRoute('/network/fees/rental').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - effectiveChildNamespaceRentalFee: '300', - effectiveMosaicRentalFee: '1500', - effectiveRootNamespaceRentalFeePerBlock: '3000' - }); - }); - }); - - it('errors if no file path specified', () => { - const mockServer = new MockServer(); - networkRoutes.register(mockServer.server, {}, { config: { apiNode: {} } }); - - const route = mockServer.getRoute('/network/fees/rental').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.send.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.send.firstCall.args[0].message).to.equal('there was an error reading the network properties file'); - }); - }); - - it('errors when the file has an invalid format', () => { - readFileStub = sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, '{ "not": "iniFormat" }')); - - const services = { config: { apiNode: {} } }; - const mockServer = new MockServer(); - - networkRoutes.register(mockServer.server, {}, services); - - const route = mockServer.getRoute('/network/fees/rental').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.send.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.send.firstCall.args[0].message).to.equal('there was an error reading the network properties file'); - }); - }); - - it('errors if the file does not exist', () => { - const mockServer = new MockServer(); - networkRoutes.register(mockServer.server, {}, { config: { apiNode: { networkPropertyFilePath: 'nowaythispath€xists' } } }); - - const route = mockServer.getRoute('/network/fees/rental').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.send.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.send.firstCall.args[0].message).to.equal('there was an error reading the network properties file'); - }); - }); - - const runNetworkEffectiveRentalFeesTest = ( - testName, - maxDifficultyBlocks, - defaultDynamicFeeMultiplier, - rootNamespaceRentalFeePerBlock, - childNamespaceRentalFee, - mosaicRentalFee, - feeMultipliers, - effectiveRootNamespaceRentalFeePerBlock, - effectiveChildNamespaceRentalFee, - effectiveMosaicRentalFee - ) => { - it(`${testName}: [${[feeMultipliers]}]`, () => { - readFileStub = sinon.stub(fs, 'readFile').callsFake((path, data, callback) => - callback(null, '[chain]\n' - + `maxDifficultyBlocks = ${maxDifficultyBlocks}\n` - + `defaultDynamicFeeMultiplier = ${defaultDynamicFeeMultiplier}\n` - + '[plugin:catapult.plugins.namespace]\n' - + `rootNamespaceRentalFeePerBlock = ${rootNamespaceRentalFeePerBlock}\n` - + `childNamespaceRentalFee = ${childNamespaceRentalFee}\n` - + '[plugin:catapult.plugins.mosaic]\n' - + `mosaicRentalFee = ${mosaicRentalFee}`)); - - const dbLatestBlocksFeeMultiplierFake = sinon.fake.resolves(feeMultipliers); - const db = { - latestBlocksFeeMultiplier: dbLatestBlocksFeeMultiplierFake - }; - const services = { config: { apiNode: { networkPropertyFilePath: 'wouldBeValidFilePath' } } }; - const mockServer = new MockServer(); - - networkRoutes.register(mockServer.server, db, services); - - const route = mockServer.getRoute('/network/fees/rental').get(); - return mockServer.callRoute(route).then(() => { - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - effectiveChildNamespaceRentalFee, - effectiveMosaicRentalFee, - effectiveRootNamespaceRentalFeePerBlock - }); - }); - }); - }; - - describe('network effective rental fees are computed correctly for the following values', () => { - runNetworkEffectiveRentalFeesTest( - 'Simple all 1', 1, - 0, 1, 1, 1, [1], - '1', '1', '1' - ); - runNetworkEffectiveRentalFeesTest( - 'No need for default dynamic fee multiplier', 3, - 0, 1, 1, 1, [1, 2, 3], - '2', '2', '2' - ); - runNetworkEffectiveRentalFeesTest( - 'Default dynamic fee multiplier applied', 3, - 5, 1, 1, 1, [5, 0, 5], - '5', '5', '5' - ); - runNetworkEffectiveRentalFeesTest( - 'Standard case', 5, - 0, 1, 2, 3, [10, 10, 25, 50, 50], - '25', '50', '75' - ); - runNetworkEffectiveRentalFeesTest( - 'Decimals', 6, - 0, 1, 1, 1, [10, 10, 20, 29, 50, 50], - '24', '24', '24' - ); - runNetworkEffectiveRentalFeesTest( - 'Random case', 12, - 0, 1, 55, 28, [25, 32, 77, 9, 1, 50, 11, 4, 89, 56], - '28', '1540', '784' - ); - runNetworkEffectiveRentalFeesTest( - 'Big numbers', 3, - 0, '4294967295', '67632967295', '9007199254740993', [25, 32, 77], - '137438953440', '2164254953440', '288230376151711776' - ); - }); - }); - }); -}); diff --git a/rest/test/routes/nodeRoutes_spec.js b/rest/test/routes/nodeRoutes_spec.js deleted file mode 100644 index 06783cd32..000000000 --- a/rest/test/routes/nodeRoutes_spec.js +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer, test } = require('./utils/routeTestUtils'); -const nodeRoutes = require('../../src/routes/nodeRoutes'); -const errors = require('../../src/server/errors'); -const { expect } = require('chai'); -const fs = require('fs'); -const path = require('path'); - -// ATM, both rest and rest sdk share the same version. In the future, -// we will have an open api and sdk dependencies with their given versions. -const restVersion = fs.readFileSync(path.resolve(__dirname, '../../../version.txt'), 'UTF-8').trim(); -const sdkVersion = restVersion; - -describe('node routes', () => { - describe('get', () => { - const serviceCreator = packet => ({ - connections: { - singleUse: () => new Promise(resolve => { - resolve({ - pushPull: () => new Promise(innerResolve => innerResolve(packet)) - }); - }) - }, - config: { - apiNode: { timeout: 1000 }, - deployment: { - deploymentTool: 'symbol-bootstrap', - deploymentToolVersion: '1.0.2', - lastUpdatedDate: '1900-01-01' - } - } - }); - - describe('node health', () => { - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashSeedBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packet = { - type: 601, - size: 57, - payload: Buffer.concat([ - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]) // friendly name size - ]) - }; - - const createMockDb = status => ({ - database: { - serverConfig: { - isConnected: () => status - } - } - }); - - it('can check node health', () => { - // Arrange: - const services = serviceCreator(packet); - const mockServer = new MockServer(); - nodeRoutes.register(mockServer.server, createMockDb(true), services); - const route = mockServer.getRoute('/node/health').get(); - - // Act - return mockServer.callRoute(route, {}).then(() => { - // Assert - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: { - status: { - apiNode: 'up', - db: 'up' - } - }, - type: 'nodeHealth' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns status code 200 when all services are up', () => { - // Arrange: - const services = serviceCreator(packet); - const mockServer = new MockServer(); - nodeRoutes.register(mockServer.server, createMockDb(true), services); - const route = mockServer.getRoute('/node/health').get(); - - // Act - return mockServer.callRoute(route, {}).then(() => { - // Assert - expect(mockServer.status.firstCall.args[0]).to.equal(200); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns status code 503 when any service is down', () => { - // Arrange: - const services = serviceCreator(packet); - const mockServer = new MockServer(); - nodeRoutes.register(mockServer.server, createMockDb(false), services); - const route = mockServer.getRoute('/node/health').get(); - - // Act - return mockServer.callRoute(route, {}).then(() => { - // Assert - expect(mockServer.status.firstCall.args[0]).to.equal(503); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns down when apiNode service fails partially', () => { - // Arrange: - const badPacket = { - type: 601, - size: 57, - payload: Buffer.concat([ - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]) // version - // missing fields make it a packet that can not be parsed correctly - ]) - }; - const services = serviceCreator(badPacket); - const mockServer = new MockServer(); - nodeRoutes.register(mockServer.server, createMockDb(true), services); - const route = mockServer.getRoute('/node/health').get(); - - // Act - return mockServer.callRoute(route, {}).then(() => { - // Assert - expect(mockServer.status.firstCall.args[0]).to.equal(503); - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: { - status: { - apiNode: 'down', - db: 'up' - } - }, - type: 'nodeHealth' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('returns down when apiNode service fails completely', () => { - // Arrange: - const failingService = { - connections: { - singleUse: () => new Promise(resolve => { - resolve({ - pushPull: () => Promise.reject(errors.createServiceUnavailableError('connection failed')) - }); - }) - }, - config: { - apiNode: { timeout: 1000 } - } - }; - - const mockServer = new MockServer(); - nodeRoutes.register(mockServer.server, createMockDb(true), failingService); - const route = mockServer.getRoute('/node/health').get(); - - // Act - return mockServer.callRoute(route, {}).then(() => { - // Assert - expect(mockServer.status.firstCall.args[0]).to.equal(503); - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: { - status: { - apiNode: 'down', - db: 'up' - } - }, - type: 'nodeHealth' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - - describe('node information', () => { - it('can retrieve node information', () => { - // Arrange: - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashSeedBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - - const nodePublicKeyBuffer = Buffer.from([ - 0xE4, 0x28, 0xC1, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - - const packet = { - type: 601, - size: 57, - payload: Buffer.concat([ - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]) // friendly name size - ]) - }; - const services = serviceCreator(packet); - services.config.apiNode.nodePublicKey = nodePublicKeyBuffer; - - // Act: - return test.route.prepareExecuteRoute(nodeRoutes.register, '/node/info', 'get', {}, {}, services, routeContext => - routeContext.routeInvoker().then(() => { - // Assert: - expect(routeContext.numNextCalls).to.equal(1); - expect(routeContext.responses.length).to.equal(1); - expect(routeContext.redirects.length).to.equal(0); - expect(routeContext.responses[0]).to.deep.equal({ - formatter: 'ws', - payload: { - friendlyName: Buffer.alloc(0), - host: Buffer.alloc(0), - networkIdentifier: 144, - port: 7900, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - nodePublicKey: nodePublicKeyBuffer, - roles: 2, - version: 23 - }, - type: 'nodeInfo' - }); - })); - }); - }); - - describe('node peers', () => { - it('can retrieve node peers', () => { - // Arrange: - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashSeedBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - - const packet = { - type: 603, - size: 114, - payload: Buffer.concat([ - // First peer - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]), // friendly name size - - // Second peer - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x18, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x03, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]) // friendly name size - ]) - }; - - const services = serviceCreator(packet); - - // Act: - return test.route.prepareExecuteRoute(nodeRoutes.register, '/node/peers', 'get', {}, {}, services, routeContext => - routeContext.routeInvoker().then(() => { - // Assert: - expect(routeContext.numNextCalls).to.equal(1); - expect(routeContext.responses.length).to.equal(1); - expect(routeContext.redirects.length).to.equal(0); - expect(routeContext.responses[0]).to.deep.equal({ - formatter: 'ws', - payload: [{ - friendlyName: Buffer.alloc(0), - host: Buffer.alloc(0), - networkIdentifier: 144, - port: 7900, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - roles: 2, - version: 23 - }, - { - friendlyName: Buffer.alloc(0), - host: Buffer.alloc(0), - networkIdentifier: 144, - port: 7900, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - roles: 3, - version: 24 - }], - type: 'nodeInfo' - }); - })); - }); - }); - - describe('node server', () => { - it('can retrieve server info', () => { - // Arrange: - const endpointUnderTest = '/node/server'; - const mockServer = new MockServer(); - nodeRoutes.register(mockServer.server, {}, serviceCreator({})); - - // Act: - const route = mockServer.getRoute(endpointUnderTest).get(); - mockServer.callRoute(route, {}); - - // Assert: - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: { - serverInfo: { - restVersion, - sdkVersion, - deployment: { - deploymentTool: 'symbol-bootstrap', - deploymentToolVersion: '1.0.2', - lastUpdatedDate: '1900-01-01' - } - } - }, - type: 'serverInfo' - }); - }); - }); - - describe('node storage', () => { - const executeRoute = (routeName, db, assertResponse) => - test.route.executeSingle(nodeRoutes.register, routeName, 'get', {}, db, serviceCreator({}).config, assertResponse); - - const createMockStorageInfoDb = (numBlocks, numTransactions, numAccounts) => ({ - storageInfo: () => Promise.resolve({ numBlocks, numTransactions, numAccounts }) - }); - - it('can retrieve node storage', () => { - // Arrange: - const db = createMockStorageInfoDb(2, 64, 9); - - // Act: - return executeRoute('/node/storage', db, response => { - // Assert: - expect(response).to.deep.equal({ - payload: { numBlocks: 2, numTransactions: 64, numAccounts: 9 }, - type: 'storageInfo' - }); - }); - }); - }); - - describe('node time', () => { - it('can retrieve node time', () => { - // Arrange: - const packet = { - type: 700, - size: 24, - payload: Buffer.from([0x90, 0xF8, 0x6D, 0x06, 0x01, 0x00, 0x00, 0x00, 0x90, 0xF8, 0x6D, 0x06, 0x10, 0x00, 0x00, 0x00]) - }; - const services = serviceCreator(packet); - - // Act: - return test.route.prepareExecuteRoute(nodeRoutes.register, '/node/time', 'get', {}, {}, services, routeContext => - routeContext.routeInvoker().then(() => { - // Assert: - expect(routeContext.numNextCalls).to.equal(1); - expect(routeContext.responses.length).to.equal(1); - expect(routeContext.redirects.length).to.equal(0); - expect(routeContext.responses[0]).to.deep.equal({ - formatter: 'ws', - payload: { - communicationTimestamps: { - receiveTimestamp: [107870352, 16], - sendTimestamp: [107870352, 1] - } - }, - type: 'nodeTime' - }); - })); - }); - }); - - describe('unlocked account', () => { - it('can retrieve unlocked account', () => { - // Arrange: - const packet = { - type: 772, - size: 40, - payload: Buffer.from([0x9b, 0x4E, 0xF2, 0x78, 0x9b, 0x4E, 0xF2, 0x78, 0x9b, - 0x4E, 0xF2, 0x78, 0x9b, 0x4E, 0xF2, 0x78, 0x9b, 0x4E, 0xF2, 0x78, 0x9b, - 0x4E, 0xF2, 0x78, 0x9b, 0x4E, 0xF2, 0x78, 0x9b, 0x4E, 0xF2, 0x78]) - }; - const services = serviceCreator(packet); - - // Act: - return test.route.prepareExecuteRoute(nodeRoutes.register, '/node/unlockedaccount', 'get', {}, {}, services, routeContext => - routeContext.routeInvoker().then(() => { - // Assert: - expect(routeContext.numNextCalls).to.equal(1); - expect(routeContext.responses.length).to.equal(1); - expect(routeContext.redirects.length).to.equal(0); - expect(routeContext.responses[0]).to.deep.equal({ - unlockedAccount: [ - '9B4EF2789B4EF2789B4EF2789B4EF2789B4EF2789B4EF2789B4EF2789B4EF278' - ] - }); - })); - }); - }); - }); -}); diff --git a/rest/test/routes/routeResultTypes_spec.js b/rest/test/routes/routeResultTypes_spec.js deleted file mode 100644 index 5439a417d..000000000 --- a/rest/test/routes/routeResultTypes_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const routeResultTypes = require('../../src/routes/routeResultTypes'); -const { expect } = require('chai'); - -describe('routeResultTypes', () => { - it('has correct links to schema', () => { - expect(Object.keys(routeResultTypes).length).to.equal(18); - expect(routeResultTypes).to.deep.equal({ - account: 'accountWithMetadata', - block: 'blockHeaderWithMetadata', - transaction: 'transactionWithMetadata', - chainInfo: 'chainInfo', - merkleProofInfo: 'merkleProofInfo', - finalizationProof: 'finalizationProof', - metadata: 'metadata', - stateTree: 'stateTree', - addressResolutionStatement: 'addressResolutionStatement', - mosaicResolutionStatement: 'mosaicResolutionStatement', - transactionStatement: 'transactionStatement', - transactionStatus: 'transactionStatus', - nodeInfo: 'nodeInfo', - nodeTime: 'nodeTime', - nodeHealth: 'nodeHealth', - mosaicRestrictions: 'mosaicRestrictions', - serverInfo: 'serverInfo', - storageInfo: 'storageInfo' - }); - }); -}); diff --git a/rest/test/routes/routeUtils_spec.js b/rest/test/routes/routeUtils_spec.js deleted file mode 100644 index 4b11c2b12..000000000 --- a/rest/test/routes/routeUtils_spec.js +++ /dev/null @@ -1,846 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { test } = require('./utils/routeTestUtils'); -const { convertToLong } = require('../../src/db/dbUtils'); -const routeUtils = require('../../src/routes/routeUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const MongoDb = require('mongodb'); -const sinon = require('sinon'); - -const { Binary, ObjectId } = MongoDb; -const { convert } = catapult.utils; - -const invalidObjectIdStrings = [ - '112233445566778899AABB', // too short - '112233445566778899AABBCCDD', // too long - '11223344556G778899AABBCC' // not hex (contains 'G') -]; - -describe('route utils', () => { - describe('parse argument', () => { - const addParserTests = traits => { - it('succeeds when parser does not error', () => { - traits.valid.forEach(valid => { - // Act: - const result = routeUtils.parseArgument({ foo: valid.id }, 'foo', traits.parser); - - // Assert: - expect(result).to.deep.equal(valid.parsed); - }); - }); - - it('maps parser error to 409 error', () => { - // Act: - traits.invalid.forEach(invalid => { - test.assert.invokerThrowsError(() => routeUtils.parseArgument({ foo: invalid.id }, 'foo', traits.parser), { - statusCode: 409, - message: 'foo has an invalid format' - }); - }); - }); - }; - - describe('custom', () => addParserTests({ - parser: x => { - if (8 !== x) - return x * 2; - - throw Error('something bad happened'); - }, - valid: [{ id: 7, parsed: 14 }], - invalid: [{ id: 8, error: 'something bad happened' }] - })); - - describe('objectId', () => addParserTests({ - parser: 'objectId', - valid: [ - { id: '112233445566778899AABBCC', parsed: '112233445566778899AABBCC' } - ], - invalid: invalidObjectIdStrings.map(id => ({ id, error: 'must be 12-byte hex string' })) - })); - - describe('uint', () => addParserTests({ - parser: 'uint', - valid: [ - { id: '1234', parsed: 1234 } - ], - invalid: ['-1', 'bar', '11223344556677889900'].map(id => ({ id, error: 'must be non-negative number' })) - })); - - const { - addresses, publicKeys, hashes256, hashes512 - } = test.sets; - - describe('address', () => addParserTests({ - parser: 'address', - valid: addresses.valid.map(id => ({ id, parsed: catapult.model.address.stringToAddress(id) })), - invalid: [ - { id: addresses.invalid, error: 'illegal base32 character 1' }, - { id: '12345', error: 'invalid length of address \'5\'' } - ] - })); - - describe('publicKey', () => addParserTests({ - parser: 'publicKey', - valid: publicKeys.valid.map(id => ({ id, parsed: catapult.utils.convert.hexToUint8(id) })), - invalid: [ - { id: publicKeys.invalid, error: 'unrecognized hex char \'1G\'' }, - { id: '12345', error: 'invalid length of publicKey \'5\'' } - ] - })); - - describe('accountId', () => { - describe('address', () => addParserTests({ - parser: 'accountId', - valid: addresses.valid.map(id => ({ id, parsed: ['address', catapult.model.address.stringToAddress(id)] })), - invalid: [ - { id: addresses.invalid, error: 'illegal base32 character 1' } - ] - })); - - describe('publicKey', () => addParserTests({ - parser: 'accountId', - valid: publicKeys.valid.map(id => ({ id, parsed: ['publicKey', catapult.utils.convert.hexToUint8(id)] })), - invalid: [ - { id: publicKeys.invalid, error: 'unrecognized hex char \'1G\'' } - ] - })); - - it('maps parser error to 409 error', () => { - // Arrange - const invalidAccountIds = [ - '012345678901234567890123456789012345678', // too short, 39 chars - '01234567890123456789012345678901234567890123456789', // more than 40 but less than 64 chars - '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0' // more than 64 chars - ]; - - // Act: - invalidAccountIds.forEach(str => { - test.assert.invokerThrowsError(() => routeUtils.parseArgument({ foo: str }, 'foo', 'accountId'), { - statusCode: 409, - message: 'foo has an invalid format' - }); - }); - }); - }); - - describe('hash256', () => addParserTests({ - parser: 'hash256', - valid: hashes256.valid.map(hash => ({ id: hash, parsed: catapult.utils.convert.hexToUint8(hash) })), - invalid: hashes256.invalid.map(hash => ({ id: hash, error: `invalid length of hash256 '${hash.length}` })) - })); - - describe('hash512', () => addParserTests({ - parser: 'hash512', - valid: hashes512.valid.map(hash => ({ id: hash, parsed: catapult.utils.convert.hexToUint8(hash) })), - invalid: hashes512.invalid.map(hash => ({ id: hash, error: `invalid length of hash512 '${hash.length}` })) - })); - - describe('boolean', () => addParserTests({ - parser: 'boolean', - valid: [{ id: 'true', parsed: true }, { id: 'false', parsed: false }], - invalid: [{ id: 'abcd', error: 'must be boolean value \'true\' or \'false\'' }] - })); - - describe('uint64', () => addParserTests({ - parser: 'uint64', - valid: [ - { id: '4468410971573743', parsed: [0x00ABCDEF, 0x000FDFFF] } - ], - invalid: ['-43534534', '0DC67FBE1CAD29E'].map(id => ({ id })) - })); - - describe('uint64hex', () => addParserTests({ - parser: 'uint64hex', - valid: [ - { id: '0DC67FBE1CAD29E3', parsed: [481110499, 231112638] } - ], - invalid: ['0DC67FBE', '0DC67FBE1CAD29E3245', '0DC67FBE1CAD29ER'].map(id => ({ id })) - })); - }); - - describe('parse argument array', () => { - it('succeeds when parser does not error', () => { - // Act: - const result = routeUtils.parseArgumentAsArray({ ids: [5, 8, 13] }, 'ids', id => id * 2); - - // Assert: - expect(result).to.deep.equal([10, 16, 26]); - }); - - it('non array passed to parser forcefully converts to array', () => { - // Act: - const result = routeUtils.parseArgumentAsArray({ ids: 1234 }, 'ids', id => id * 2); - - // Assert: - expect(result).to.deep.equal([2468]); - }); - - it('maps parser error to 409 error', () => { - // Arrange: - const throwIfEight = value => { - if (8 === value) - throw Error(`something bad happened, element ${value}`); - - return value + 1; - }; - - // Act + Assert: - test.assert.invokerThrowsError(() => routeUtils.parseArgumentAsArray({ ids: [5, 8, 13] }, 'ids', throwIfEight), { - statusCode: 409, - message: 'element in array ids has an invalid format' - }); - }); - }); - - describe('parse pagination arguments', () => { - const servicesConfigPageSize = { - min: 10, - max: 100, - default: 20 - }; - - const createObjectId = id => new ObjectId(`${'00'.repeat(12)}${id.toString(16)}`.slice(-24)); - - it('succeeds when no arguments are provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments({}, servicesConfigPageSize, ['id']); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('succeeds when valid page size is provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments({ pageSize: '12' }, servicesConfigPageSize, { id: 'objectId' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: 12, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('binds page size to max page size', () => { - // Act: - const options = routeUtils.parsePaginationArguments( - { pageSize: (servicesConfigPageSize.max + 1).toString() }, - servicesConfigPageSize, - { id: 'objectId' } - ); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.max, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('binds page size to min page size', () => { - // Act: - const options = routeUtils.parsePaginationArguments( - { pageSize: (servicesConfigPageSize.min - 1).toString() }, - servicesConfigPageSize, - { id: 'objectId' } - ); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.min, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('succeeds when valid page number is provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments({ pageNumber: '5' }, servicesConfigPageSize, { id: 'objectId' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 5, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('defaults page number to 1 when 0 is provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments({ pageNumber: '0' }, servicesConfigPageSize, { id: 'objectId' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('succeeds when valid sort field is provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments( - { orderBy: 'hash' }, - servicesConfigPageSize, - { id: 'objectId', hash: 'hash256' } - ); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 1, - sortField: 'hash', - sortDirection: 1 - }); - }); - - it('uses `id` sort field as default', () => { - // Act: - const options = routeUtils.parsePaginationArguments({}, servicesConfigPageSize, ['address', 'key']); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 1, - sortField: 'id', - sortDirection: 1 - }); - }); - - describe('succeeds when valid sort direction is provided', () => { - const runSortDirectionTest = (argName, order, expectedValue) => { - it(`sort argument: ${argName}`, () => { - // Act: - const options = routeUtils.parsePaginationArguments({ order }, servicesConfigPageSize, { id: 'objectId' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 1, - sortField: 'id', - sortDirection: expectedValue - }); - }); - }; - - runSortDirectionTest('asc', 'asc', 1); - runSortDirectionTest('desc', 'desc', -1); - runSortDirectionTest('other', 'abcd', 1); - }); - - it('succeeds when valid offset is provided', () => { - // Arrange - const offset = createObjectId(123).toString(); - - // Act: - const options = routeUtils.parsePaginationArguments({ offset }, servicesConfigPageSize, { id: 'objectId' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: servicesConfigPageSize.default, - pageNumber: 1, - sortField: 'id', - sortDirection: 1, - offset, - offsetType: 'objectId' - }); - }); - - it('succeeds when valid page size and page number are provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments( - { pageSize: '12', pageNumber: '5' }, - servicesConfigPageSize, - { id: 'objectId' } - ); - - // Assert: - expect(options).to.deep.equal({ - pageSize: 12, - pageNumber: 5, - sortField: 'id', - sortDirection: 1 - }); - }); - - it('succeeds when valid page size, page number, sort field and sort direction are provided', () => { - // Act: - const options = routeUtils.parsePaginationArguments({ - pageSize: '12', - pageNumber: '5', - orderBy: 'signerPublicKey', - order: 'desc' - }, servicesConfigPageSize, { signerPublicKey: 'publicKey' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: 12, - pageNumber: 5, - sortField: 'signerPublicKey', - sortDirection: -1 - }); - }); - - it('succeeds when valid page size, page number, sort field, sort direction and offset are provided', () => { - // Arrange - const offset = test.sets.publicKeys.valid[0]; - - // Act: - const options = routeUtils.parsePaginationArguments({ - pageSize: '12', - pageNumber: '5', - orderBy: 'signerPublicKey', - order: 'desc', - offset - }, servicesConfigPageSize, { signerPublicKey: 'publicKey' }); - - // Assert: - expect(options).to.deep.equal({ - pageSize: 12, - pageNumber: 5, - sortField: 'signerPublicKey', - sortDirection: -1, - offset: convert.hexToUint8(offset), - offsetType: 'publicKey' - }); - }); - - it('fails when invalid page size is provided', () => { - // Act: - expect(() => routeUtils.parsePaginationArguments({ pageSize: '1Y2' }, servicesConfigPageSize, { id: 'objectId' })) - .to.throw('pageSize is not a valid unsigned integer'); - }); - - it('fails when invalid page number is provided', () => { - // Act: - expect(() => routeUtils.parsePaginationArguments({ pageNumber: '12aa' }, servicesConfigPageSize, { id: 'objectId' })) - .to.throw('pageNumber is not a valid unsigned integer'); - }); - - it('fails when invalid sort field is provided', () => { - // Act: - expect(() => routeUtils.parsePaginationArguments( - { orderBy: 'hash' }, - servicesConfigPageSize, - { id: 'objectId', address: 'address' } - )).to.throw('sorting by hash is not allowed'); - }); - - it('fails when invalid offset is provided', () => { - // Act: - expect(() => routeUtils.parsePaginationArguments({ offset: '1Y2' }, servicesConfigPageSize, { id: 'objectId' })) - .to.throw('offset has an invalid format'); - }); - }); - - describe('sender', () => { - const sendTest = (sender, assertResponse) => { - // Arrange: set up the route params - const routeContext = { numNextCalls: 0 }; - const next = () => { ++routeContext.numNextCalls; }; - - routeContext.responses = []; - const res = { send: response => { routeContext.responses.push(response); } }; - - // Act: send the entity - sender(res, next); - - // Assert: exactly one response was sent - expect(routeContext.numNextCalls).to.equal(1); - expect(routeContext.responses.length).to.equal(1); - assertResponse(routeContext.responses[0]); - }; - - describe('send array', () => { - const send = (object, id, type, assertResponse) => { - sendTest((res, next) => routeUtils.createSender(type).sendArray(id, res, next)(object), assertResponse); - }; - - it('forwards array when defined', () => { - // Act: - send([{ alpha: 7 }], 'alpha-7', 'foo', response => { - // Assert: - expect(response).to.deep.equal({ payload: [{ alpha: 7 }], type: 'foo' }); - }); - }); - - it('sends error when not array', () => { - // Act: - send({ alpha: 7 }, 'alpha-7', 'foo', response => { - // Assert: - expect(response.body).to.deep.equal({ code: 'Internal', message: 'error retrieving data for id: \'alpha-7\'' }); - }); - }); - - it('sends error when array is undefined', () => { - // Act: - send(undefined, 'alpha-7', 'foo', response => { - // Assert: - expect(response.body).to.deep.equal({ code: 'Internal', message: 'error retrieving data for id: \'alpha-7\'' }); - }); - }); - }); - - describe('send one', () => { - const send = (object, id, type, assertResponse) => { - sendTest((res, next) => routeUtils.createSender(type).sendOne(id, res, next)(object), assertResponse); - }; - - it('forwards object when defined', () => { - // Act: - send({ alpha: 7 }, 'alpha-7', 'foo', response => { - // Assert: - expect(response).to.deep.equal({ payload: { alpha: 7 }, type: 'foo' }); - }); - }); - - it('sends error when object is undefined', () => { - // Act: - send(undefined, 'alpha-7', 'foo', response => { - // Assert: - expect(response.body).to.deep.equal({ code: 'ResourceNotFound', message: 'no resource exists with id \'alpha-7\'' }); - }); - }); - - it('forwards object in single element array when defined', () => { - // Act: - send([{ alpha: 7 }], 'alpha-7', 'foo', response => { - // Assert: - expect(response).to.deep.equal({ payload: { alpha: 7 }, type: 'foo' }); - }); - }); - - it('sends error when array is empty', () => { - // Act: - send([], 'alpha-7', 'foo', response => { - // Assert: - expect(response.body).to.deep.equal({ code: 'ResourceNotFound', message: 'no resource exists with id \'alpha-7\'' }); - }); - }); - - it('sends error when array has multiple elements', () => { - // Act: - send([{ alpha: 7 }, { beta: 6 }], 'alpha-7', 'foo', response => { - // Assert: - expect(response.body).to.deep.equal({ - code: 'Internal', - message: 'error retrieving data for id: \'alpha-7\' (length 2)' - }); - }); - }); - }); - - describe('send page', () => { - const send = (object, type, assertResponse) => { - sendTest((res, next) => routeUtils.createSender(type).sendPage(res, next)(object), assertResponse); - }; - - it('forwards valid page object', () => { - // Act: - const page = { - data: [{}], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - send(page, 'foo', response => { - // Assert: - expect(response).to.deep.equal({ payload: page, type: 'foo', structure: 'page' }); - }); - }); - - it('forwards valid empty page object', () => { - // Act: - const page = { - data: [], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - - send(page, 'foo', response => { - // Assert: - expect(response).to.deep.equal({ payload: page, type: 'foo', structure: 'page' }); - }); - }); - - it('sends error when object is not a page', () => { - // Act: - send({ alpha: 7 }, 'foo', response => { - // Assert: - expect(response.body).to.deep.equal({ code: 'Internal', message: 'error retrieving data' }); - }); - }); - }); - }); - - describe('addGetPostDocumentRoutes', () => { - const createRegistrar = postfixes => (server, db) => { - const sender = routeUtils.createSender('bar'); - const routeInfo = { - base: '/foo', singular: 'foo', plural: 'foos', postfixes - }; - routeUtils.addGetPostDocumentRoutes(server, sender, routeInfo, keys => db.foos(keys), 'uint'); - }; - - const errorMessage = 'has an invalid format'; - const basicRoutesDescriptor = { - inputs: { - valid: { object: { foo: '12345' }, parsed: [12345], printable: '12345' }, - validMultiple: { object: { foos: ['12345', '98765'] }, parsed: [12345, 98765] }, - invalid: { object: { foo: '12B45' }, error: `foo ${errorMessage}` }, - invalidMultiple: { object: { foos: ['12345', '12B45', '98765'] }, error: `element in array foos ${errorMessage}` } - }, - dbApiName: 'foos', - type: 'bar' - }; - - describe('default naming', () => { - test.route.document.addGetPostDocumentRouteTests( - createRegistrar(), - Object.assign({ routes: { singular: '/foo/:foo', plural: '/foo' } }, basicRoutesDescriptor) - ); - }); - - describe('postfix naming', () => { - test.route.document.addGetPostDocumentRouteTests( - createRegistrar({ singular: 'token', plural: 'tokens' }), - Object.assign({ routes: { singular: '/foo/:foo/token', plural: '/foo/tokens' } }, basicRoutesDescriptor) - ); - }); - }); - - describe('addPutPacketRoute', () => { - const registrar = (server, db, services) => { - const parseHexParam = (params, key) => routeUtils.parseArgument(params, key, catapult.utils.convert.hexToUint8); - routeUtils.addPutPacketRoute( - server, - services.connections, - { routeName: '/foo/bar', packetType: 987 }, - params => Buffer.concat([parseHexParam(params, 'alpha'), parseHexParam(params, 'beta')]) - ); - }; - - test.route.packet.addPutPacketRouteTests(registrar, { - routeName: '/foo/bar', - packetType: '987', - inputs: { - valid: { - params: { alpha: '1234', beta: '9981AB' }, - parsed: Buffer.of( - 0x0D, 0x00, 0x00, 0x00, // size (header) - 0xDB, 0x03, 0x00, 0x00, // type (header) - 0x12, 0x34, 0x99, 0x81, 0xAB // payload (alpha, beta) - ) - }, - invalid: { - params: { alpha: '1234', beta: '9P81AB' }, - error: { key: 'beta' } - } - } - }); - }); - - describe('blockRouteMerkleProcessor', () => { - // Arrange: - const highestHeight = 50; - - const sendFake = sinon.fake(); - const nextFake = sinon.fake(); - - const formatHashAsBinary = hash => test.factory.createBinary(Buffer.from(convert.hexToUint8(hash), 'hex')); - const formatBinaryAsHash = binary => convert.uint8ToHex(binary.buffer); - const merkleTree = [ - formatHashAsBinary('9922093F19F7160BDCBCA8AA48499DA8DF532D4102745670B85AA4BDF63B8D59'), - formatHashAsBinary('E8FCFD95CA220D442BE748F5494001A682DC8015A152EBC433222136E99A96B8'), - formatHashAsBinary('C1C1062C63CAB4197C87B366052ECE3F4FEAE575D81A7F728F4E3704613AF876'), - formatHashAsBinary('F8E8FCDAD1B94D2C76D769B113FF5CAC5D5170772F2D80E466EB04FCA23D6887'), - formatHashAsBinary('2D3418274BBC250616223C162534B460216AED82C4FA9A87B53083B7BA7A9391'), - formatHashAsBinary('AEAF30ED55BBE4805C53E5232D88242F0CF719F99A8E6D339BCBF5D5DE85E1FB'), - formatHashAsBinary('AFE6C917BABA60ADC1512040CC35033B563DAFD1718FA486AB1F3D9B84866B27') - ]; - const blockMetaCountField = 'blockMetaCountField'; - const blockMetaTreeField = 'blockMetaTreeField'; - - const blockInfoMockData = { meta: {} }; - blockInfoMockData.meta[blockMetaCountField] = 4; - blockInfoMockData.meta[blockMetaTreeField] = merkleTree; - - const db = { - chainStatisticCurrent: () => Promise.resolve({ height: convertToLong(highestHeight) }), - blockWithMerkleTreeAtHeight: () => Promise.resolve(blockInfoMockData) - }; - - const processorFunction = routeUtils.blockRouteMerkleProcessor( - db, - blockMetaCountField, - blockMetaTreeField - ); - - beforeEach(() => { - sendFake.resetHistory(); - nextFake.resetHistory(); - }); - - it('returns a merkle path for valid height and hash', () => { - // Arrange: - const req = { params: { height: highestHeight.toString(), hash: formatBinaryAsHash(merkleTree[2]) } }; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(sendFake.calledOnceWith(sinon.match({ - payload: { - merklePath: [ - { position: catapult.crypto.merkle.NodePosition.right, hash: merkleTree[3].buffer }, - { position: catapult.crypto.merkle.NodePosition.left, hash: merkleTree[4].buffer } - ] - }, - type: 'merkleProofInfo' - }))).to.equal(true); - expect(nextFake.calledOnce).to.equal(true); - }); - }); - - it('throws error if height has an invalid format', () => { - // Arrange: - const req = { params: { height: 'abc', hash: formatBinaryAsHash(merkleTree[2]) } }; - - // Act + Assert: - expect(processorFunction.bind(processorFunction, req, { send: sendFake }, nextFake)) - .to.throw('height has an invalid format'); - }); - - it('throws error if hash has an invalid format', () => { - // Arrange: - const req = { params: { height: highestHeight.toString(), hash: 'AFE6C917' } }; - - // Act + Assert: - expect(processorFunction.bind(processorFunction, req, { send: sendFake }, nextFake)) - .to.throw('hash has an invalid format'); - }); - - it('returns resource not found error if there is no block at this height', () => { - // Arrange: - const queriedHeight = highestHeight + 10; - const queriedHash = formatBinaryAsHash(merkleTree[2]); - const req = { params: { height: queriedHeight.toString(), hash: queriedHash } }; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(sendFake.firstCall.args[0].body).to.deep.equal({ - code: 'ResourceNotFound', - message: `no resource exists with id '${queriedHeight}'` - }); - expect(nextFake.calledOnce).to.equal(true); - }); - }); - - it('returns invalid argument if hash is not included in block at this height', () => { - // Arrange: - const req = { params: { height: highestHeight.toString(), hash: formatBinaryAsHash(merkleTree[2]) } }; - blockInfoMockData.meta[blockMetaCountField] = 0; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(sendFake.firstCall.args[0].body).to.deep.equal({ - code: 'InvalidArgument', - message: `hash '${req.params.hash}' not included in block height '${highestHeight}'` - }); - expect(nextFake.calledOnce).to.equal(true); - // restore data for following tests - blockInfoMockData.meta[blockMetaCountField] = 4; - }); - }); - - it('returns invalid argument if hash is not found in merkle tree', () => { - // Arrange: - const req = { - params: { - height: highestHeight.toString(), - hash: 'AAAAA62C63CAB4197C87B36605AAAAAF4FEAE575D81A7F728F4E3704613AAAAA' - } - }; - - // Act: - return processorFunction(req, { send: sendFake }, nextFake).then(() => { - // Assert: - expect(sendFake.firstCall.args[0].body).to.deep.equal({ - code: 'InvalidArgument', - message: `hash '${req.params.hash}' not included in block height '${highestHeight}'` - }); - expect(nextFake.calledOnce).to.equal(true); - }); - }); - }); - - describe('addressToPublicKey', () => { - const { addresses, publicKeys } = test.sets; - const accountAddress = catapult.model.address.stringToAddress(addresses.valid[0]); - const accountPublicKey = convert.hexToUint8(publicKeys.valid[0]); - - it('return correct public key from account address ', () => { - // Arrange: - const dbAddressToPublicKeyFake = sinon.fake.resolves({ - _id: undefined, - account: { publicKey: new Binary(Buffer.from(accountPublicKey)) } - }); - const db = { addressToPublicKey: dbAddressToPublicKeyFake }; - // Act: - return routeUtils.addressToPublicKey(db, accountAddress).then(result => { - // Assert: - expect(dbAddressToPublicKeyFake.calledOnceWith(accountAddress)).to.equal(true); - expect(result.equals(accountPublicKey)).to.be.equal(true); - }); - }); - - it('rejects with error when account id is not found', () => { - // Arrange: - const dbAddressToPublicKeyFake = sinon.fake.resolves(undefined); - const db = { addressToPublicKey: dbAddressToPublicKeyFake }; - // Act: - return routeUtils.addressToPublicKey(db, accountAddress) - // Assert: - .then(() => expect.fail()) - .catch(err => { - expect(err.toString()).to.include('account not found'); - }); - }); - }); -}); diff --git a/rest/test/routes/transactionRoutes_spec.js b/rest/test/routes/transactionRoutes_spec.js deleted file mode 100644 index f2c82a89d..000000000 --- a/rest/test/routes/transactionRoutes_spec.js +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer, test } = require('./utils/routeTestUtils'); -const routeResultTypes = require('../../src/routes/routeResultTypes'); -const routeUtils = require('../../src/routes/routeUtils'); -const transactionRoutes = require('../../src/routes/transactionRoutes'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { address } = catapult.model; -const { convert } = catapult.utils; - -const TransactionGroups = { - confirmed: 'confirmed', - unconfirmed: 'unconfirmed', - partial: 'partial' -}; - -describe('transaction routes', () => { - describe('transactions', () => { - const validObjectId = 'CCDDEEFF0011223344556677'; - const validHash = '112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00'; - - describe('get', () => { - describe('by id', () => { - const fakeTransaction = { meta: { addresses: [] }, transaction: { type: 12345 } }; - - const dbTransactionsByIdsFake = sinon.fake.resolves(fakeTransaction); - const dbTransactionsByHashesFake = sinon.fake.resolves(fakeTransaction); - - const mockServer = new MockServer(); - const db = { - transactionsByIds: dbTransactionsByIdsFake, - transactionsByHashes: dbTransactionsByHashesFake - }; - transactionRoutes.register(mockServer.server, db, {}); - - const route = mockServer.getRoute('/transactions/:group/:transactionId').get(); - - beforeEach(() => { - mockServer.resetStats(); - dbTransactionsByIdsFake.resetHistory(); - dbTransactionsByHashesFake.resetHistory(); - }); - - const runParseArgumentParamTest = (params, parserName) => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionId: params } }; - const parseArgumentSpy = sinon.spy(routeUtils, 'parseArgument'); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(parseArgumentSpy.calledOnceWith( - { group: TransactionGroups.confirmed, transactionId: params }, - 'transactionId', - parserName - )).to.equal(true); - parseArgumentSpy.restore(); - }); - }; - - it('throws if invalid length of transaction id', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionId: '12345' } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('invalid length of transaction id \'12345\''); - }); - - it('calls parseArgument with correct parser for id', () => runParseArgumentParamTest(validObjectId, 'objectId')); - it('calls parseArgument with correct parser for hash', () => runParseArgumentParamTest(validHash, 'hash256')); - - describe('checks correct group is provided', () => { - const runValidGroupTest = group => { - it(`${group} - by id`, () => { - // Arrange - const req = { params: { group, transactionId: validObjectId } }; - - // Act: - mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByIdsFake.calledOnce).to.equal(true); - expect(dbTransactionsByIdsFake.firstCall.args[0]).to.equal(group); - }); - }); - - it(`${group} - by hash`, () => { - // Arrange - const req = { params: { group, transactionId: validHash } }; - - // Act: - mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByHashesFake.calledOnce).to.equal(true); - expect(dbTransactionsByHashesFake.firstCall.args[0]).to.equal(group); - }); - }); - }; - - Object.keys(TransactionGroups).forEach(group => runValidGroupTest(group)); - - it('not found if group does not exists', () => { - // Arrange - const req = { params: { group: 'nonExistingGroup', transactionId: validObjectId } }; - - // Act: - mockServer.callRoute(route, req); - - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - }); - - describe('calls correct transaction retriever with correct params', () => { - it('id param', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionId: validObjectId } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByIdsFake.calledOnce).to.equal(true); - expect(dbTransactionsByIdsFake.firstCall.args[1]).to.deep.equal([validObjectId]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeTransaction, - type: routeResultTypes.transaction - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('hash param', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionId: validHash } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByHashesFake.calledOnce).to.equal(true); - expect(dbTransactionsByHashesFake.firstCall.args[1]).to.deep.equal([convert.hexToUint8(validHash)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeTransaction, - type: routeResultTypes.transaction - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - }); - - describe('paginated', () => { - const testAddressString = 'SBZ22LWA7GDZLPLQF7PXTMNLWSEZ7ZRVGRMWLXQ'; - const testAddress = address.stringToAddress(testAddressString); - - const testPublickeyString = '7DE16AEDF57EB9561D3E6EFA4AE66F27ABDA8AEC8BC020B6277360E31619DCE7'; - const testPublickey = convert.hexToUint8(testPublickeyString); - - const fakeTransaction = { meta: { addresses: [] }, transaction: { type: 12345 } }; - const fakePaginatedTransaction = { - data: [fakeTransaction], - pagination: { - pageNumber: 1, - pageSize: 10 - } - }; - const dbTransactionsFake = sinon.fake.resolves(fakePaginatedTransaction); - - const mockServer = new MockServer(); - const db = { transactions: dbTransactionsFake }; - const services = { - config: { - pageSize: { - min: 10, - max: 100, - default: 20 - } - } - }; - transactionRoutes.register(mockServer.server, db, services); - - const route = mockServer.getRoute('/transactions/:group').get(); - - beforeEach(() => { - mockServer.resetStats(); - dbTransactionsFake.resetHistory(); - }); - - describe('returns transactions', () => { - it('returns correct structure with transactions', () => { - const req = { - params: { group: TransactionGroups.confirmed } - }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakePaginatedTransaction, - type: routeResultTypes.transaction, - structure: 'page' - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - - describe('parses filters', () => { - const runParseFilterTest = (filter, param, value) => { - it(filter, () => { - const req = { params: { group: TransactionGroups.confirmed, [filter]: param } }; - - const expectedResult = { - address: undefined, - height: undefined, - fromHeight: undefined, - toHeight: undefined, - recipientAddress: undefined, - signerPublicKey: undefined, - embedded: undefined, - transactionTypes: undefined, - transferMosaicId: undefined, - fromTransferAmount: undefined, - toTransferAmount: undefined - }; - - expectedResult[filter] = value; - - // Act + Assert - return mockServer.callRoute(route, req).then(() => { - expect(dbTransactionsFake.firstCall.args[1]).to.deep.equal(expectedResult); - }); - }); - }; - - const testCases = [ - { filter: 'height', param: '15', value: [15, 0] }, - { filter: 'fromHeight', param: '10', value: [10, 0] }, - { filter: 'toHeight', param: '20', value: [20, 0] }, - { filter: 'address', param: testAddressString, value: testAddress }, - { filter: 'signerPublicKey', param: testPublickeyString, value: testPublickey }, - { filter: 'recipientAddress', param: testAddressString, value: testAddress }, - { filter: 'embedded', param: 'true', value: true }, - { filter: 'transferMosaicId', param: '0000000000001000', value: [4096, 0] } - ]; - - testCases.forEach(testCase => { - runParseFilterTest(testCase.filter, testCase.param, testCase.value); - }); - - it('transactionTypes', () => { - const req = { params: { group: TransactionGroups.confirmed, type: ['1', '5', '25'] } }; - - // Act + Assert - return mockServer.callRoute(route, req).then(() => { - expect(dbTransactionsFake.firstCall.args[1].transactionTypes).to.deep.equal([1, 5, 25]); - }); - }); - - it('fromTransferAmount', () => { - const req = { - params: { - group: TransactionGroups.confirmed, - transferMosaicId: '0000000000001000', - fromTransferAmount: '12345' - } - }; - - // Act + Assert - return mockServer.callRoute(route, req).then(() => { - expect(dbTransactionsFake.firstCall.args[1].fromTransferAmount).to.deep.equal([12345, 0]); - expect(dbTransactionsFake.firstCall.args[1].transferMosaicId).to.deep.equal([4096, 0]); - }); - }); - - it('toTransferAmount', () => { - const req = { - params: { - group: TransactionGroups.confirmed, - transferMosaicId: '0000000000001000', - toTransferAmount: '12345' - } - }; - - // Act + Assert - return mockServer.callRoute(route, req).then(() => { - expect(dbTransactionsFake.firstCall.args[1].toTransferAmount).to.deep.equal([12345, 0]); - expect(dbTransactionsFake.firstCall.args[1].transferMosaicId).to.deep.equal([4096, 0]); - }); - }); - }); - - describe('parses options', () => { - it('parses and forwards paging options', () => { - // Arrange: - const pagingBag = 'fakePagingBagObject'; - const paginationParser = sinon.stub(routeUtils, 'parsePaginationArguments').returns(pagingBag); - - // Act: - const req = { params: { group: TransactionGroups.confirmed } }; - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(paginationParser.firstCall.args[0]).to.deep.equal(req.params); - expect(paginationParser.firstCall.args[2]).to.deep.equal({ id: 'objectId' }); - - expect(dbTransactionsFake.calledOnce).to.equal(true); - expect(dbTransactionsFake.firstCall.args[2]).to.deep.equal(pagingBag); - paginationParser.restore(); - }); - }); - - it('allowed sort fields are taken into account', () => { - // Arrange: - const paginationParserSpy = sinon.spy(routeUtils, 'parsePaginationArguments'); - const expectedAllowedSortFields = { id: 'objectId' }; - - // Act: - return mockServer.callRoute(route, { params: { group: TransactionGroups.confirmed } }).then(() => { - // Assert: - expect(paginationParserSpy.calledOnce).to.equal(true); - expect(paginationParserSpy.firstCall.args[2]).to.deep.equal(expectedAllowedSortFields); - paginationParserSpy.restore(); - }); - }); - }); - - describe('does not allow filtering by address if signerPublicKey or recipientAddress are provided', () => { - const errorMessage = 'can\'t filter by address if signerPublicKey or recipientAddress are already provided'; - - it('address and signer public key', () => { - const req = { - params: { group: TransactionGroups.confirmed, address: testAddressString, signerPublicKey: testPublickeyString } - }; - - // Act + Assert - mockServer.callRoute(route, req); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.next.firstCall.args[0].message).to.equal(errorMessage); - }); - - it('address and recipient address', () => { - const req = { - params: { group: TransactionGroups.confirmed, address: testAddressString, recipientAddress: testAddressString } - }; - - // Act + Assert - mockServer.callRoute(route, req); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.next.firstCall.args[0].message).to.equal(errorMessage); - }); - }); - - describe('does not allow filtering by transfer amount if transfer mosaic id is not provided', () => { - const errorMessage = 'can\'t filter by transfer amount if `transferMosaicId` is not provided'; - - it('does not allow filtering by fromTransferAmount if transferMosaicId is not provided', () => { - const req = { - params: { - group: TransactionGroups.confirmed, - fromTransferAmount: '12345' - } - }; - - // Act + Assert - mockServer.callRoute(route, req); - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.next.firstCall.args[0].message).to.equal(errorMessage); - }); - - it('does not allow filtering by toTransferAmount if transferMosaicId is not provided', () => { - const req = { - params: { - group: TransactionGroups.confirmed, - toTransferAmount: '12345' - } - }; - - // Act + Assert - mockServer.callRoute(route, req); - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(409); - expect(mockServer.next.firstCall.args[0].message).to.equal(errorMessage); - }); - }); - - describe('allows filtering by fromTransferAmount and toTransferAmount', () => { - it('even if their provided values are 0', () => { - const req = { - params: { - group: TransactionGroups.confirmed, - transferMosaicId: '0000000000001000', - fromTransferAmount: '0', - toTransferAmount: '0' - } - }; - - // Act + Assert - return mockServer.callRoute(route, req).then(() => { - expect(dbTransactionsFake.firstCall.args[1].fromTransferAmount).to.deep.equal([0, 0]); - expect(dbTransactionsFake.firstCall.args[1].toTransferAmount).to.deep.equal([0, 0]); - expect(dbTransactionsFake.firstCall.args[1].transferMosaicId).to.deep.equal([4096, 0]); - }); - }); - }); - - describe('checks correct group is provided', () => { - const runValidGroupTest = group => { - it(group, () => - // Act + Assert - mockServer.callRoute(route, { params: { group } }).then(() => { - expect(dbTransactionsFake.firstCall.args[1]).to.deep.equal({ - address: undefined, - height: undefined, - fromHeight: undefined, - toHeight: undefined, - recipientAddress: undefined, - signerPublicKey: undefined, - embedded: undefined, - transactionTypes: undefined, - transferMosaicId: undefined, - fromTransferAmount: undefined, - toTransferAmount: undefined - }); - })); - }; - - Object.keys(TransactionGroups).forEach(group => runValidGroupTest(group)); - - it('not found if group does not exists', () => { - // Arrange: - const req = { params: { group: 'nonExistingGroup' } }; - - // Act: - mockServer.callRoute(route, req); - - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - }); - }); - }); - - describe('post', () => { - const fakeTransactions = [{ meta: { addresses: [] }, transaction: { type: 12345 } }]; - - const dbTransactionsByIdsFake = sinon.fake.resolves(fakeTransactions); - const dbTransactionsByHashesFake = sinon.fake.resolves(fakeTransactions); - - const mockServer = new MockServer(); - const db = { - transactionsByIds: dbTransactionsByIdsFake, - transactionsByHashes: dbTransactionsByHashesFake - }; - transactionRoutes.register(mockServer.server, db, {}); - - const route = mockServer.getRoute('/transactions/:group').post(); - - beforeEach(() => { - mockServer.resetStats(); - dbTransactionsByIdsFake.resetHistory(); - dbTransactionsByHashesFake.resetHistory(); - }); - - it('throws if ids or hashes are not provided', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('either ids or hashes must be provided'); - }); - - it('throws if both ids and hashes are provided', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionIds: [], hashes: [] } }; - - // Act + Assert: - expect(() => mockServer.callRoute(route, req)).to.throw('either ids or hashes must be provided'); - }); - - describe('checks correct group is provided', () => { - const runValidGroupTest = group => { - it(`${group} - by ids`, () => { - // Arrange - const req = { params: { group, transactionIds: [validObjectId] } }; - - // Act: - mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByIdsFake.calledOnce).to.equal(true); - expect(dbTransactionsByIdsFake.firstCall.args[0]).to.equal(group); - }); - }); - it(`${group} - by hashes`, () => { - // Arrange - const req = { params: { group, hashes: [validHash] } }; - - // Act: - mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByHashesFake.calledOnce).to.equal(true); - expect(dbTransactionsByHashesFake.firstCall.args[0]).to.equal(group); - }); - }); - }; - - Object.keys(TransactionGroups).forEach(group => runValidGroupTest(group)); - - it('not found if group does not exists', () => { - // Arrange - const req = { params: { group: 'nonExistingGroup', transactionIds: [validObjectId] } }; - - // Act: - mockServer.callRoute(route, req); - - // Assert: - expect(mockServer.next.calledOnce).to.equal(true); - expect(mockServer.next.firstCall.args[0].statusCode).to.equal(404); - }); - }); - - const runParseArgumentAsArrayParamTest = (paramValues, paramName, parserName) => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, [paramName]: paramValues } }; - const parseArgumentsAsArraySpy = sinon.spy(routeUtils, 'parseArgumentAsArray'); - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(parseArgumentsAsArraySpy.calledOnceWith( - { group: TransactionGroups.confirmed, [paramName]: paramValues }, - paramName, - parserName - )).to.equal(true); - parseArgumentsAsArraySpy.restore(); - }); - }; - - it('calls parseArgumentAsArray with correct parser for ids', () => - runParseArgumentAsArrayParamTest([validObjectId, validObjectId], 'transactionIds', 'objectId')); - it('calls parseArgumentAsArray with correct parser for hashes', () => - runParseArgumentAsArrayParamTest([validHash, validHash], 'hashes', 'hash256')); - - describe('calls correct transaction retriever with correct params', () => { - it('id params', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionIds: [validObjectId] } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByIdsFake.calledOnce).to.equal(true); - expect(dbTransactionsByIdsFake.firstCall.args[1]).to.deep.equal([validObjectId]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeTransactions, - type: routeResultTypes.transaction - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('hash params', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, hashes: [validHash] } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByHashesFake.calledOnce).to.equal(true); - expect(dbTransactionsByHashesFake.firstCall.args[1]).to.deep.equal([convert.hexToUint8(validHash)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeTransactions, - type: routeResultTypes.transaction - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - - it('hash params (provisional test until params are split into transactionIds/hashes)', () => { - // Arrange - const req = { params: { group: TransactionGroups.confirmed, transactionIds: [validHash] } }; - - // Act: - return mockServer.callRoute(route, req).then(() => { - // Assert: - expect(dbTransactionsByHashesFake.calledOnce).to.equal(true); - expect(dbTransactionsByHashesFake.firstCall.args[1]).to.deep.equal([convert.hexToUint8(validHash)]); - - expect(mockServer.send.firstCall.args[0]).to.deep.equal({ - payload: fakeTransactions, - type: routeResultTypes.transaction - }); - expect(mockServer.next.calledOnce).to.equal(true); - }); - }); - }); - }); - - describe('put', () => { - test.route.packet.addPutPacketRouteTests(transactionRoutes.register, { - routeName: '/transactions', - packetType: '9', - inputs: { - valid: { - params: { payload: '123456' }, - parsed: Buffer.of( - 0x0B, 0x00, 0x00, 0x00, // size (header) - 0x09, 0x00, 0x00, 0x00, // type (header) - 0x12, 0x34, 0x56 // payload - ) - }, - invalid: { - params: { payload: '1234S6' }, - error: { key: 'payload' } - } - } - }); - }); - }); -}); diff --git a/rest/test/routes/transactionStatusRoutes_spec.js b/rest/test/routes/transactionStatusRoutes_spec.js deleted file mode 100644 index 28d2f209c..000000000 --- a/rest/test/routes/transactionStatusRoutes_spec.js +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { MockServer } = require('./utils/routeTestUtils'); -const dbFacade = require('../../src/routes/dbFacade'); -const routeResultTypes = require('../../src/routes/routeResultTypes'); -const routeUtils = require('../../src/routes/routeUtils'); -const transactionStatusRoutes = require('../../src/routes/transactionStatusRoutes'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const { convert } = catapult.utils; - -describe('transaction status routes', () => { - describe('calls addGetPostDocumentRoutes once with correct params', () => { - // Arrange: - const mockServer = new MockServer(); - const db = { - transactionsByHashesFailed: () => Promise.resolve([]), - transactionsByHashesUnconfirmed: () => Promise.resolve([]), - transactionsByHashes: () => Promise.resolve([]) - }; - const services = { config: { transactionStates: [] } }; - - const routeInfo = { - base: '/transactionStatus', - singular: 'hash', - plural: 'hashes' - }; - - let addGetPostDocumentRoutesSpy = null; - let routeUtilsCreateSenderSpy = null; - let transactionStatusesByHashesSpy = null; - - before(() => { - addGetPostDocumentRoutesSpy = sinon.spy(routeUtils, 'addGetPostDocumentRoutes'); - routeUtilsCreateSenderSpy = sinon.spy(routeUtils, 'createSender'); - transactionStatusesByHashesSpy = sinon.spy(dbFacade, 'transactionStatusesByHashes'); - - // Act: - transactionStatusRoutes.register(mockServer.server, db, services); - }); - - // Assert: - it('calls addGetPostDocumentRoutes once', () => { - expect(addGetPostDocumentRoutesSpy.calledOnce).to.equal(true); - }); - - it('calls addGetPostDocumentRoutes with correct server', () => { - expect(addGetPostDocumentRoutesSpy.firstCall.args[0]).to.deep.equal(mockServer.server); - }); - - it('calls addGetPostDocumentRoutes with correct sender', () => { - expect(routeUtilsCreateSenderSpy.calledOnce).to.equal(true); - expect(routeUtilsCreateSenderSpy.firstCall.args[0]).to.deep.equal(routeResultTypes.transactionStatus); - expect(addGetPostDocumentRoutesSpy.firstCall.args[1]).to.deep.equal(routeUtilsCreateSenderSpy.firstCall.returnValue); - }); - - it('calls addGetPostDocumentRoutes with correct route info', () => { - expect(addGetPostDocumentRoutesSpy.firstCall.args[2]).to.deep.equal(routeInfo); - }); - - it('calls addGetPostDocumentRoutes with correct document retriever', () => { - const calledDocumentRetriever = addGetPostDocumentRoutesSpy.firstCall.args[3]; - const paramHashes = ['6E9D130BBBB1C3190B02AF751CBEE32BEF6D6AE045E7618E4CE4D0BD582B6A27']; - - return calledDocumentRetriever(paramHashes).then(() => { - expect(transactionStatusesByHashesSpy.calledOnce).to.equal(true); - expect(transactionStatusesByHashesSpy.firstCall.args[0]).to.deep.equal(db); - expect(transactionStatusesByHashesSpy.firstCall.args[1]).to.deep.equal(paramHashes); - expect(transactionStatusesByHashesSpy.firstCall.args[2]).to.deep.equal(services.config.transactionStates); - }); - }); - - it('calls addGetPostDocumentRoutes with correct parser', () => { - const calledParser = addGetPostDocumentRoutesSpy.firstCall.args[4]; - - // - invalid length of hash - expect(() => { calledParser('abcd'); }).to.throw('invalid length of hash \'4\''); - - // - valid length of hash - const hexValue = '6BAD46BDBEF2B84D03BA9668E635EF14FA66099258FE669DADCF8C23324C5DF1'; - const parsedValue = convert.hexToUint8(hexValue); - expect(calledParser(hexValue)).to.deep.equal(parsedValue); - }); - - after(() => { - addGetPostDocumentRoutesSpy.restore(); - routeUtilsCreateSenderSpy.restore(); - transactionStatusesByHashesSpy.restore(); - }); - }); -}); diff --git a/rest/test/routes/utils/routeTestUtils.js b/rest/test/routes/utils/routeTestUtils.js deleted file mode 100644 index 2b461abbe..000000000 --- a/rest/test/routes/utils/routeTestUtils.js +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const test = require('../../testUtils'); -const { expect } = require('chai'); -const sinon = require('sinon'); - -const makeTestName = (base, desc) => (desc ? `${base} ${desc}` : base); - -class MockServer { - constructor() { - this.routes = {}; - this.server = {}; - ['get', 'put', 'post'].forEach(method => { - this.server[method] = (path, handler) => { - this.routes[path] = this.routes[path] || {}; - this.routes[path][method] = () => handler; - }; - }); - - this.next = sinon.fake(); - this.send = sinon.fake(); - this.redirect = sinon.fake(); - this.status = sinon.fake(); - this.setHeader = sinon.fake(); - this.res = { - send: this.send, - redirect: this.redirect, - status: this.status, - setHeader: this.setHeader - }; - } - - resetStats() { - this.next.resetHistory(); - this.send.resetHistory(); - this.redirect.resetHistory(); - } - - getRoute(path) { - return this.routes[path]; - } - - callRoute(route, req) { - return route(req, this.res, this.next); - } -} - -const routeTestUtils = { - setup: { - createMockServer: (captureMethod, routes) => { - const server = {}; - ['get', 'put', 'post', 'ws'].forEach(method => { - server[method] = () => {}; - }); - - server[captureMethod] = (path, handler) => { - routes[path] = handler; - }; - return server; - }, - - createCapturingMockServer: (captureMethod, routes) => { - const server = {}; - ['get', 'put', 'post', 'ws'].forEach(method => { - server[method] = () => {}; - }); - - server[captureMethod] = route => routes.push(route); - return server; - }, - - createCapturingDb: (dbApiName, keyGroups, document) => ({ - [dbApiName]: (...keys) => { - keyGroups.push(...keys); - return Promise.resolve(document); - } - }), - - createCapturingDbWithExtensions: ({ dbApiName, extendDb }, keyGroups, document) => { - const db = routeTestUtils.setup.createCapturingDb(dbApiName, keyGroups, document); - if (extendDb) - extendDb(db); - - return db; - }, - - findRoute: (routes, routeName) => { - const route = routes[routeName]; - expect(route).to.not.equal(undefined); - return route; - }, - - createPagingTestsFactory(routeInfo, routeEntityId, dbEntityId, responseType) { - const makeCommonParams = (db, params) => [ - routeInfo.routes.register, - routeInfo.routeName, - routeInfo.routeCaptureMethod, - Object.assign({}, routeEntityId, params), - db, - routeInfo.config - ]; - - const factory = { - addDefault: () => { - // - success tests - const validId = '112233445566778899AABBCC'; - factory.addSuccessTest('basic query', {}, { pageId: undefined, pageSize: 0 }); - factory.addSuccessTest('query with pageId', { id: validId }, { pageId: validId, pageSize: 0 }); - factory.addSuccessTest('query with pageSize', { pageSize: '321' }, { pageId: undefined, pageSize: 321 }); - factory.addSuccessTest( - 'query with pageId and pageSize', - { id: validId, pageSize: '321' }, - { pageId: validId, pageSize: 321 } - ); - - // - failure tests - factory.addFailureUndefinedDbObjectTest({}, { pageId: undefined, pageSize: 0 }); - - factory.addFailureTest('invalid pageId', { id: 'alice', pageSize: '321' }, 'id is not a valid object id'); - factory.addFailureTest( - 'invalid pageSize', - { id: validId, pageSize: 'alice' }, - 'pageSize is not a valid unsigned integer' - ); - }, - - addSuccessTest: (name, params, expectedParams) => - it(name, () => { - // Arrange: - const keyGroups = []; - const payload = [{ id: 100 }, { id: 101 }, { id: 102 }]; - const db = routeInfo.createDb(keyGroups, payload); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(db, params), response => { - // Assert: - expect(keyGroups).to.deep.equal([Object.assign({}, dbEntityId, expectedParams)]); - expect(response).to.deep.equal({ payload, type: responseType }); - }); - }), - - addFailureUndefinedDbObjectTest: (params, expectedParams) => - it('returns 500 if not array', () => { - // Arrange: - const keyGroups = []; - const db = routeInfo.createDb(keyGroups, undefined); - const paramId = Object.keys(routeEntityId)[0]; - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(db, params), response => { - // Assert: - expect(keyGroups).to.deep.equal([Object.assign({}, dbEntityId, expectedParams)]); - expect(response.statusCode).to.equal(500); - expect(response.message).to.equal(`error retrieving data for id: '${paramId}'`); - }); - }), - - addFailureTest: (name, params, error) => - it(`returns 409 if ${name}`, () => { - // Arrange: - const db = routeInfo.createDb([], [{ id: 100 }, { id: 101 }, { id: 102 }]); - - // Act: - return routeTestUtils.route.executeThrows(...makeCommonParams(db, params), error, 409); - }), - - addNonPagingParamFailureTest: (name, value) => - factory.addFailureTest(`${name} is invalid`, { [name]: value }, `${name} has an invalid format`) - }; - - return factory; - } - }, - - assert: { - invokerThrowsError: (invoker, expectedError) => { - try { - invoker(); - } catch (err) { - expect(err.statusCode).to.equal(expectedError.statusCode); - expect(err.message).to.contain(expectedError.message); - return; - } - - throw Error('no exception was thrown by test'); - }, - - assertRoutes: (routes, expectedRoutes) => { - expect(routes.length).to.equal(expectedRoutes.length); - expectedRoutes.forEach(route => { - expect(routes).to.include(route); - }); - } - }, - - route: { - prepareExecuteRoute: (registerRoutes, routeName, routeCaptureMethod, params, db, services, assertRoute) => { - // Arrange: set up a mock server - const routes = {}; - const server = routeTestUtils.setup.createMockServer(routeCaptureMethod || 'get', routes); - - // - register the routes - registerRoutes(server, db, services); - - // - set up the route params - const routeContext = { - numNextCalls: 0, - responses: [], - redirects: [] - }; - - const next = () => { ++routeContext.numNextCalls; }; - const req = { params }; - - const res = { - send: response => { routeContext.responses.push(response); }, - redirect: uri => { - routeContext.redirects.push(uri); - next(); - } - }; - - // Act: get the desired route and call it - const route = routeTestUtils.setup.findRoute(routes, routeName); - routeContext.routeInvoker = () => route(req, res, next); - return assertRoute(routeContext); - }, - - executeSingle: (registerRoutes, routeName, routeCaptureMethod, params, db, config, assertResponse) => - routeTestUtils.route.prepareExecuteRoute(registerRoutes, routeName, routeCaptureMethod, params, db, { config }, routeContext => - routeContext.routeInvoker().then(() => { - expect(routeContext.numNextCalls, 'next should be called once').to.equal(1); - expect(routeContext.responses.length, 'single response is expected').to.equal(1); - expect(routeContext.redirects.length, 'no redirects are expected').to.equal(0); - assertResponse(routeContext.responses[0]); - })), - - executeThrows: (registerRoutes, routeName, routeCaptureMethod, params, db, config, expectedMessage, expectedStatusCode) => - routeTestUtils.route.prepareExecuteRoute( - registerRoutes, - routeName, - routeCaptureMethod, - params, - db, - { config }, - routeContext => { - routeTestUtils.assert.invokerThrowsError(routeContext.routeInvoker, { - statusCode: expectedStatusCode, - message: expectedMessage - }); - } - ), - - executeRedirects: (registerRoutes, routeName, routeCaptureMethod, params, config, assertRedirect) => { - routeTestUtils.route.prepareExecuteRoute( - registerRoutes, - routeName, - routeCaptureMethod, - params, - {}, - { config }, - routeContext => { - // redirects happen synchronously, so routeInvoker does not return a promise - routeContext.routeInvoker(); - expect(routeContext.numNextCalls, 'next should be called once').to.equal(1); - expect(routeContext.responses.length, 'no responses are expected').to.equal(0); - expect(routeContext.redirects.length, 'single redirect is expected').to.equal(1); - assertRedirect(routeContext.redirects[0]); - } - ); - }, - - document: { - // prepare tests for resources that support only multiple (GET) retrieval - prepareGetDocumentsRouteTests: (registerRoutes, rd) => { - const makeCommonParams = (input, db) => { - const params = [registerRoutes, rd.route, 'get', input.object]; - if (db) - params.push(db); - - params.push(rd.config); - return params; - }; - - return { - addValidInputTest: (input, desc) => { - it(makeTestName('returns result if document is found in db', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, [{ value: 'this is nonsense' }]); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal(input.parsed); - expect(response).to.deep.equal({ payload: [{ value: 'this is nonsense' }], type: rd.type }); - }); - }); - }, - - addEmptyArrayTest: input => { - it('returns empty array if no documents are found', () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, []); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal(input.parsed); - expect(response).to.deep.equal({ payload: [], type: rd.type }); - }); - }); - }, - - addNotFoundInputTest: (input, desc) => { - it(`returns 404 if ${desc || 'documents are not found in db'}`, () => { - // Arrange: return *something* from the db because the 404 should be triggered by something external - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, [{ value: 'this is nonsense' }]); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal(input.parsed); - expect(response.statusCode).to.equal(404); - expect(response.message).to.equal(`no resource exists with id '${input.printable}'`); - }); - }); - }, - - addRedirectTest: (input, desc) => { - it(makeTestName('redirects if route parameters are not in range', desc), () => { - // Arrange: - const keyGroups = []; - - // Act: - return routeTestUtils.route.executeRedirects(...makeCommonParams(input, undefined), redirect => { - // Assert: - expect(keyGroups).to.deep.equal([]); - expect(redirect).to.deep.equal(input.redirectUri); - }); - }); - }, - - addInvalidKeyTest: (input, desc) => { - it(makeTestName('returns 409 if key is invalid', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, [{ value: 'this is nonsense' }]); - - // Act: - return routeTestUtils.route.executeThrows(...makeCommonParams(input, db), input.error, 409); - }); - } - }; - }, - - // prepare tests for resources that support only singular (GET) retrieval - // notice that these are a slightly different subset of prepareGetDocumentsRouteTests - // (refactoring is possible but would lose readability) - prepareGetDocumentRouteTests: (registerRoutes, rd) => { - const makeCommonParams = (input, db) => [registerRoutes, rd.route, 'get', input.object, db, rd.config]; - - return { - addValidInputTest: (input, desc) => { - it(makeTestName('returns result if document is found in db', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, { value: 'this is nonsense' }); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal(input.parsed); - const payload = Object.assign({ value: 'this is nonsense' }, rd.payloadTemplate); - expect(response).to.deep.equal({ payload, type: rd.type }); - }); - }); - }, - - addNotFoundInputTest: (input, desc) => { - it(`returns 404 if ${desc || 'documents are not found in db'}`, () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal(input.parsed); - expect(response.statusCode).to.equal(404); - expect(response.message).to.equal(`no resource exists with id '${input.printable}'`); - }); - }); - }, - - addInvalidKeyTest: (input, desc) => { - it(makeTestName('returns 409 if key is invalid', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, { value: 'this is nonsense' }); - - // Act: - return routeTestUtils.route.executeThrows(...makeCommonParams(input, db), input.error, 409); - }); - }, - - addDefault(inputs) { - this.addValidInputTest(inputs.valid); - this.addNotFoundInputTest(inputs.valid); - this.addInvalidKeyTest(inputs.invalid); - } - }; - }, - - // prepare tests for resources that support multiple (POST) retrieval - preparePostDocumentsRouteTests: (registerRoutes, rd) => { - const makeCommonParams = (input, db) => [ - registerRoutes, - rd.routes.plural, - 'post', - input.object, - db, - rd.config - ]; - - return { - addValidInputTest: (input, desc) => { - it(makeTestName('returns documents if found', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, [{ value: 'this is nonsense' }]); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal([input.parsed]); - const payload = [Object.assign({ value: 'this is nonsense' }, rd.payloadTemplate)]; - expect(response).to.deep.equal({ payload, type: rd.type }); - }); - }); - }, - - addEmptyArrayTest: (input, desc) => { - it(makeTestName('returns empty array if no documents are found', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, []); - - // Act: - return routeTestUtils.route.executeSingle(...makeCommonParams(input, db), response => { - // Assert: - expect(keyGroups).to.deep.equal([input.parsed]); - expect(response).to.deep.equal({ payload: [], type: rd.type }); - }); - }); - }, - - addInvalidKeyTest: (input, desc) => { - it(makeTestName('returns 409 if any key is invalid', desc), () => { - // Arrange: - const keyGroups = []; - const db = routeTestUtils.setup.createCapturingDbWithExtensions(rd, keyGroups, { value: 'this is nonsense' }); - - // Act: - return routeTestUtils.route.executeThrows(...makeCommonParams(input, db), input.error, 409); - }); - } - }; - }, - - // add tests for resources that support only singular (GET) retrieval - addGetDocumentRouteTests: (registerRoutes, routesDescriptor) => { - const builder = routeTestUtils.route.document.prepareGetDocumentRouteTests(registerRoutes, routesDescriptor); - builder.addDefault(routesDescriptor.inputs); - }, - - // add tests for resources that support both singular (GET) and multiple (POST) retrieval - addGetPostDocumentRouteTests: (registerRoutes, routesDescriptor) => { - const rd = routesDescriptor; - describe('GET', () => { - routeTestUtils.route.document.addGetDocumentRouteTests(registerRoutes, { - route: rd.routes.singular, - inputs: { - // singular param should be passed as array to db function - valid: { - object: rd.inputs.valid.object, - parsed: [rd.inputs.valid.parsed], - printable: rd.inputs.valid.printable - }, - invalid: rd.inputs.invalid - }, - dbApiName: rd.dbApiName, - extendDb: rd.extendDb, - payloadTemplate: rd.payloadTemplate, - type: rd.type, - config: rd.config - }); - }); - - describe('POST', () => { - const builder = routeTestUtils.route.document.preparePostDocumentsRouteTests(registerRoutes, routesDescriptor); - builder.addValidInputTest(routesDescriptor.inputs.validMultiple); - builder.addEmptyArrayTest(routesDescriptor.inputs.validMultiple); - builder.addInvalidKeyTest(routesDescriptor.inputs.invalidMultiple); - }); - } - }, - - packet: { - // add tests for routes that send packets to api servers - addPutPacketRouteTests: (registerRoutes, routeDescriptor) => { - const rd = routeDescriptor; - const runTestWithConnections = (params, assertRoute) => { - // Arrange: set up a mock server - const routes = {}; - const server = routeTestUtils.setup.createMockServer('put', routes); - - // - set up the route params - const routeContext = { - sendPayloads: [], - numNextCalls: 0 - }; - - const services = { - connections: { - lease: () => Promise.resolve({ - send: payload => { - routeContext.sendPayloads.push(payload); - return Promise.resolve(); - } - }) - } - }; - - const next = () => { ++routeContext.numNextCalls; }; - const req = { params }; - - routeContext.responses = []; - const res = { send: (status, response) => { routeContext.responses.push({ status, response }); } }; - - // - register the routes - registerRoutes(server, undefined, services); - - // Act: get the desired route and call it - const route = routeTestUtils.setup.findRoute(routes, rd.routeName); - routeContext.routeInvoker = () => route(req, res, next); - return assertRoute(routeContext); - }; - - it('succeeds if payload is valid', () => - // Act: - runTestWithConnections(rd.inputs.valid.params, routeContext => - routeContext.routeInvoker().then(() => { - // Assert: next is called - expect(routeContext.numNextCalls).to.equal(1); - - // - the send payload is correct - expect(routeContext.sendPayloads.length).to.equal(1); - expect(routeContext.sendPayloads[0]).to.deep.equal(rd.inputs.valid.parsed); - - // - the response is correct - expect(routeContext.responses.length).to.equal(1); - expect(routeContext.responses[0]).to.deep.equal({ - status: 202, - response: { message: `packet ${rd.packetType} was pushed to the network via ${rd.routeName}` } - }); - }))); - - it('throws if payload is invalid', () => - // Act: - runTestWithConnections(rd.inputs.invalid.params, routeContext => { - routeTestUtils.assert.invokerThrowsError(routeContext.routeInvoker, { - statusCode: 409, - message: `${rd.inputs.invalid.error.key} has an invalid format` - }); - })); - } - } - }, - - sets: { - addresses: { - valid: ['SAAA244WMCB2JXGNQTQHQOS45TGBFF4V2MJBVOQ', 'NAR3W7B4BCOZSZMFIZRYB3N5YGOUSWIYJCJ6HDA'], - invalid: 'SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1' - }, - - publicKeys: { - valid: [ - '3485D98EFD7EB07ADAFCFD1A157D89DE2796A95E780813C0258AF3F5F84ED8CB', - '75D8BB873DA8F5CCA741435DE76A46AFC2840803EBF080E931195B048D77F88C' - ], - invalid: '111111111111111111111111111111111111111111111111111111111111111G' - }, - - hashes256: { - valid: [ - 'D9A0641F8444CD789A83B8789371109E2BB0F7322A4A8E790EC72D580DBBB947', - '0CDB15C0BEE1AB41AAC540C6AEB30F5DAEDB57BAA062E9E7EA8764BED58B6540' - ], - invalid: [ - '0CDB15C0BEE1AB41AAC540C6AEB30F5DAEDB57BAA062E9E7EA8764BED58B65408', // + 1 - '0CDB15C0BEE1AB41AAC540C6AEB30F5DAEDB57BAA062E9E7EA8764BED58B654', // - 1 - 'ZCDB15C0BEE1AB41AAC540C6AEB30F5DAEDB57BAA062E9E7EA8764BED58B6540' // contains z - ] - }, - - hashes512: { - valid: [ - '91AC9F58DF84081F0DEFEDB151D3BBC94618587A66CDD255654E6CD32981D6A1' - + '4FC839B99AD9E3EFB9E4EB623C44E2BC0441FCEB14FFFA0AB04846C59B65C7BC', - '8F1DD428F30349F26525C4E7293D1B5AEC256785CA0F7F49A7CB79A514B41670' - + '266C69014B95EDAC19F896E68CE31F3E3CAE1884CE13DB67072FB8F1B9044058' - ], - invalid: [ - '8F1DD428F30349F26525C4E7293D1B5AEC256785CA0F7F49A7CB79A514B41670' - + '266C69014B95EDAC19F896E68CE31F3E3CAE1884CE13DB67072FB8F1B90440581', // + 1 - '8F1DD428F30349F26525C4E7293D1B5AEC256785CA0F7F49A7CB79A514B41670' - + '266C69014B95EDAC19F896E68CE31F3E3CAE1884CE13DB67072FB8F1B904405', // - 1 - 'ZF1DD428F30349F26525C4E7293D1B5AEC256785CA0F7F49A7CB79A514B41670' - + '266C69014B95EDAC19F896E68CE31F3E3CAE1884CE13DB67072FB8F1B9044058' // contains z - ] - } - } -}; -Object.assign(routeTestUtils, test); - -module.exports = { - MockServer, - test: routeTestUtils -}; diff --git a/rest/test/routes/wsRoutes_spec.js b/rest/test/routes/wsRoutes_spec.js deleted file mode 100644 index 2bd9db11b..000000000 --- a/rest/test/routes/wsRoutes_spec.js +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const { test } = require('./utils/routeTestUtils'); -const wsRoutes = require('../../src/routes/wsRoutes'); -const { expect } = require('chai'); - -describe('web socket routes', () => { - const setupWebsocketTest = (action, assertCaptures) => { - // Arrange: - const service = { eventHandlers: {}, removedChannels: [] }; - service.on = (eventName, eventHandler) => { service.eventHandlers[eventName] = eventHandler; }; - service.removeAllListeners = channel => { service.removedChannels.push(channel); }; - - const routes = []; - const server = test.setup.createMockServer('ws', routes); - wsRoutes.register(server, undefined, { zmqService: service }); - - // Act: get the desired route and pass it to action - const route = test.setup.findRoute(routes, '/ws'); - action(route); - - // Assert: - assertCaptures(service); - }; - - describe('newChannel', () => { - const assertSubscriptionToEvent = (channel, expectedEvent) => { - // Act: - setupWebsocketTest( - route => route.newChannel(channel, {}), - service => { - // Assert: channel event was registered - const handler = service.eventHandlers[expectedEvent]; - expect(handler).to.be.a('function'); - } - ); - }; - - it('subscribes to service channel event', () => { assertSubscriptionToEvent('block', 'block'); }); - it('subscribes to service channel close event', () => { assertSubscriptionToEvent('block', 'block.close'); }); - - it('handles service channel event by forwarding message to sender', () => { - // Arrange: - const message = {}; - const sendMessages = []; - const sender = { send: sendMessage => sendMessages.push(sendMessage) }; - - // Act: - setupWebsocketTest( - route => route.newChannel('block', sender), - service => { - // - invoke the handler - const handler = service.eventHandlers.block; - expect(handler).to.be.a('function'); - handler(message); - - // Assert: message was passed to handler - expect(sendMessages.length).to.equal(1); - expect(sendMessages[0]).to.equal(message); - } - ); - }); - - it('handles service channel close event by closing sender', () => { - // Arrange: - let numCloseCalls = 0; - const sender = { close: () => { ++numCloseCalls; } }; - - // Act: - setupWebsocketTest( - route => route.newChannel('block', sender), - service => { - // - invoke the handler - const handler = service.eventHandlers['block.close']; - expect(handler).to.be.a('function'); - handler(); - - // Assert: close was called on the sender - expect(numCloseCalls).to.equal(1); - } - ); - }); - }); - - describe('removeChannel', () => { - it('forwards channel to service', () => { - // Act: - setupWebsocketTest( - route => route.removeChannel('block'), - service => { - // Assert: - expect(service.removedChannels).to.deep.equal(['block']); - } - ); - }); - }); -}); diff --git a/rest/test/server/SubscriptionManager_spec.js b/rest/test/server/SubscriptionManager_spec.js deleted file mode 100644 index cc0326dc8..000000000 --- a/rest/test/server/SubscriptionManager_spec.js +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const SubscriptionManager = require('../../src/server/SubscriptionManager'); -const { expect } = require('chai'); - -describe('subscription manager', () => { - const createSubscription = (channel, client) => ({ channel, client }); - - const createChannelSubscriptions = (channelName, startId, clientCount) => { - let id = startId; - return Array.from(Array(clientCount)).map(() => { ++id; return createSubscription(channelName, `client${id}`); }); - }; - - const createSubscriptions = (...descriptors) => { - const current = []; - descriptors.forEach(descriptor => { - const [channelName, clientCount] = descriptor; - current.push(...createChannelSubscriptions(channelName, 0, clientCount)); - }); - - return current; - }; - - const addAllSubscriptions = (manager, subscriptions) => { - subscriptions.forEach(subscription => { - manager.add(subscription.channel, subscription.client); - }); - }; - - const runTest = (subscriptions, action, assertCaptures) => { - // Arrange: - const captures = { newChannels: [], clients: [], removal: [] }; - const manager = new SubscriptionManager({ - newChannel: (channel, subscribers) => captures.newChannels.push({ channel, subscribers }), - removeChannel: channel => captures.removal.push(channel), - newClient: (channel, client) => captures.clients.push({ channel, client }) - }); - - // Act: - action(manager, subscriptions); - - // Assert: common for all tests: all subscriptions are always subscribed by manager (see addAllSubscriptions) - expect(captures.clients).to.deep.equal(subscriptions); - assertCaptures(captures, manager.subscriptions); - }; - - const assertChannels = (newChannelCaptures, subscriptions, expectedChannelNames) => { - // Assert: - const channelNames = newChannelCaptures.map(capture => capture.channel); - expect(channelNames).to.deep.equal(expectedChannelNames); - - // note: subscriptions passed to assertChannels are not original subscriptions, but SubscriptionManager owned subscriptions. - // assert that proper set of clients has been passed in invocation of new channel handler - for (let id = 0; expectedChannelNames.length > id; ++id) { - const channelName = expectedChannelNames[id]; - - // if channel is not in subscriptions it means it's been deleted, and we have nothing to compare against - if (channelName in subscriptions) - expect(newChannelCaptures[id].subscribers).to.equal(subscriptions[channelName]); - } - }; - - const assertChannelSubscribers = (newChannels, expectedClientNames) => { - // Assert: - expect(Array.from(newChannels.subscribers)).to.deep.equal(expectedClientNames); - }; - - // region basic - - it('is initially empty', () => { - // Arrange: - const manager = new SubscriptionManager({}); - - // Assert: - expect(manager.subscriptions).to.deep.equal({}); - }); - - // endregion - - // region add - - it('can subscribe a single client to single channel', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 1]), - addAllSubscriptions, - (captures, subscriptions) => { - // Assert: - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1']); - assertChannelSubscribers(captures.newChannels[0], ['client1']); - } - ); - }); - - it('can subscribe a single client to the same channel multiple times', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 1]), - (...args) => { - // Act: subscribe to the same channel multiple times - for (let i = 0; 5 > i; ++i) - addAllSubscriptions(...args); - }, - (captures, subscriptions) => { - // Assert: only unique subscriptions are present - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1']); - assertChannelSubscribers(captures.newChannels[0], ['client1']); - } - ); - }); - - it('can subscribe multiple clients to single channel', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3]), - addAllSubscriptions, - (captures, subscriptions) => { - // Assert: - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1']); - assertChannelSubscribers(captures.newChannels[0], ['client1', 'client2', 'client3']); - } - ); - }); - - it('can subscribe multiple clients to multiple clients', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3], ['channel-2', 5]), - addAllSubscriptions, - (captures, subscriptions) => { - // Assert: - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1', 'channel-2']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1', 'channel-2']); - assertChannelSubscribers(captures.newChannels[0], ['client1', 'client2', 'client3']); - assertChannelSubscribers(captures.newChannels[1], ['client1', 'client2', 'client3', 'client4', 'client5']); - } - ); - }); - - it('cannot subscribe clients to an unsupported channel', () => { - // Arrange: configure newChannel to throw to simulate unsupported channel - const manager = new SubscriptionManager({ - newChannel: channel => { throw Error(`channel ${channel} is not supported`); } - }); - - // Act: add disallowed subscriptions (all attempts should fail) - expect(() => manager.add('foo')).to.throw('channel foo is not supported'); - expect(() => manager.add('foo')).to.throw('channel foo is not supported'); - - // Assert: no subscriptions were added - expect(manager.subscriptions).to.deep.equal({}); - }); - - // endregion - - // region delete - - it('can unsubscribe a client from a channel without affecting other client subscriptions', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3], ['channel-2', 5]), - (manager, subscriptions) => { - // Act: delete a single subscription - addAllSubscriptions(manager, subscriptions); - manager.delete('channel-1', 'client2'); - }, - (captures, subscriptions) => { - // Assert: no removals should have been raised because all channels are still active - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1', 'channel-2']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1', 'channel-2']); - assertChannelSubscribers(captures.newChannels[0], ['client1', 'client3']); - assertChannelSubscribers(captures.newChannels[1], ['client1', 'client2', 'client3', 'client4', 'client5']); - } - ); - }); - - it('can unsubscribe all clients from a channel without affecting other client subscriptions', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3], ['channel-2', 5]), - (manager, subscriptions) => { - // Act: delete all channel-1 subscriptions - addAllSubscriptions(manager, subscriptions); - manager.delete('channel-1', 'client2'); - manager.delete('channel-1', 'client1'); - manager.delete('channel-1', 'client3'); - }, - (captures, subscriptions) => { - // Assert: - expect(Object.keys(subscriptions)).to.deep.equal(['channel-2']); - - expect(captures.removal).to.deep.equal(['channel-1']); - assertChannels(captures.newChannels, subscriptions, ['channel-1', 'channel-2']); - assertChannelSubscribers(captures.newChannels[0], []); - assertChannelSubscribers(captures.newChannels[1], ['client1', 'client2', 'client3', 'client4', 'client5']); - } - ); - }); - - it('can unsubscribe a client from an unknown channel', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3], ['channel-2', 5]), - (manager, subscriptions) => { - // Act: delete a single subscription for an unsubscribed channel - addAllSubscriptions(manager, subscriptions); - manager.delete('channel-X', 'client2'); - }, - (captures, subscriptions) => { - // Assert: nothing should have changed - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1', 'channel-2']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1', 'channel-2']); - assertChannelSubscribers(captures.newChannels[0], ['client1', 'client2', 'client3']); - assertChannelSubscribers(captures.newChannels[1], ['client1', 'client2', 'client3', 'client4', 'client5']); - } - ); - }); - - // endregion - - // region clientSubscriptions - - it('can get client subscriptions for known clients', () => { - // Arrange: - const manager = new SubscriptionManager({ newChannel: () => {} }); - const subscriptions = createSubscriptions(['channel-1', 3], ['channel-2', 5], ['channel-3', 1]); - - // Act: - addAllSubscriptions(manager, subscriptions); - - // Assert: - expect(manager.clientSubscriptions('client1')).to.deep.equal(['channel-1', 'channel-2', 'channel-3']); - expect(manager.clientSubscriptions('client2')).to.deep.equal(['channel-1', 'channel-2']); - expect(manager.clientSubscriptions('client3')).to.deep.equal(['channel-1', 'channel-2']); - expect(manager.clientSubscriptions('client4')).to.deep.equal(['channel-2']); - expect(manager.clientSubscriptions('client5')).to.deep.equal(['channel-2']); - }); - - it('can get client subscriptions for unknown clients', () => { - // Arrange: - const manager = new SubscriptionManager({ newChannel: () => {} }); - const subscriptions = createSubscriptions(['channel-1', 3], ['channel-2', 5], ['channel-3', 1]); - - // Act: - addAllSubscriptions(manager, subscriptions); - - // Assert: - expect(manager.clientSubscriptions('clientX')).to.deep.equal([]); - }); - - it('can get client subscriptions after subscriptions and unsubscriptions', () => { - // Arrange: - const manager = new SubscriptionManager({ newChannel: () => {} }); - const subscriptions = createSubscriptions(['channel-1', 3], ['channel-2', 5], ['channel-3', 1]); - - // Act: - addAllSubscriptions(manager, subscriptions); - manager.delete('channel-1', 'client1'); - manager.delete('channel-2', 'client3'); - manager.delete('channel-2', 'client4'); - - // Assert: - expect(manager.clientSubscriptions('client1')).to.deep.equal(['channel-2', 'channel-3']); - expect(manager.clientSubscriptions('client2')).to.deep.equal(['channel-1', 'channel-2']); - expect(manager.clientSubscriptions('client3')).to.deep.equal(['channel-1']); - expect(manager.clientSubscriptions('client4')).to.deep.equal([]); - expect(manager.clientSubscriptions('client5')).to.deep.equal(['channel-2']); - }); - - // endregion - - // region deleteClient - - it('can delete a client from all subscriptions', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3], ['channel-2', 5]), - (manager, subscriptions) => { - // Act: delete a single client - addAllSubscriptions(manager, subscriptions); - manager.deleteClient('client2'); - }, - (captures, subscriptions) => { - // Assert: no removals should have been raised because all channels are still active - expect(Object.keys(subscriptions)).to.deep.equal(['channel-1', 'channel-2']); - - expect(captures.removal).to.deep.equal([]); - assertChannels(captures.newChannels, subscriptions, ['channel-1', 'channel-2']); - assertChannelSubscribers(captures.newChannels[0], ['client1', 'client3']); - assertChannelSubscribers(captures.newChannels[1], ['client1', 'client3', 'client4', 'client5']); - } - ); - }); - - it('can delete all clients subscribed to a channel', () => { - // Arrange: - runTest( - createSubscriptions(['channel-1', 3], ['channel-2', 5]), - (manager, subscriptions) => { - // Act: delete all clients - addAllSubscriptions(manager, subscriptions); - manager.deleteClient('client1'); - manager.deleteClient('client2'); - manager.deleteClient('client3'); - }, - (captures, subscriptions) => { - // Assert: - expect(Object.keys(subscriptions)).to.deep.equal(['channel-2']); - - expect(captures.removal).to.deep.equal(['channel-1']); - assertChannels(captures.newChannels, subscriptions, ['channel-1', 'channel-2']); - assertChannelSubscribers(captures.newChannels[0], []); - assertChannelSubscribers(captures.newChannels[1], ['client4', 'client5']); - } - ); - }); - - // endregion -}); diff --git a/rest/test/server/bootstrapper_spec.js b/rest/test/server/bootstrapper_spec.js deleted file mode 100644 index 50b30e910..000000000 --- a/rest/test/server/bootstrapper_spec.js +++ /dev/null @@ -1,1222 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const MessageChannelBuilder = require('../../src/connection/MessageChannelBuilder'); -const { createZmqConnectionService } = require('../../src/connection/zmqService'); -const bootstrapper = require('../../src/server/bootstrapper'); -const errors = require('../../src/server/errors'); -const formatters = require('../../src/server/formatters'); -const test = require('../testUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); -const hippie = require('hippie'); -const restify = require('restify'); -const sinon = require('sinon'); -const winston = require('winston'); -const WebSocket = require('ws'); -const zmq = require('zeromq'); -const EventEmitter = require('events'); - -const supportedHttpMethods = ['get', 'post', 'put']; - -const dummyIds = { - valid: 'valid', - replayTag: 'replayTag', - notFound: 'notFound', - redirect: 'redirect', - error: 'error', - asyncValid: 'asyncValid', - asyncError: 'asyncError' -}; - -// region dummy route - -// note that custom formatting will strip high part -const createChainStatistic = (height, scoreLow, scoreHigh) => ({ - id: 123, - current: { - height: [height, height], - scoreLow: [scoreLow, scoreLow], - scoreHigh: [scoreHigh, scoreHigh] - } -}); - -const addRestRoutes = server => { - supportedHttpMethods.forEach(method => { - server[method]('/dummy/:dummyId', (req, res, next) => { - const { dummyId } = req.params; - - switch (dummyId) { - case dummyIds.valid: { - // respond with a valid chain info - const chainStatistic = createChainStatistic(10, 16, 11); - res.send({ payload: chainStatistic, type: 'chainStatistic' }); - break; - } - - case dummyIds.replayTag: { - // respond with a valid chain info computed from the tag parameter - const tag = req.params.tag | 0; // query parameters are parsed as strings so convert to int - const chainStatistic = createChainStatistic(tag, tag, tag); - res.send({ payload: chainStatistic, type: 'chainStatistic' }); - break; - } - - case dummyIds.notFound: - res.send(errors.createNotFoundError('foo')); // http errors are mapped properly - break; - - case dummyIds.redirect: - res.redirect(`/dummy/${dummyIds.valid}`, next); - return undefined; // don't call next below because it is called by res.redirect - - case dummyIds.asyncValid: - return Promise.resolve({ current: { height: [11, 11] } }) - .then(chainStatistic => { - res.send({ payload: chainStatistic, type: 'chainStatistic' }); - next(); - }); - - case dummyIds.asyncError: - return Promise.reject(Error('async badness')); - - default: - throw Error('badness'); // exceptions are handled properly - } - - // complete non-async, non-exceptional handling - next(); - return undefined; - }); - }); -}; - -// endregion - -const servers = []; - -const createFormatters = options => formatters.create({ - [(options && options.formatterName) || 'json']: { - chainStatistic: { - // real formatting is not actually being tested, so just drop high part - format: chainStatistic => { - const formatUint64 = uint64 => (uint64 ? [uint64[0], 0] : undefined); - const formatChainStatisticCurrent = chainStatisticCurrent => ({ - height: formatUint64(chainStatisticCurrent.height), - scoreLow: formatUint64(chainStatisticCurrent.scoreLow), - scoreHigh: formatUint64(chainStatisticCurrent.scoreHigh) - }); - - return { - id: chainStatistic.id, - current: formatChainStatisticCurrent(chainStatistic.current) - }; - } - }, - blockHeaderWithMetadata: { - // real formatting is not actually being tested, so just format a few properties - format: blockHeaderWithMetadata => { - const { block } = blockHeaderWithMetadata; - return { - height: block.height, - signerPublicKey: catapult.utils.convert.uint8ToHex(block.signerPublicKey) - }; - } - } - } -}); - -const createServer = options => { - const server = bootstrapper.createServer((options || {}), createFormatters(options)); - servers.push(server); - return server; -}; - -const createWebSocketServer = () => createServer({ protocol: 'HTTP', formatterName: 'ws' }); - -describe('server (bootstrapper)', () => { - afterEach(() => { - // close servers used during the previous test - while (0 < servers.length) { - const server = servers.pop(); - server.close(); - } - }); - - // throttling tests are not ideal (can't guarantee those were added to the server) because everything related - // to the restify server happens intrinsically and is too coupled - those are best-effort tests - describe('throttling config', () => { - it('uses provided config', done => { - // Arrange: - const throttlingConfig = { - burst: 20, - rate: 5 - }; - const spy = sinon.spy(restify.plugins, 'throttle'); - - // Act: - bootstrapper.createServer({ protocol: 'HTTP' }, createFormatters(), throttlingConfig); - - // Assert: - expect(spy.calledOnceWith({ - burst: 20, - rate: 5, - ip: true - })).to.equal(true); - - spy.restore(); - done(); - }); - - it('does not throttle if no configuration present', done => { - // Arrange: - const spy = sinon.spy(restify.plugins, 'throttle'); - - // Act: - bootstrapper.createServer({ protocol: 'HTTP' }, createFormatters()); - - // Assert: - expect(spy.notCalled).to.equal(true); - - spy.restore(); - done(); - }); - - describe('does not throttle for incomplete configuration and logs a warning', () => { - it('missing rate', done => { - // Arrange: - const spy = sinon.spy(restify.plugins, 'throttle'); - const logSpy = sinon.spy(winston, 'warn'); - - // Act: - bootstrapper.createServer({ protocol: 'HTTP' }, createFormatters(), { burst: 20 }); - spy.restore(); - logSpy.restore(); - - // Assert: - expect(spy.notCalled).to.equal(true); - expect(logSpy.calledWith('throttling was not enabled - configuration is invalid or incomplete')).to.equal(true); - - done(); - }); - - it('missing burst', done => { - // Arrange: - const spy = sinon.spy(restify.plugins, 'throttle'); - const logSpy = sinon.spy(winston, 'warn'); - - // Act: - bootstrapper.createServer({ protocol: 'HTTP' }, createFormatters(), { rate: 20 }); - spy.restore(); - logSpy.restore(); - - // Assert: - expect(spy.notCalled).to.equal(true); - expect(logSpy.calledWith('throttling was not enabled - configuration is invalid or incomplete')).to.equal(true); - - done(); - }); - }); - }); - - describe('HTTP', () => { - const wrapHippieEndHandler = handler => (err, res, body) => { - if (err) - throw err; - - handler(res.headers, body); - }; - - const makeJsonHippie = (route, method, options) => { - const server = createServer({ ...options, protocol: 'HTTP' }); - addRestRoutes(server); - - const mockServer = hippie(server).json()[method](route); - if ('get' === method) { - // hippie.form() overrides Content-Type to 'application/x-www-form-urlencoded' and uses a matching serializer - // since hippie.json() was called before, Accept is still 'application/json' and has a matching parser - mockServer.form(); - } - - // wrap the server to make sure errors are handled appropriately across all tests - const hippieAdapter = { - end: handler => { - mockServer.end(wrapHippieEndHandler(handler)); - return hippieAdapter; - } - }; - - // expose allowed methods - ['header', 'send', 'expectStatus', 'expectHeader'].forEach(delegatingMethod => { - hippieAdapter[delegatingMethod] = (...args) => { - mockServer[delegatingMethod](...args); - return hippieAdapter; - }; - }); - - return hippieAdapter; - }; - - const assertPayloadHeaders = (headers, expectedContentLength, options = {}) => { - const shouldAllowCrossDomain = !!options.allowedMethods; - const shouldHaveContent = undefined !== expectedContentLength; - - const message = `received headers: ${JSON.stringify(headers)}`; - const numExpectedHeaders = 2 - + (options.numAdditionalHeaders | 0) - + (shouldAllowCrossDomain ? 3 : 0) - + (shouldHaveContent ? 2 : 0); - expect(Object.keys(headers).length, message).to.equal(numExpectedHeaders); - - // these headers should always be stamped - expect(headers.connection).to.equal('close'); - expect(headers.date).to.not.equal(undefined); - - // these headers should be stamped when there is a response body - if (shouldHaveContent) { - expect(headers['content-length'], message).to.equal(expectedContentLength.toString()); - expect(headers['content-type']).to.equal('application/json'); - } - - // these headers should be stamped when cross domain is allowed - if (shouldAllowCrossDomain) { - expect(headers['access-control-allow-origin']).to.equal('*'); - expect(headers['access-control-allow-methods']).to.equal(options.allowedMethods); - expect(headers['access-control-allow-headers']).to.equal('Content-Type'); - } - }; - - const addCommonTestsForHttpMethod = method => { - const methodOptions = {}; - - // region sync route handling - - it('handles success properly', done => { - makeJsonHippie(`/dummy/${dummyIds.valid}`, method) - .expectStatus(200) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 75, methodOptions); - expect(body).to.deep.equal({ - id: 123, - current: { height: [10, 0], scoreLow: [16, 0], scoreHigh: [11, 0] } - }); - done(); - }); - }); - - it('can parse query params', done => { - makeJsonHippie(`/dummy/${dummyIds.replayTag}?tag=25`, method) - .expectStatus(200) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 75, methodOptions); - expect(body).to.deep.equal({ - id: 123, - current: { height: [25, 0], scoreLow: [25, 0], scoreHigh: [25, 0] } - }); - done(); - }); - }); - - it('handles not found properly', done => { - makeJsonHippie(`/dummy/${dummyIds.notFound}`, method) - .expectStatus(404) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 72, methodOptions); - expect(body).to.deep.equal({ code: 'ResourceNotFound', message: 'no resource exists with id \'foo\'' }); - done(); - }); - }); - - it('handles error properly', done => { - makeJsonHippie(`/dummy/${dummyIds.error}`, method) - .expectStatus(500) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 39, methodOptions); - expect(body).to.deep.equal({ code: 'Internal', message: 'badness' }); - done(); - }); - }); - - // endregion - - // region async route handling - - it('handles async success properly', done => { - makeJsonHippie(`/dummy/${dummyIds.asyncValid}`, method) - .expectStatus(200) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 29, methodOptions); - expect(body).to.deep.equal({ current: { height: [11, 0] } }); - done(); - }); - }); - - it('handles async error properly', done => { - makeJsonHippie(`/dummy/${dummyIds.asyncError}`, method) - .expectStatus(500) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 45, methodOptions); - expect(body).to.deep.equal({ code: 'Internal', message: 'async badness' }); - done(); - }); - }); - - // endregion - - // region server errors - - it('handles non existent route properly', done => { - makeJsonHippie(`/fake/${dummyIds.valid}`, method) - .expectStatus(404) - .end((headers, body) => { - // Assert: note that non-existent routes never support cross domain - assertPayloadHeaders(headers, 66); - expect(body).to.deep.equal({ code: 'ResourceNotFound', message: '/fake/valid does not exist' }); - done(); - }); - }); - - it('rejects request with invalid accept header', done => { - makeJsonHippie(`/dummy/${dummyIds.valid}`, method) - .header('Accept', 'text/plain') - .expectStatus(406) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 69, methodOptions); - expect(body).to.deep.equal({ code: 'NotAcceptable', message: 'Server accepts: application/json' }); - done(); - }); - }); - - // endregion - - // region cross domain - - it('logs a warning if CORS configuration not provided', done => { - // Arrange: - const spy = sinon.spy(winston, 'warn'); - - // Act: - bootstrapper.createServer({ protocol: 'HTTP' }, createFormatters()); - spy.restore(); - - // Assert: - expect(spy.calledWith('CORS was not enabled - configuration incomplete')).to.equal(true); - - done(); - }); - - it('omits CORS response if no config provided', done => { - // Arrange: - const crossDomainAdder = bootstrapper.createCrossDomainHeaderAdder(); - const request = { - method: 'GET', - headers: { origin: 'http://nem.example' } - }; - const response = { header: sinon.spy() }; - - // Act: - crossDomainAdder(request, response); - - // Assert: - expect(response.header.notCalled).to.equal(true); - - done(); - }); - - it('builds CORS response with wildcard as set in the config', done => { - // Arrange: - const crossDomainAdder = bootstrapper.createCrossDomainHeaderAdder({ allowedMethods: ['GET'], allowedHosts: ['*'] }); - const request = { - method: 'GET', - headers: { origin: 'http://nem.example' } - }; - const response = { header: sinon.spy() }; - - // Act: - crossDomainAdder(request, response); - - // Assert: - expect(response.header.calledThrice).to.equal(true); - expect(response.header.calledWith('Access-Control-Allow-Origin', '*')).to.equal(true); - expect(response.header.calledWith('Access-Control-Allow-Methods', 'GET')).to.equal(true); - expect(response.header.calledWith('Access-Control-Allow-Headers', 'Content-Type')).to.equal(true); - - done(); - }); - - it('builds CORS response with matching origin in the provided config', done => { - // Arrange: - const crossDomainAdder = bootstrapper.createCrossDomainHeaderAdder({ - allowedMethods: ['GET'], allowedHosts: ['http://nem.example'] - }); - const request = { - method: 'GET', - headers: { origin: 'http://nem.example' } - }; - const response = { header: sinon.spy() }; - - // Act: - crossDomainAdder(request, response); - - // Assert: - expect(response.header.callCount).to.equal(4); - expect(response.header.calledWith('Access-Control-Allow-Origin', 'http://nem.example')).to.equal(true); - expect(response.header.calledWith('Vary', 'Origin')).to.equal(true); - expect(response.header.calledWith('Access-Control-Allow-Methods', 'GET')).to.equal(true); - expect(response.header.calledWith('Access-Control-Allow-Headers', 'Content-Type')).to.equal(true); - - done(); - }); - - it('omits CORS response if provided operation not allowed', done => { - // Arrange: - const crossDomainAdder = bootstrapper.createCrossDomainHeaderAdder({ - allowedMethods: ['GET'], allowedHosts: ['http://nem.example'] - }); - const request = { - method: 'POST', - headers: { origin: 'http://nem.example' } - }; - const response = { header: sinon.spy() }; - - // Act: - crossDomainAdder(request, response); - - // Assert: - expect(response.header.notCalled).to.equal(true); - - done(); - }); - - it('omits CORS response if origin does not match provided config', done => { - // Arrange: - const crossDomainAdder = bootstrapper.createCrossDomainHeaderAdder({ - allowedMethods: ['GET'], allowedHosts: ['http://nem.example'] - }); - const request = { - method: 'GET', - headers: { origin: 'http://bad.example' } - }; - const response = { header: sinon.spy() }; - - // Act: - crossDomainAdder(request, response); - - // Assert: - expect(response.header.notCalled).to.equal(true); - - done(); - }); - - it('omits CORS response if origin not provided in the request', done => { - // Arrange: - const crossDomainAdder = bootstrapper.createCrossDomainHeaderAdder({ - allowedMethods: ['GET', 'OPTIONS'], allowedHosts: ['*'] - }); - const crossDomainAdder2 = bootstrapper.createCrossDomainHeaderAdder({ - allowedMethods: ['GET'], allowedHosts: ['http://nem.example'] - }); - const request = { - method: 'GET', - headers: {} - }; - const response = { header: sinon.spy() }; - const response2 = { header: sinon.spy() }; - - // Act: - crossDomainAdder(request, response); - crossDomainAdder2(request, response2); - - // Assert: - expect(response.header.notCalled).to.equal(true); - expect(response2.header.notCalled).to.equal(true); - - done(); - }); - - // endregion - }; - - // region unsupported media type - - const runUnsupportedMediaTypeTest = (server, mediaType, sendBody, done) => { - server - .header('Content-Type', mediaType) - .send(sendBody ? { foo: 'bar' } : '') - .expectStatus(415) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 44 + mediaType.length); - expect(body).to.deep.equal({ code: 'UnsupportedMediaType', message: mediaType }); - done(); - }); - }; - - const runUnsupportedMediaTypeTestForMethod = (method, mediaType, sendBody, done) => { - const server = makeJsonHippie(`/dummy/${dummyIds.valid}`, method); - runUnsupportedMediaTypeTest(server, mediaType, sendBody, done); - }; - - // endregion - - describe('GET', () => { - addCommonTestsForHttpMethod('get'); - - it('rejects request with body with supported media type', done => { - runUnsupportedMediaTypeTestForMethod('get', 'application/json', true, done); - }); - - it('rejects request with body with unsupported media type', done => { - runUnsupportedMediaTypeTestForMethod('get', 'application/octet-stream', true, done); - }); - }); - - const addRejectsUnsupportedMediaTypeTests = method => { - it('rejects request with unsupported (custom) media type without body', done => { - runUnsupportedMediaTypeTestForMethod(method, 'text/plain', false, done); - }); - - it('rejects request with unsupported (custom) media type with body', done => { - runUnsupportedMediaTypeTestForMethod(method, 'text/plain', true, done); - }); - - it('rejects request with unsupported (built-in) media type without body', done => { - runUnsupportedMediaTypeTestForMethod(method, 'application/x-www-form-urlencoded', false, done); - }); - - it('rejects request with unsupported (built-in) media type with body', done => { - runUnsupportedMediaTypeTestForMethod(method, 'application/x-www-form-urlencoded', true, done); - }); - }; - - const addBodyParsingTest = method => { - it('can parse json body', done => { - makeJsonHippie(`/dummy/${dummyIds.replayTag}`, method) - .send({ tag: 25 }) - .expectStatus(200) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 75, {}); - expect(body).to.deep.equal({ - id: 123, - current: { height: [25, 0], scoreLow: [25, 0], scoreHigh: [25, 0] } - }); - done(); - }); - }); - }; - - describe('PUT', () => { - const method = 'put'; - addCommonTestsForHttpMethod(method); - addRejectsUnsupportedMediaTypeTests(method); - addBodyParsingTest(method); - }); - - describe('POST', () => { - const method = 'post'; - addCommonTestsForHttpMethod(method); - addRejectsUnsupportedMediaTypeTests(method); - addBodyParsingTest(method); - }); - - describe('OPTIONS', () => { - const makeJsonHippieForOptions = route => { - const server = createServer({ - protocol: 'HTTP', - crossDomain: { allowedMethods: ['FOO', 'OPTIONS', 'BAR'], allowedHosts: ['*'] } - }); - const routeHandler = (req, res, next) => { - res.send(200); - next(); - }; - - server.get('/dummy/:dummyId', routeHandler); - server.post('/dummy/names', routeHandler); - server.post('/dummy', routeHandler); - - return hippie(server) - .header('Origin', 'http://nem.example') - .url(route) - .method('OPTIONS') - .json() - .form(); - }; - - const runBasicOptionsTest = (route, expectedMethod, done) => { - makeJsonHippieForOptions(route) - .expectStatus(204) - .expectHeader('allow', expectedMethod) - .end(wrapHippieEndHandler((headers, body) => { - // Assert: there should be no body - assertPayloadHeaders(headers, undefined, { allowedMethods: 'FOO,OPTIONS,BAR', numAdditionalHeaders: 1 }); - expect(body).to.equal(null); - done(); - })); - }; - - it('supports GET', done => { - runBasicOptionsTest('/dummy/123', 'GET', done); - }); - - it('supports POST', done => { - runBasicOptionsTest('/dummy', 'POST', done); - }); - - it('allows all matches', done => { - // notice that /dummy/names could also match GET /dummy/:dummyId - runBasicOptionsTest('/dummy/names', 'GET, POST', done); - }); - - it('handles non existent route properly', done => { - makeJsonHippieForOptions(`/fake/${dummyIds.valid}`) - .expectStatus(404) - .end(wrapHippieEndHandler((headers, body) => { - // Assert: note that non-existent routes never support cross domain - assertPayloadHeaders(headers, 66); - expect(body).to.deep.equal({ code: 'ResourceNotFound', message: '/fake/valid does not exist' }); - done(); - })); - }); - - const runUnsupportedMediaTypeTestForOptions = (mediaType, done) => { - makeJsonHippieForOptions('/dummy') - .header('Content-Type', mediaType) - .send({ foo: 'bar' }) - .expectStatus(415) - .end(wrapHippieEndHandler((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 44 + mediaType.length); - expect(body).to.deep.equal({ code: 'UnsupportedMediaType', message: mediaType }); - done(); - })); - }; - - it('rejects request with body with supported media type', done => { - runUnsupportedMediaTypeTestForOptions('application/json', done); - }); - - it('rejects request with body with unsupported media type', done => { - runUnsupportedMediaTypeTestForOptions('application/octet-stream', done); - }); - }); - - describe('other', () => { - it('rejects invalid methods', done => { - makeJsonHippie(`/dummy/${dummyIds.valid}`, 'del') - .expectStatus(405) - .expectHeader('allow', 'GET, POST, PUT') - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 61, { numAdditionalHeaders: 1 }); - expect(body).to.deep.equal({ code: 'MethodNotAllowed', message: 'DELETE is not allowed' }); - done(); - }); - }); - - it('follows redirects', done => { - // Arrange: 'redirect' should redirect to 'valid' - makeJsonHippie(`/dummy/${dummyIds.redirect}`, 'get') - .expectStatus(302) - .expectHeader('location', `/dummy/${dummyIds.valid}`) - .end((headers, body) => { - // Assert: - assertPayloadHeaders(headers, 4, { numAdditionalHeaders: 1 }); - expect(body).to.equal(null); - done(); - }); - }); - }); - }); - - describe('HTTPS', () => { - it('creates https server with certificate and key given', done => { - createServer({ - port: 3001, - protocol: 'HTTPS', - sslKeyPath: `${__dirname}/certs/restSSL.key`, - sslCertificatePath: `${__dirname}/certs/restSSL.crt` - }); - done(); - }); - - it('throws error when the key path is missing', done => { - expect(() => createServer({ port: 3001, protocol: 'HTTPS', sslCertificatePath: `${__dirname}/certs/restSSL.crt` })) - .to.throw('No SSL Key found, \'sslKeyPath\' property in the configuration must be provided.'); - done(); - }); - - it('throws error when the certificate path is missing', done => { - expect(() => createServer({ port: 3001, protocol: 'HTTPS', sslKeyPath: `${__dirname}/certs/restSSL.key` })) - .to.throw('No SSL Certificate found, ' - + '\'sslCertificatePath\' property in the configuration must be provided.'); - done(); - }); - - it('starts https and throws error when the protocol is not defined', done => { - expect(() => createServer({ port: 3001 })).to.throw(); - done(); - }); - - it('starts http when the protocol is HTTP', done => { - createServer({ port: 3001, protocol: 'HTTP' }); - done(); - }); - - it('handles HTTPS routes successfully', done => { - // For unit testing, the unit test client ignores self-signed certificate errors. - process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - - const httpsPort = 3001; - const server = createServer({ - port: httpsPort, - protocol: 'HTTPS', - sslKeyPath: `${__dirname}/certs/restSSL.key`, - sslCertificatePath: `${__dirname}/certs/restSSL.crt` - }); - - addRestRoutes(server); - server.listen(httpsPort); - - hippie() - .header('User-Agent', 'hippie') - .json() - .get(`https://127.0.0.1:${httpsPort}/dummy/${dummyIds.valid}`) - .expectStatus(200) - .end((err, res, body) => { - expect(body).to.deep.equal({ - id: 123, - current: { height: [10, 0], scoreLow: [16, 0], scoreHigh: [11, 0] } - }); - done(); - }); - }); - }); - - describe('websockets', () => { - // note: although rest server implementation uses single websocket route ('/ws'), - // server.ws allows you to register any name and you can register multiple different routes - // the tests are using custom `/ws/block*` routes - - const ports = { server: 1234, mq: 7912 }; - const delays = { publish: 50 }; - - const createBlockBuffer = tag => Buffer.concat([ - Buffer.of(0x30, 0x01, 0x00, 0x00), // size 4b - Buffer.of(0x00, 0x00, 0x00, 0x00), // verifiable entity header reserved 1 4b - Buffer.from(test.random.bytes(test.constants.sizes.signature)), // signature 64b - Buffer.from('A4C656B45C02A02DEF64F15DD781DD5AF29698A353F414FAAA9CDB364A09F98F', 'hex'), // signerPublicKey 32b - Buffer.of(0x00, 0x00, 0x00, 0x00), // entity body reserved 1 4b - Buffer.of(0x03), // version 1b - Buffer.of(0x90), // network 1b - Buffer.of(0x00, 0x80), // type 2b - Buffer.of(0x97, 0x87, 0x45, 0x0E, tag || 0xE1, 0x6C, 0xB6, 0x62), // height 8b - Buffer.from(test.random.bytes(8)), // timestamp 8b - Buffer.from(test.random.bytes(8)), // difficulty 8b - Buffer.from(test.random.bytes(32)), // proofGamma 32b - Buffer.from(test.random.bytes(16)), // proofVerificationHash 16b - Buffer.from(test.random.bytes(32)), // proofScalar 32b - Buffer.from(test.random.bytes(test.constants.sizes.hash256)), // previous block hash 32b - Buffer.from(test.random.bytes(test.constants.sizes.hash256)), // transactionsHashBuffer 32b - Buffer.from(test.random.bytes(test.constants.sizes.hash256)), // receiptsHashBuffer 32b - Buffer.from(test.random.bytes(test.constants.sizes.hash256)), // stateHashBuffer 32b - test.random.bytes(test.constants.sizes.addressDecoded), // beneficiaryAddress 24b - Buffer.of(0x0A, 0x00, 0x00, 0x00), // fee feeMultiplierBuffer 4b - Buffer.of(0x00, 0x00, 0x00, 0x00) // reserved padding 4b - ]); - - // notice that the formatter only returns height and signerPublicKey - const createFormattedBlock = tag => ({ - topic: 'block', - data: { - height: [0x0E458797, 0x62B66C00 | (tag || 0xE1)], - signerPublicKey: 'A4C656B45C02A02DEF64F15DD781DD5AF29698A353F414FAAA9CDB364A09F98F' - } - }); - - const registerRoute = (server, route) => { - // create a zmq service that supports only basic (non-transaction) models - const modelSystem = catapult.plugins.catapultModelSystem.configure([], {}); - const config = { - host: '127.0.0.1', port: ports.mq, connectTimeout: 1000, monitorInterval: 50 - }; - const channelDescriptors = new MessageChannelBuilder().build(); - const zmqService = createZmqConnectionService(config, modelSystem.codec, channelDescriptors, test.createMockLogger()); - - // create a custom emitter for raising client connected events - const emitter = new EventEmitter(); - - // register a ws route (notice that these callbacks make the same calls to zmqService as the callbacks in wsRoutes) - // except for newClient, which is exclusively used for testing - server.ws(route, { - newChannel: (channel, sender) => zmqService.on(channel, object => sender.send(object)), - removeChannel: channel => zmqService.removeAllListeners(channel), - newClient: () => { emitter.emit('clientConnected'); } - }); - - return emitter; - }; - - const extractBasicClientOptionValues = options => { - if ('number' !== typeof options) - return { numTotalClients: options.numClients, messageIds: options.messageIds }; - - // by default, expect all message ids - const messageIds = new Set(); - for (let i = 1; i <= options; ++i) - messageIds.add(i); - - return { numTotalClients: options, messageIds }; - }; - - const createBoundZsocket = () => { - const zsocket = zmq.socket('pub'); - zsocket.bindSync(`tcp://127.0.0.1:${ports.mq}`); - return zsocket; - }; - - const publishBlock = (zsocket, buffer) => { - // publish the block buffer to the block topic after short delay to allow subscribers to finish attaching - setTimeout(() => { - test.log('publishing block data'); - zsocket.send([Buffer.of(0x49, 0x6A, 0xCA, 0x80, 0xE4, 0xD8, 0xF2, 0x9F), buffer]); - }, delays.publish); - }; - - const createClientSockets = (route, emitter, options, handlers) => { - const { numTotalClients, messageIds } = extractBasicClientOptionValues(options); - - // bind to a publisher if one is not provided - const zsocket = options.zsocket || createBoundZsocket(); - const sockets = []; - - const curryMessageCallback = (ws, id) => messageJson => { - test.log(`${route} (id ${id}) received message: ${messageJson}`); - - // 1. if uid is sent, subscribe to topic 'block' - const message = messageJson ? JSON.parse(messageJson) : {}; - if ('uid' in message) { - const responseJson = JSON.stringify(Object.assign(message, { subscribe: 'block' })); - ws.send(responseJson); - test.log('subscribed to block'); - - // store the client id in the socket - ws.uid = message.uid; - return; - } - - // 2. if uid is not sent, handle payload (should be block buffer) - const messageHandler = () => { - expect(messageIds.has(id), `message id ${id}`).to.equal(true); - messageIds.delete(id); - handlers.onMessage(JSON.parse(messageJson)); - - if (0 === messageIds.size) { - test.log('all messages processed'); - handlers.onAllMessages(zsocket, sockets); - } - }; - - messageHandler(id, messageJson); - }; - - // create web sockets - let numRemainingClients = numTotalClients; - for (let i = 1; i <= numTotalClients; ++i) { - const ws = new WebSocket(`ws://localhost:${ports.server}${route}`); - sockets.push(ws); - ws.on('message', curryMessageCallback(ws, i)); - } - - // aggregate test 'clientConnected' events to raise onAllConnected - emitter.on('clientConnected', () => { - if (0 === --numRemainingClients) { - test.log('all clients connected'); - handlers.onAllConnected(zsocket, sockets); - } - }); - }; - - const createHandlers = (server, done, blockTag = undefined) => ({ - onAllConnected: zsocket => { - // Act: publish a block - publishBlock(zsocket, createBlockBuffer(blockTag)); - }, - onMessage: payload => { - // Assert: notice that payload is already formatted - expect(payload, `blockTag: ${blockTag}`).to.deep.equal(createFormattedBlock(blockTag)); - }, - onAllMessages: zsocket => { - // close mq socket and server, otherwise subsequent tests would fail - zsocket.close(); - server.close(); - done(); - } - }); - - const runSingleRouteTest = (numClients, done) => { - // Arrange: set up the server with a single ws route - const server = createWebSocketServer(); - const emitter = registerRoute(server, '/ws/block'); - server.listen(ports.server); - - // Act + Assert: create a client websocket and run the test - createClientSockets('/ws/block', emitter, numClients, createHandlers(server, done)); - }; - - // region subscribe - - it('handles single subscription', done => runSingleRouteTest(1, done)); - it('handles multiple subscriptions to same route', done => runSingleRouteTest(3, done)); - - it('handles multiple subscriptions to different routes', done => { - // Arrange: set up the server with two ws routes - const server = createWebSocketServer(); - const emitter1 = registerRoute(server, '/ws/block1'); - const emitter2 = registerRoute(server, '/ws/block2'); - server.listen(ports.server); - - const counts = { - numAllConnectedHandlers: 0, - numAllMessagesHandlers: 0 - }; - const customHandlers = { - onAllConnected: zsocket => { - // - push to the mq only when both websockets are connected - if (2 === ++counts.numAllConnectedHandlers) - createHandlers(server, done).onAllConnected(zsocket); - }, - onAllMessages: zsocket => { - // - close the server only when messages from both websockets are received and processed - if (2 === ++counts.numAllMessagesHandlers) - createHandlers(server, done).onAllMessages(zsocket); - } - }; - - // - bind to a zsocket - const zsocket = createBoundZsocket(); - - // Act + Assert: create two client websockets pointed to different routes - // (the routes themselves are meaningless and both will get the same data; the single push above pushes to both routes) - // (the only difference is that the set of connections and ids are per-route, which is why both connections will have id 1) - const createOptions = () => ({ numClients: 1, messageIds: new Set([1]), zsocket }); - createClientSockets('/ws/block1', emitter1, createOptions(), Object.assign(createHandlers(server, done), customHandlers)); - createClientSockets('/ws/block2', emitter2, createOptions(), Object.assign(createHandlers(server, done), customHandlers)); - }); - - // endregion - - // region unsubscribe - - it('handles unsubscription of client from subscribed channel', done => { - // Arrange: set up the server with a single ws route - const server = createWebSocketServer(); - const emitter = registerRoute(server, '/ws/block'); - server.listen(ports.server); - - // - create three client websockets - const defaultHandlers = createHandlers(server, done); - const defaultOnAllConnected = defaultHandlers.onAllConnected; - const defaultOnAllMessages = defaultHandlers.onAllMessages; - createClientSockets( - '/ws/block', - emitter, - { numClients: 3, messageIds: new Set([1, 3]) }, // messages should only be sent to the first and last sockets - Object.assign(defaultHandlers, { - onAllConnected: (zsocket, sockets) => { - // Act: unsubscribe the second websocket - test.log('unsubscribing second websocket'); - sockets[1].send(JSON.stringify({ uid: sockets[1].uid, unsubscribe: 'block' })); - defaultOnAllConnected(zsocket, sockets); - }, - onAllMessages: (zsocket, sockets) => { - // Assert: all sockets are still open - sockets.forEach(socket => { - expect(socket.readyState).to.equal(WebSocket.OPEN); - }); - - defaultOnAllMessages(zsocket); - } - }) - ); - }); - - it('handles unsubscription of client from unknown channel', done => { - // Arrange: set up the server with a single ws route - const server = createWebSocketServer(); - const emitter = registerRoute(server, '/ws/block'); - server.listen(ports.server); - - // - create three client websockets - const defaultHandlers = createHandlers(server, done); - const defaultOnAllConnected = defaultHandlers.onAllConnected; - createClientSockets( - '/ws/block', - emitter, - 3, - Object.assign(defaultHandlers, { - onAllConnected: (zsocket, sockets) => { - // Act: unsubscribe the second websocket from an unknown channel (this should have no effect) - test.log('unsubscribing second websocket'); - sockets[1].send(JSON.stringify({ uid: sockets[1].uid, unsubscribe: 'chainStatistic' })); - defaultOnAllConnected(zsocket, sockets); - } - }) - ); - }); - - // endregion - - // region disconnect (client) - - it('handles disconnecting client sockets', done => { - // Arrange: set up the server with a single ws route - const server = createWebSocketServer(); - const emitter = registerRoute(server, '/ws/block'); - server.listen(ports.server); - - // - create three client websockets - const defaultHandlers = createHandlers(server, done); - const defaultOnAllConnected = defaultHandlers.onAllConnected; - createClientSockets( - '/ws/block', - emitter, - { numClients: 3, messageIds: new Set([1, 3]) }, // messages should only be sent to the first and last sockets - Object.assign(defaultHandlers, { - onAllConnected: (zsocket, sockets) => { - // Act: close the second websocket - test.log('closing second websocket'); - sockets[1].close(); - defaultOnAllConnected(zsocket, sockets); - } - }) - ); - }); - - // endregion - - // region invalid subscription requests - - const runInvalidClientTest = (done, messageCallback) => { - // Arrange: set up the server with a single ws route - const server = createWebSocketServer(); - registerRoute(server, '/ws/block'); - server.listen(ports.server); - - // - connect four clients to the route - const numConnections = 4; - let numCloses = 0; - const addHandlers = (ws, id) => { - ws.on('message', messageJson => messageCallback(ws, messageJson)); - ws.on('close', () => { - // Assert: all clients have been closed - test.log(`client ${id} was closed`); - if (numConnections === ++numCloses) { - // close server, otherwise subsequent tests would fail - server.close(); - done(); - } - }); - }; - - for (let i = 0; i < numConnections; ++i) { - const ws = new WebSocket(`ws://localhost:${ports.server}/ws/block`); - addHandlers(ws, i); - } - }; - - it('invalid data disconnects client', done => { - runInvalidClientTest(done, ws => { - // Act: non-json data - ws.send('hello'); - }); - }); - - it('malformed request disconnects client', done => { - runInvalidClientTest(done, (ws, messageJson) => { - // Arrange: - const message = JSON.parse(messageJson); - Object.assign(message, { subscribe: 7 }); - - // Act: subscribe must be a string - ws.send(JSON.stringify(message)); - }); - }); - - it('unsupported topic subscribe request disconnects client', done => { - runInvalidClientTest(done, (ws, messageJson) => { - // Act: try to subscribe to an unsupported topic - const responseJson = JSON.stringify(Object.assign(JSON.parse(messageJson), { subscribe: 'chainStatistic' })); - ws.send(responseJson); - }); - }); - - // endregion - - // region close (server) - - it('closing server closes all clients', done => { - // Arrange: set up the server with two ws routes - const server = createWebSocketServer(); - registerRoute(server, '/ws/block1'); - registerRoute(server, '/ws/block2'); - server.listen(ports.server); - - // - connect two clients to each route - const numConnections = 4; - let numOpens = 0; - let numCloses = 0; - - const addHandlers = (ws, id) => { - ws.on('open', () => { - // Act: close the server after all connections have been opened - if (numConnections === ++numOpens) - // close server, otherwise subsequent tests would fail - server.close(); - }); - - ws.on('close', () => { - // Assert: all clients have been closed - test.log(`client ${id} was closed`); - if (numConnections === ++numCloses) - done(); - }); - }; - - for (let i = 0; i < numConnections; ++i) { - const routePostfix = (i % 2) + 1; - const ws = new WebSocket(`ws://localhost:${ports.server}/ws/block${routePostfix}`); - addHandlers(ws, i); - } - }); - - // endregion - }); - - // endregion -}); diff --git a/rest/test/server/certs/restSSL.crt b/rest/test/server/certs/restSSL.crt deleted file mode 100644 index 4011881c1..000000000 --- a/rest/test/server/certs/restSSL.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFwTCCA6mgAwIBAgIUAIYz+h52BpXbB8JEOZVqRM86Ck0wDQYJKoZIhvcNAQEL -BQAwcDELMAkGA1UEBhMCVVMxDzANBgNVBAgMBk9yZWdvbjERMA8GA1UEBwwIUG9y -dGxhbmQxFTATBgNVBAoMDENvbXBhbnkgTmFtZTEMMAoGA1UECwwDT3JnMRgwFgYD -VQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjEwNzI4MTgyMjQ2WhcNMjIwNzI4MTgy -MjQ2WjBwMQswCQYDVQQGEwJVUzEPMA0GA1UECAwGT3JlZ29uMREwDwYDVQQHDAhQ -b3J0bGFuZDEVMBMGA1UECgwMQ29tcGFueSBOYW1lMQwwCgYDVQQLDANPcmcxGDAW -BgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC -AgoCggIBAMIC1Xz11K6pVbw9rJdiYtn93MdeEkLdpWLj3Mw+lMOUrWuESgKtPuGj -/hB5C18sWWcDF4hofz8GU7AMyHo5jHiz54KmbcuZewp+SfL4UHUNOfwbFXpiO8nf -+hsVd9YY6GEF85iYg/sczfVDIjODCfONgI0t5QCiKvh/rIbe+zbn7pd40S9jFqeA -VngAXbzYZ+ExiOksdSkp2gUNdoDEHRXi007lUXK5prl1kff4TH/TlFLDiPJsN8ck -Zkgt/vtYdIcw4kxm0ToPBP4Mlxq8jBXqnq9bvtv+ypcUVi5BbsGJkw2cDOz0l1j/ -aUXKRsXuKNGodM57h+Qt8pYSq1Ydxl4VtzhueyDscsOZNGK9rhinXKYQkV+yFzpY -/1j3OnOZlcOa/rJyYpR96SBxZFDXor1rQ79EwBLQlBQztFK2cgBisVAR/M4UqE5a -WUJwyWsX3Dq0gJ4oYT+10X8eu5+TNAVBUWJ7xmAo7iftjeoWrMow47ChE9mIhAqy -H2H+B4U2o2J9GJpOjOPe+yJaoBkAp71EYCReT5xv4J2y0Oa5LJyQ5f9EnvIoUGNe -fC8ZrTiPqvk0ztAr6ejdzxIhlny6+BON/nab0mPWYc7RdfYshUzUeG7jXPJrAezK -1AMvPApqeO8mJeMv/V0bXlJMpfdiDWiA7kOM81LlhIgfsDLomKWfAgMBAAGjUzBR -MB0GA1UdDgQWBBS/tZSVNYEiqNoEVEF3b2vGpK+KtTAfBgNVHSMEGDAWgBS/tZSV -NYEiqNoEVEF3b2vGpK+KtTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA -A4ICAQA0w6P0dCiN2afpVoddkJds0Lg85IffZJjx03mhqWsG2qds7uzsg5qljvWA -8F3JGwy22/N8+43hMUw+qmcqhI2Me1crBvPaa6vh8nvrCiyd7V9OSKqKZ8amObqI -cKTpK8iJl/+K4tzJpdn/RNhYGp6XCIInB7bUu7lyogOdpH+kWVu/SWks1H0Nh59Z -/USiOYa1n7JotN7Fn4MXygDXDAIpyApoiGrrYiCwozlkds6C5lJ6QmlT/PbqwZ2D -0Ruf69vkGe6JSJYHjuOC64Q/FzVmx3uCtG2VJe6Eolmm36vk9GywuUT3SK3/bX7E -EIg3hiQYjEoGJ6XwWGwDGeLp5y7s+OBbHcpodtDwldR/kZUijE3D/AmKCBt16qm7 -XgKFE6RXMAxa8khxtQVYh7BxkGGF+ofi98SjsbugA+O2+Z5Ly4AIxx/Ou/IsRmvs -41v03CvCNZ16dNvLWpk1qlD+3oNIxBuFqiUdlS4OQX68XCEWeVNf53KT1CA8qhU9 -Jv+5bn5N1+n8WdGXROyPwxvix2hYXQniwnO6ToXdQ4L3wc61TgzSClT9IDF9y9bv -qLUlXM23DepDsJPw8ib32b5XPBzE/7KeHx+LBeLADAi8Dfrzu2aGKq83gIpaQouV -Eh3BrqbwKoKJlQ8Op4aSimkyvzQXyY+ySNkXaqKs8a+ZjdzNjQ== ------END CERTIFICATE----- diff --git a/rest/test/server/certs/restSSL.key b/rest/test/server/certs/restSSL.key deleted file mode 100644 index 3059e2a3d..000000000 --- a/rest/test/server/certs/restSSL.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDCAtV89dSuqVW8 -PayXYmLZ/dzHXhJC3aVi49zMPpTDlK1rhEoCrT7ho/4QeQtfLFlnAxeIaH8/BlOw -DMh6OYx4s+eCpm3LmXsKfkny+FB1DTn8GxV6YjvJ3/obFXfWGOhhBfOYmIP7HM31 -QyIzgwnzjYCNLeUAoir4f6yG3vs25+6XeNEvYxangFZ4AF282GfhMYjpLHUpKdoF -DXaAxB0V4tNO5VFyuaa5dZH3+Ex/05RSw4jybDfHJGZILf77WHSHMOJMZtE6DwT+ -DJcavIwV6p6vW77b/sqXFFYuQW7BiZMNnAzs9JdY/2lFykbF7ijRqHTOe4fkLfKW -EqtWHcZeFbc4bnsg7HLDmTRiva4Yp1ymEJFfshc6WP9Y9zpzmZXDmv6ycmKUfekg -cWRQ16K9a0O/RMAS0JQUM7RStnIAYrFQEfzOFKhOWllCcMlrF9w6tICeKGE/tdF/ -HrufkzQFQVFie8ZgKO4n7Y3qFqzKMOOwoRPZiIQKsh9h/geFNqNifRiaTozj3vsi -WqAZAKe9RGAkXk+cb+CdstDmuSyckOX/RJ7yKFBjXnwvGa04j6r5NM7QK+no3c8S -IZZ8uvgTjf52m9Jj1mHO0XX2LIVM1Hhu41zyawHsytQDLzwKanjvJiXjL/1dG15S -TKX3Yg1ogO5DjPNS5YSIH7Ay6JilnwIDAQABAoICAEr2IVrY+UZLM086XTdY0mz8 -A5Qcqt2fGkntVOCtxXkUNzV1tcr2+XbhkEb5HgW18w00SqFwDsphPXCmX8ep+Lai -fG8kswOZ18qkJRp2C1BOvfrE1DWnQwarPc29K8JTeWYTkJ2DQGuEI6gCOnLAzNWH -9QWXmAX4orXFTvoFqfb7AlsQWXL/zD8H/WD8czuGOgzuwMGnZdVz0ENngkQagkp0 -i8TOIfw780lxPecbzyMMsyCPYJiaa6rMS6DT9NNUyCF8J9PxXiIar4khgDjaZR4K -uylyP3ptJgXd27afnZW1/FWj1/KuRtQiS6ClmVbcwHTRq+AkJstpXXPS3tS1SHFg -xas89D2LXjEV7Ly2KR3RE7KiUj00Bw/wLgNSY44iIjHzI2z3uHBpCEsax3xRkzk1 -W2u8BPASBMcPtgosPFtRED/gss+XX5FVMr34zYkeLSkq5bE9ILjHa8mhc0vN78fA -/O0W+Y51YEgRgQ5SOM2QucC25xeAKArvB8IKtY4I6rGZFbqXdqohLmKJTgdRIamO -FRVQjFGTbYiJwxOgqLPZ8/nLXoCOc1gF4rqgSoqIn8uAouvd4cHZbcHfWdubaOyP -dP5jlN0L0UiEvM8ANs51S8HUFsLuwt4/kF58PkIhNJmkSnaSsqgiu14unzYwMgc+ -6KXu0KflETMPgiPK6EKRAoIBAQD2iKqC0wJAaAD2OLYY0qqMTHAhHv6jlNyRWJl7 -GBReL9bAT28JVSibsg4jOWu1ViDgekGp/A5Fdmye/RVHq3wBGW9p9tAa2Z1DtV7g -VzCjiksDOvqs4Ep3BSpl4cRKhJsttL1p+i/V03A1C0CCfVoY73zUZMwh8Ravi17w -JDKopRhCw8PyZ4/oYLKuMAm5ArWQwuL52r9Qtfrz2nQQOnAA/Z4KrUygX6IUIoLl -ketBp+nMEmVEBZPdIYAxXnmBpgkQzrDg+6gScEMfZb57K5yudSAbpXtkB/KaLkeO -qSwN2CGm0KbijSBLIOnmhVW+K5tbT0g3g3VgS6V1GfjacfRVAoIBAQDJdeOQeMKy -eXpkFPFCl34Y8fcSjzJjIB6pe/fp5b+aBb1n2AEzLFslrkO2DLyQE3FeE0LFcUIV -BmQkyhDI/WXGT7RTURB+vUaLNIxSRqftEYspAO5eEH9neWZceodhZdF4w3cxO4YB -eHDkzNRe6mPivi5qHYcrqKhwTYQCjIMoYfJvzHrViAtGhqoSIu+asl45R4fSJsEZ -mE6ZZgu+uBkqOao+72cqCrEkjWOgDBF7w/lOBYv06sjo0qjqs5rrJW/YiwuKzf4E -n2PiDRs7xoXy/yvsVA4iCEMoePIxlLmbqlZ52jYAoc65WzjxloYGto6t4b0Akcld -QdyStzEWYUYjAoIBAEPPL2cwdswUTz9qNdv6BeL1G1pg1hVUWp63ye9rnh6R9fWL -Y7UjcTnx7aWOo6uK9xwHRIxmwd4lRpcscW/3IPKEdnqk4nSgKnt3JZN7J+uznBJV -ZKGsR48ZIqJHSOBePPiDYB4ILKQZtiFA6Qt7Qw7cwG8DEoq7b0v1f7V5n113m4ax -pfHEvnZiMoNqvyHeNuaMVDX5Duo6Q75S9d2I1UnQeGnjZNIvu7riCzLtwdGbR9lT -rfrZteP61PG/VJhufMvcrhYT4hTAQBYgvBXQ1xW9LYmtKJVJAleaJyB8M5vTON5T -QbPKsXk4ol0/i2f1QpQI6IosZFqKNAZTkHk1IskCggEAT5eHxHgxU5myxP+RIaIA -a5KM7oQsgAUcmBEmLP5b6FoELpakQrdvez+R+ManaLSFwYkShDbuyKexwOckIoQa -RXMP5yrLvYbB7BViqs7HYV3hAN4hToBuFU9dJYQzIEO9slxnJshBdStETuCttqIb -vGUuqTXpRVJo2ZWGZgtldfrccVbz4JDTA5YIcwniZ9e4aiDchCZTe+00gF5UnZDW -QFxv6lVjCLUYrzw88+pQrfkK8cw3MxffMDyqB6/VsLklqwOkF76ycNkX+SL8c21H -Vm2ByOicfM2O2tqNtRDxE5MEfze6xh0nMwvbP3cclGJjlEbvCN6QE4wFvOErP5BG -yQKCAQB2Ski6eVDaJDyn1KbMRI5oO86ZsqzTC63vz/E08+SJOuLllWoMIyQgSM3e -j0NtnbLOzDLC5brTarDCHO1omkzuAx4Dy1UuUS0FcW1OgWF8RYSXcO6nbvwx6w9D -9jQE3vQgdc78cg65mgVFlHIVNbigCJ3dS8CDmLrjO9UGtj3WhRZzgybn+/G6JZ4v -GOGReyqz6FQLSVRg5ZvGG4VsJWqt61bXzhU8UlFSXHdwXhbHEbRd3CgX8wuSuKhQ -zzxHIb80U5sRGzB/Vj4cYaKs9qX7ZaSPH7BjzdZWR53f2mV3mkgwS3s/rN9n0JnQ -ZLeHTEemDGIzL0gEuV48U/ObVhoo ------END PRIVATE KEY----- diff --git a/rest/test/server/errors_spec.js b/rest/test/server/errors_spec.js deleted file mode 100644 index 5b8d54135..000000000 --- a/rest/test/server/errors_spec.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const errors = require('../../src/server/errors'); -const { expect } = require('chai'); -const restifyErrors = require('restify-errors'); - -describe('errors', () => { - describe('toRestError', () => { - it('can map basic error without message', () => { - // Act: - const err = errors.toRestError(new Error()); - - // Assert: - expect(err.statusCode).to.equal(500); - expect(err.body).to.deep.equal({ code: 'Internal', message: 'unexpected error' }); - }); - - it('can map basic error with message', () => { - // Act: - const err = errors.toRestError(new Error('badness')); - - // Assert: - expect(err.statusCode).to.equal(500); - expect(err.body).to.deep.equal({ code: 'Internal', message: 'badness' }); - }); - - it('can map rest error', () => { - // Act: - const err = new restifyErrors.NotFoundError('not found'); - - // Assert: - expect(err.statusCode).to.equal(404); - expect(err.body).to.deep.equal({ code: 'NotFound', message: 'not found' }); - }); - }); - - describe('create', () => { - it('can create not found error', () => { - // Act: - const err = errors.createNotFoundError('foo'); - - // Assert: - expect(err.statusCode).to.equal(404); - expect(err.body).to.deep.equal({ code: 'ResourceNotFound', message: 'no resource exists with id \'foo\'' }); - }); - - it('can create invalid argument error', () => { - // Act: - const err = errors.createInvalidArgumentError('badness'); - - // Assert: - expect(err.statusCode).to.equal(409); - expect(err.body).to.deep.equal({ code: 'InvalidArgument', message: 'badness' }); - expect(err.jse_cause).to.equal(undefined); - }); - - it('can create invalid argument error with cause', () => { - // Act: - const err = errors.createInvalidArgumentError('badness', new Error('foo')); - - // Assert: - expect(err.statusCode).to.equal(409); - expect(err.body).to.deep.equal({ code: 'InvalidArgument', message: 'badness' }); - expect(err.jse_cause).to.not.equal(undefined); - expect(err.jse_cause.message).to.equal('foo'); - }); - - it('can create service unavailable error', () => { - // Act: - const err = errors.createServiceUnavailableError('badness'); - - // Assert: - expect(err.statusCode).to.equal(503); - expect(err.body).to.deep.equal({ code: 'ServiceUnavailable', message: 'badness' }); - }); - - it('can create internal error', () => { - // Act: - const err = errors.createInternalError('badness'); - - // Assert: - expect(err.statusCode).to.equal(500); - expect(err.body).to.deep.equal({ code: 'Internal', message: 'badness' }); - }); - }); -}); diff --git a/rest/test/server/formatters_spec.js b/rest/test/server/formatters_spec.js deleted file mode 100644 index 34edd2f29..000000000 --- a/rest/test/server/formatters_spec.js +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const formatters = require('../../src/server/formatters'); -const { expect } = require('chai'); - -describe('formatters', () => { - const createFormatters = name => formatters.create({ - [name]: { - chainStatistic: { - format: chainStatistic => { - const formatUint64 = uint64 => (uint64 ? [uint64[0], uint64[1] * 2] : undefined); - const formatChainStatisticCurrent = chainStatisticCurrent => ({ - height: formatUint64(chainStatisticCurrent.height), - scoreLow: formatUint64(chainStatisticCurrent.scoreLow), - scoreHigh: formatUint64(chainStatisticCurrent.scoreHigh) - }); - - return { - id: chainStatistic.id, - current: formatChainStatisticCurrent(chainStatistic.current) - }; - } - } - } - }); - - const addBasicObjectFormattingTests = assertJsonFormat => { - // region non-error - - it('can format null object', () => { - // Arrange: - const object = null; - - // Assert: - assertJsonFormat(object, 'null', undefined); - }); - - it('can format basic object', () => { - // Arrange: - const object = { foo: 1, bar: 7 }; - - // Assert: - assertJsonFormat(object, '{"foo":1,"bar":7}', undefined); - }); - - it('can format catapult object', () => { - // Arrange: - const object = { - payload: { - current: { - height: [1, 2], - scoreLow: [112233, 8899], - scoreHigh: [4, 3] - } - }, - type: 'chainStatistic' - }; - - // Assert: formatter doubles high part - assertJsonFormat(object, '{"current":{"height":[1,4],"scoreLow":[112233,17798],"scoreHigh":[4,6]}}', undefined); - }); - - it('can format catapult object with page structure', () => { - // Arrange: - const object = { - payload: { - data: [{ - current: { - height: [1, 2], - scoreLow: [112233, 8899], - scoreHigh: [4, 3] - } - }], - pagination: {} - }, - type: 'chainStatistic', - structure: 'page' - }; - - // Assert: formatter doubles high part - assertJsonFormat( - object, '{"data":[{"current":{"height":[1,4],"scoreLow":[112233,17798],"scoreHigh":[4,6]}}],"pagination":{}}', undefined - ); - }); - - it('can format catapult object array', () => { - // Arrange: - const object = { - payload: [ - { current: { height: [1, 2] } }, - { current: { height: [8, 7] } } - ], - type: 'chainStatistic' - }; - - // Assert: formatter doubles high part - assertJsonFormat(object, '[{"current":{"height":[1,4]}},{"current":{"height":[8,14]}}]', undefined); - }); - - // endregion - - // region error - - it('can format empty error object', () => { - // Arrange: - const object = new Error(); - - // Assert: - assertJsonFormat(object, '{"message":""}', 500); - }); - - it('can format error object with message', () => { - // Arrange: - const object = new Error(); - object.message = 'bad message'; - - // Assert: - assertJsonFormat(object, '{"message":"bad message"}', 500); - }); - - it('can format error object with message and status code', () => { - // Arrange: - const object = new Error(); - object.message = 'bad message'; - object.statusCode = 404; - - // Assert: - assertJsonFormat(object, '{"message":"bad message"}', 404); - }); - - it('can format error object with body', () => { - // Arrange: note that body takes precedence - const object = new Error(); - object.body = { foo: 1, bar: 7 }; - object.message = 'bad message'; - - // Assert: - assertJsonFormat(object, '{"foo":1,"bar":7}', 500); - }); - - it('can format error object with body and status code', () => { - // Arrange: note that body takes precedence - const object = new Error(); - object.body = { foo: 1, bar: 7 }; - object.message = 'bad message'; - object.statusCode = 404; - - // Assert: - assertJsonFormat(object, '{"foo":1,"bar":7}', 404); - }); - - // endregion - }; - - describe('json', () => { - addBasicObjectFormattingTests((object, expectedJson, expectedStatusCode) => { - // Arrange: - const req = {}; - - const resHeaders = []; - const res = { - setHeader: (key, value) => { - resHeaders.push({ key, value }); - } - }; - - // Act: - const result = createFormatters('json').json(req, res, object); - - // Assert: - expect(res.statusCode).to.equal(expectedStatusCode); - - expect(resHeaders.length).to.equal(1); - expect(resHeaders[0]).to.deep.equal({ - key: 'Content-Length', - value: expectedJson.length - }); - - expect(result).to.equal(expectedJson); - }); - - describe('override formatter per-object', () => { - addBasicObjectFormattingTests((object, expectedJson, expectedStatusCode) => { - // Arrange: - const req = {}; - - const resHeaders = []; - const res = { - setHeader: (key, value) => { - resHeaders.push({ key, value }); - } - }; - - if (object) - object.formatter = 'anotherFormatter'; - - // Act: - const result = createFormatters('anotherFormatter').json(req, res, object); - - // Assert: - expect(res.statusCode).to.equal(expectedStatusCode); - - expect(resHeaders.length).to.equal(1); - expect(resHeaders[0]).to.deep.equal({ - key: 'Content-Length', - value: expectedJson.length - }); - - expect(result).to.equal(expectedJson); - }); - }); - }); - - describe('ws', () => { - // note that formatters.ws ignores the status code - addBasicObjectFormattingTests((object, expectedJson) => { - // Act: - const result = createFormatters('ws').ws(object); - - // Assert: - expect(result).to.equal(expectedJson); - }); - - it('can bypass formatting of raw object', () => { - // Arrange: - const object = { - payload: { - foo: 123, - bar: 987 - }, - type: 'raw' - }; - - // Act: - const result = createFormatters('ws').ws(object); - - // Assert: - expect(result).to.equal(object.payload); - }); - }); -}); diff --git a/rest/test/server/messageFormattingRules_spec.js b/rest/test/server/messageFormattingRules_spec.js deleted file mode 100644 index cba093079..000000000 --- a/rest/test/server/messageFormattingRules_spec.js +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const formattingRules = require('../../src/server/messageFormattingRules'); -const test = require('../testUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const { ModelType } = catapult.model; - -describe('message formatting rules', () => { - it('can format none type', () => { - // Arrange: - const object = { foo: 8 }; - - // Act: - const result = formattingRules[ModelType.none](object); - - // Assert: - expect(result).to.deep.equal({ foo: 8 }); - }); - - it('can format binary type', () => { - // Arrange: - const object = Buffer.from('FEDCBA9876543210', 'hex'); - - // Act: - const result = formattingRules[ModelType.binary](object); - - // Assert: - expect(result).to.equal('FEDCBA9876543210'); - }); - - it('cannot format object id type', () => { - // Assert: objectId should never be written into messages, so it should be dropped - expect(formattingRules).to.not.contain.key(ModelType.objectId); - }); - - it('can format status code type', () => { - // Arrange: - const code = 0x80530001; - - // Act: - const result = formattingRules[ModelType.statusCode](code); - - // Assert: - expect(result).to.equal('Failure_Signature_Not_Verifiable'); - }); - - it('can format string type', () => { - // Arrange: - const object = test.factory.createBinary(Buffer.from('6361746170756C74', 'hex')); - - // Act: - const result = formattingRules[ModelType.string](object); - - // Assert: - expect(result).to.equal('catapult'); - }); - - it('can format uint8 type', () => { - // Arrange: - const object = 12345678; - - // Act: - const result = formattingRules[ModelType.uint8](object); - - // Assert: - expect(result).to.deep.equal(12345678); - }); - - it('can format uint16 type', () => { - // Arrange: - const object = 56; - - // Act: - const result = formattingRules[ModelType.uint16](object); - - // Assert: - expect(result).to.deep.equal(56); - }); - - it('can format uint32 type', () => { - // Arrange: - const object = 12345678; - - // Act: - const result = formattingRules[ModelType.uint32](object); - - // Assert: - expect(result).to.deep.equal(12345678); - }); - - it('can format uint64 type', () => { - // Arrange: - const object = [1, 2]; - - // Act: - const result = formattingRules[ModelType.uint64](object); - - // Assert: - expect(result).to.equal('8589934593'); - }); - - it('can format int type', () => { - // Arrange: - const object = 12345678; - - // Act: - const result = formattingRules[ModelType.int](object); - - // Assert: - expect(result).to.deep.equal(12345678); - }); - - it('can format uint64HexIdentifier type', () => { - // Arrange: - const object = [1, 2]; - - // Act: - const result = formattingRules[ModelType.uint64HexIdentifier](object); - - // Assert: - expect(result).to.equal('0000000200000001'); - }); - - it('can format boolean type', () => { - // Arrange: - const object = true; - - // Act: - const result = formattingRules[ModelType.boolean](object); - - // Assert: - expect(result).to.deep.equal(true); - }); - - it('can format decodedAddress type', () => { - // Arrange: - const object = test.factory.createBinary(Buffer.from('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56', 'hex')); - - // Act: - const result = formattingRules[ModelType.encodedAddress](object); - - // Assert: - expect(result).to.deep.equal('98E0D138EAF2AC342C015FF0B631EC3622E8AFFA04BFCC56'); - }); -}); diff --git a/rest/test/server/websocketMessageHandler_spec.js b/rest/test/server/websocketMessageHandler_spec.js deleted file mode 100644 index 1c7bdbf52..000000000 --- a/rest/test/server/websocketMessageHandler_spec.js +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const websocketMessageHandler = require('../../src/server/websocketMessageHandler'); -const { expect } = require('chai'); - -describe('websocketMessageHandler', () => { - // region invalid - - const runInvalidMessageTest = traits => { - // Arrange: - const client = { uid: 'client1' }; - const messageJson = 'string' === typeof traits.message ? traits.message : JSON.stringify(traits.message); - const subscriptionManager = {}; - - // Act: - const result = websocketMessageHandler.handleMessage(client, messageJson, subscriptionManager); - - // Assert: - if (traits.hasCause) { - expect(result.length).to.equal(2); - expect(result[1]).to.not.equal(undefined); - } else { - expect(result.length).to.equal(1); - } - - expect(result[0]).to.contain(traits.error); - }; - - it('rejects invalid json message', () => runInvalidMessageTest({ - message: 'hello', // non-json data - error: 'parse error for data', - hasCause: true - })); - - it('rejects message without uid', () => runInvalidMessageTest({ - message: { subscribe: 'block' }, - error: 'client data does not have proper uid' - })); - - it('rejects message with neither subscribe nor unsubscribe', () => runInvalidMessageTest({ - message: { uid: 'client1' }, - error: 'client subscription request (subscribe) must be string' - })); - - it('rejects message with both subscribe and unsubscribe', () => runInvalidMessageTest({ - message: { uid: 'client1', subscribe: 'block', unsubscribe: 'block' }, - error: 'client data cannot specify both subscribe and unsubscribe' - })); - - it('rejects message with malformed subscribe', () => runInvalidMessageTest({ - message: { uid: 'client1', subscribe: 7 }, - error: 'client subscription request (subscribe) must be string' - })); - - it('rejects message with malformed unsubscribe', () => runInvalidMessageTest({ - message: { uid: 'client1', unsubscribe: 7 }, - error: 'client subscription request (unsubscribe) must be string' - })); - - it('rejects message when subscription manager fails', () => runInvalidMessageTest({ - // subscriptionManager in runInvalidMessageTest does not support 'subscribe' - message: { uid: 'client1', subscribe: 'block' }, - error: 'subscribe error for data', - hasCause: true - })); - - // endregion - - // region valid - - const createCapturingSubscriptionManager = () => { - const captures = { - adds: [], - deletes: [] - }; - - return { - captures, - add: (channel, client) => { - captures.adds.push({ channel, client }); - }, - delete: (channel, client) => { - captures.deletes.push({ channel, client }); - } - }; - }; - - it('can subscribe client to channel', () => { - // Arrange: - const client = { uid: 'client1' }; - const messageJson = JSON.stringify({ uid: 'client1', subscribe: 'block' }); - const subscriptionManager = createCapturingSubscriptionManager(); - - // Act: - const result = websocketMessageHandler.handleMessage(client, messageJson, subscriptionManager); - - // Assert: - expect(result).to.equal(undefined); - expect(subscriptionManager.captures.adds).to.deep.equal([{ channel: 'block', client }]); - expect(subscriptionManager.captures.deletes).to.deep.equal([]); - }); - - it('can unsubscribe client from channel', () => { - // Arrange: - const client = { uid: 'client1' }; - const messageJson = JSON.stringify({ uid: 'client1', unsubscribe: 'block' }); - const subscriptionManager = createCapturingSubscriptionManager(); - - // Act: - const result = websocketMessageHandler.handleMessage(client, messageJson, subscriptionManager); - - // Assert: - expect(result).to.equal(undefined); - expect(subscriptionManager.captures.adds).to.deep.equal([]); - expect(subscriptionManager.captures.deletes).to.deep.equal([{ channel: 'block', client }]); - }); - - // endregion -}); diff --git a/rest/test/server/websocketUtils_spec.js b/rest/test/server/websocketUtils_spec.js deleted file mode 100644 index 6fad7c9bf..000000000 --- a/rest/test/server/websocketUtils_spec.js +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const websocketUtils = require('../../src/server/websocketUtils'); -const { expect } = require('chai'); - -describe('websocketUtils', () => { - const createMockSender = (options = {}) => { - const sender = { - payloads: [], - numCloseCalls: 0, - eventHandlers: {} - }; - - sender.send = (data, cb) => { - sender.payloads.push(data); - cb(options.raiseSendError ? new Error('send error') : undefined); - }; - - sender.close = () => { ++sender.numCloseCalls; }; - sender.on = (eventName, eventHandler) => { sender.eventHandlers[eventName] = eventHandler; }; - return sender; - }; - - describe('createMultisender', () => { - describe('send', () => { - it('does nothing when there are no subscribers', () => { - // Arrange: - const multisender = websocketUtils.createMultisender('topicName', [], value => ({ str: value.toString(), value })); - - // Act + Assert: no exceptions - multisender.send(123); - }); - - it('forwards formatted data to single subscriber', () => { - // Arrange: - const sender = createMockSender(); - const multisender = websocketUtils.createMultisender('topicName', [sender], value => ({ str: value.toString(), value })); - - // Act: - multisender.send(123); - - // Assert: - expect(sender.payloads).to.deep.equal([{ str: '123', value: 123 }]); - expect(sender.numCloseCalls).to.equal(0); - }); - - it('forwards formatted data to multiple subscribers', () => { - // Arrange: - const senders = [createMockSender(), createMockSender(), createMockSender()]; - const multisender = websocketUtils.createMultisender('topicName', senders, value => ({ str: value.toString(), value })); - - // Act: - multisender.send(123); - - // Assert: - senders.forEach((sender, index) => { - const message = `sender ${index}`; - expect(sender.payloads, message).to.deep.equal([{ str: '123', value: 123 }]); - expect(sender.numCloseCalls).to.equal(0); - }); - }); - - it('closes subscriber on send error', () => { - // Arrange: - const senders = [createMockSender(), createMockSender({ raiseSendError: true }), createMockSender()]; - const multisender = websocketUtils.createMultisender('topicName', senders, value => ({ str: value.toString(), value })); - - // Act: - multisender.send(123); - - // Assert: only the second sender should have been closed - senders.forEach((sender, index) => { - const message = `sender ${index}`; - expect(sender.payloads, message).to.deep.equal([{ str: '123', value: 123 }]); - expect(sender.numCloseCalls, message).to.equal(1 === index ? 1 : 0); - }); - }); - }); - - describe('close', () => { - it('does nothing when there are no subscribers', () => { - // Arrange: - const multisender = websocketUtils.createMultisender('topicName', []); - - // Act + Assert: no exceptions - multisender.close(); - }); - - it('closes all subscribers when there is single subscriber', () => { - // Arrange: - const sender = createMockSender(); - const multisender = websocketUtils.createMultisender('topicName', [sender]); - - // Act: - multisender.close(); - - // Assert: - expect(sender.numCloseCalls).to.equal(1); - }); - - it('closes all subscribers when there are multiple subscribers', () => { - // Arrange: - const senders = [createMockSender(), createMockSender(), createMockSender()]; - const multisender = websocketUtils.createMultisender('topicName', senders); - - // Act: - multisender.close(); - - // Assert: - senders.forEach((sender, index) => { - expect(sender.numCloseCalls, `sender ${index}`).to.equal(1); - }); - }); - }); - }); - - describe('handshake', () => { - it('assigns client unique id', () => { - // Arrange: - const client1 = createMockSender(); - const client2 = createMockSender(); - - // Act: - websocketUtils.handshake(client1); - websocketUtils.handshake(client2); - - // Assert: - expect(client1.uid.length).to.equal(32); - expect(client2.uid.length).to.equal(32); - expect(client1.uid).to.not.deep.equal(client2.uid); - }); - - it('sends unique id to client', () => { - // Arrange: - const client = createMockSender(); - - // Act: - websocketUtils.handshake(client); - - // Assert: - expect(client.payloads).to.deep.equal([`{"uid": "${client.uid}"}`]); - expect(client.numCloseCalls).to.equal(0); - }); - - it('closes client on send error', () => { - // Arrange: - const client = createMockSender({ raiseSendError: true }); - - // Act: - websocketUtils.handshake(client); - - // Assert: - expect(client.payloads).to.deep.equal([`{"uid": "${client.uid}"}`]); - expect(client.numCloseCalls).to.equal(1); - }); - - it('closes client on arbitrary error', () => { - // Arrange: - const client = createMockSender(); - - // Act: - websocketUtils.handshake(client); - client.eventHandlers.error(new Error()); - - // Assert: - expect(client.numCloseCalls).to.equal(1); - }); - - it('forwards message to message handler', () => { - // Arrange: - const client = createMockSender(); - const messages = []; - - // Act: - websocketUtils.handshake(client, message => { - messages.push(message); - return undefined; - }); - client.eventHandlers.message('hello world'); - - // Assert: - expect(messages).to.deep.equal(['hello world']); - expect(client.numCloseCalls).to.equal(0); - }); - - it('closes client on message handler error', () => { - // Arrange: - const client = createMockSender(); - const messages = []; - - // Act: - websocketUtils.handshake(client, message => { - messages.push(message); - return ['message handler error', new Error('cause')]; - }); - client.eventHandlers.message('hello world'); - - // Assert: - expect(messages).to.deep.equal(['hello world']); - expect(client.numCloseCalls).to.equal(1); - }); - }); -}); diff --git a/rest/test/sockets/finalizationProofCodec_spec.js b/rest/test/sockets/finalizationProofCodec_spec.js deleted file mode 100644 index 28f3c7097..000000000 --- a/rest/test/sockets/finalizationProofCodec_spec.js +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const finalizationProofCodec = require('../../src/sockets/finalizationProofCodec'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const { BinaryParser } = catapult.parser; - -describe('deserialize', () => { - const size = Buffer.from([0x38, 0x00, 0x00, 0x00]); // 4b - const version = Buffer.from([0x64, 0x00, 0x00, 0x00]); // 4b - const finalizationEpoch = Buffer.from([0x02, 0x00, 0x00, 0x00]); // 4b - const finalizationPoint = Buffer.from([0x01, 0x00, 0x00, 0x00]); // 4b - const height = Buffer.from([0xCD, 0x49, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00]); // 8b - const hash = Buffer.from([ // 32b - 0xC3, 0xC4, 0xDE, 0xA0, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0xBB, 0x00, 0xFF, 0x11, 0xFF, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0xF8, 0xF3 - ]); - const testPublicKey = Buffer.from([ // 32b - 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, - 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF - ]); - const testInnerSignature = Buffer.from([ // 64b - 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, - 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, - 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, - 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF - ]); - - const createSignature = () => { - const rootParentPublicKey = testPublicKey; - const rootSignature = testInnerSignature; - const bottomParentPublicKey = testPublicKey; - const bottomSignature = testInnerSignature; - - const signature = [ - rootParentPublicKey, rootSignature, - bottomParentPublicKey, bottomSignature - ]; - - return Buffer.concat(signature); - }; - - const createMessageGroup = (hashCount, signatureCount) => { - const messageGroupSize = Buffer.from([0x00, 0x00, 0x00, 0x00]); // 4b - const messageGrouphashCount = Buffer.from([0x00, 0x00, 0x00, 0x00]); // 4b - const messageGroupsignatureCount = Buffer.from([0x00, 0x00, 0x00, 0x00]); // 4b - const messageGroupStage = Buffer.from([0x01, 0x00, 0x00, 0x00]); // 4b - const messageGroupHeight = Buffer.from([0xCD, 0x49, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00]); // 8b - - const messageGroup = [ - messageGroupSize, messageGrouphashCount, messageGroupsignatureCount, - messageGroupStage, messageGroupHeight - ]; - - for (let i = 0; i < hashCount; ++i) - messageGroup.push(hash); - - for (let i = 0; i < signatureCount; ++i) - messageGroup.push(createSignature()); - - const messageGroupBuffer = Buffer.concat(messageGroup); - messageGroupBuffer.writeInt32LE(messageGroupBuffer.length, 0); - messageGroupBuffer.writeInt32LE(hashCount, 4); - messageGroupBuffer.writeInt16LE(signatureCount, 8); - - return messageGroupBuffer; - }; - - const runFinalizationProofTests = (testDescription, messageGroupsCount, hashCount, signatureCount) => - it(testDescription, () => { - // Arrange: - const expectedHashes = []; - for (let i = 0; i < hashCount; ++i) - expectedHashes.push(hash); - - const expectedSignatures = []; - for (let i = 0; i < signatureCount; ++i) { - expectedSignatures.push({ - root: { - parentPublicKey: testPublicKey, - signature: testInnerSignature - }, - bottom: { - parentPublicKey: testPublicKey, - signature: testInnerSignature - } - }); - } - - const finalizationProof = [ - size, version, finalizationEpoch, finalizationPoint, height, hash - ]; - - const expectedMessageGroups = []; - for (let i = 0; i < messageGroupsCount; ++i) { - finalizationProof.push(createMessageGroup(hashCount, signatureCount)); - expectedMessageGroups.push({ - stage: 1, - height: [215501, 0], - hashes: expectedHashes, - signatures: expectedSignatures - }); - } - - const finalizationProofBuffer = Buffer.concat(finalizationProof); - finalizationProofBuffer.writeInt32LE(finalizationProofBuffer.length, 0); - - const binaryParser = new BinaryParser(); - binaryParser.push(Buffer.from(finalizationProofBuffer)); - - // Assert: - expect(finalizationProofCodec.deserialize(binaryParser)).to.deep.equal({ - version: 100, - finalizationEpoch: 2, - finalizationPoint: 1, - height: [215501, 0], - hash, - messageGroups: expectedMessageGroups - }); - }); - - it('returns undefined if object is 0 bytes length', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const packet = []; - binaryParser.push(Buffer.from(packet)); - - // Assert: - expect(finalizationProofCodec.deserialize(binaryParser)).to.equal(undefined); - }); - - runFinalizationProofTests('returns a deserialized finalization proof object with no message groups', 0, 0, 0); - - describe('returns a deserialized finalization proof object with message groups', () => { - runFinalizationProofTests('with one message group', 1, 0, 0); - runFinalizationProofTests('with multiple message group', 3, 0, 0); - - describe('message group with hashes', () => { - runFinalizationProofTests('with one hash', 1, 1, 0); - runFinalizationProofTests('with multiple hash', 1, 3, 0); - }); - - describe('message group with signatures', () => { - runFinalizationProofTests('with one signature', 1, 0, 1); - runFinalizationProofTests('with multiple signatures', 1, 0, 3); - }); - - describe('message group with hashes and signatures', () => { - runFinalizationProofTests('with one of each', 1, 1, 1); - runFinalizationProofTests('with multiple of each', 1, 3, 3); - }); - }); -}); diff --git a/rest/test/sockets/nodeInfoCodec_spec.js b/rest/test/sockets/nodeInfoCodec_spec.js deleted file mode 100644 index 15224ba0c..000000000 --- a/rest/test/sockets/nodeInfoCodec_spec.js +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const nodeInfoCodec = require('../../src/sockets/nodeInfoCodec'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const { BinaryParser } = catapult.parser; - -describe('deserialize', () => { - it('returns a deserialized object without friendlyName or host', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packetBuffer = Buffer.concat([ - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]) // friendly name size - ]); - binaryParser.push(packetBuffer); - - // Act: - const deserializedData = nodeInfoCodec.deserialize(binaryParser); - - // Assert: - expect(deserializedData).to.deep.equal({ - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: Buffer.from([]), - host: Buffer.from([]) - }); - }); - - it('returns a deserialized object with friendlyName', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const friendlyNameBuffer = Buffer.from([0x10]); - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packetBuffer = Buffer.concat([ - Buffer.from([0x31 + friendlyNameBuffer.length, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([friendlyNameBuffer.length]), // friendly name size - // host - friendlyNameBuffer - ]); - binaryParser.push(Buffer.from(packetBuffer)); - - // Act: - const deserializedData = nodeInfoCodec.deserialize(binaryParser); - - // Assert: - expect(deserializedData).to.deep.equal({ - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: friendlyNameBuffer, - host: Buffer.from([]) - }); - }); - - it('returns a deserialized object with host', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const hostBuffer = Buffer.from([0xCC]); - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packetBuffer = Buffer.concat([ - Buffer.from([0x31 + hostBuffer.length, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([hostBuffer.length]), // host size - Buffer.from([0x00]), // friendly name size - hostBuffer - ]); - binaryParser.push(Buffer.from(packetBuffer)); - - // Act: - const deserializedData = nodeInfoCodec.deserialize(binaryParser); - - // Assert: - expect(deserializedData).to.deep.equal({ - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: Buffer.from([]), - host: hostBuffer - }); - }); - - it('returns a deserialized object with friendlyName and host', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const friendlyNameBuffer = Buffer.from([0x10, 0x17]); - const hostBuffer = Buffer.from([0xCC, 0x00, 0x03]); - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packetBuffer = Buffer.concat([ - Buffer.from([0x31 + friendlyNameBuffer.length + hostBuffer.length, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([hostBuffer.length]), // host size - Buffer.from([friendlyNameBuffer.length]), // friendly name size - hostBuffer, - friendlyNameBuffer - ]); - binaryParser.push(Buffer.from(packetBuffer)); - - // Act: - const deserializedData = nodeInfoCodec.deserialize(binaryParser); - - // Assert: - expect(deserializedData).to.deep.equal({ - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: friendlyNameBuffer, - host: hostBuffer - }); - }); -}); diff --git a/rest/test/sockets/nodePeersCodec_spec.js b/rest/test/sockets/nodePeersCodec_spec.js deleted file mode 100644 index b3e72dd6a..000000000 --- a/rest/test/sockets/nodePeersCodec_spec.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const nodePeersCodec = require('../../src/sockets/nodePeersCodec'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const { BinaryParser } = catapult.parser; - -describe('deserialize', () => { - it('returns multiple deserialized objects without friendlyName or host', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashSeedBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packetBuffer01 = Buffer.concat([ - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]) // friendly name size - ]); - const packetBuffer02 = Buffer.concat([ - Buffer.from([0x31, 0x00, 0x00, 0x00]), // size - Buffer.from([0x18, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x03, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([0x00]), // host size - Buffer.from([0x00]) // friendly name size - ]); - binaryParser.push(packetBuffer01); - binaryParser.push(packetBuffer02); - - // Act: - const deserializedData = nodePeersCodec.deserialize(binaryParser); - - // Assert: - expect(deserializedData).to.deep.equal([{ - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: Buffer.from([]), - host: Buffer.from([]) - }, - { - version: 24, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - roles: 3, - port: 7900, - networkIdentifier: 144, - friendlyName: Buffer.from([]), - host: Buffer.from([]) - }]); - }); - - it('returns multiple deserialzed objects with friendlyName and host', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const friendlyNameBufferPeerA = Buffer.from([0x10, 0x17]); - const friendlyNameBufferPeerB = Buffer.from([0x20, 0x27]); - const hostBuffer = Buffer.from([0xCC, 0x00, 0x03]); - const publicKeyBuffer = Buffer.from([ - 0xE3, 0x27, 0xC0, 0xF1, 0xC9, 0x97, 0x5C, 0x3A, 0xA5, 0x1B, 0x2A, 0x41, 0x76, 0x81, 0x58, 0xC1, - 0x07, 0x7D, 0x16, 0xB4, 0x60, 0x99, 0x9A, 0xAB, 0xE7, 0xAD, 0xB5, 0x26, 0x2B, 0xE2, 0x9A, 0x68 - ]); - const networkGenerationHashSeedBuffer = Buffer.from([ - 0xA3, 0x00, 0xEA, 0xFE, 0xDA, 0xBD, 0x5C, 0xFA, 0x0D, 0x4B, 0x94, 0x1D, 0x15, 0xBB, 0x51, 0xB1, - 0xB4, 0x64, 0x72, 0x42, 0xF1, 0xFF, 0x11, 0x00, 0x9F, 0xD0, 0x9A, 0x8F, 0x3D, 0x35, 0x87, 0xF8 - ]); - const packetBufferPeerA = Buffer.concat([ - Buffer.from([0x31 + friendlyNameBufferPeerA.length + hostBuffer.length, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([hostBuffer.length]), // host size - Buffer.from([friendlyNameBufferPeerA.length]), // friendly name size - hostBuffer, - friendlyNameBufferPeerA - ]); - const packetBufferPeerB = Buffer.concat([ - Buffer.from([0x31 + friendlyNameBufferPeerB.length + hostBuffer.length, 0x00, 0x00, 0x00]), // size - Buffer.from([0x17, 0x00, 0x00, 0x00]), // version - publicKeyBuffer, - networkGenerationHashSeedBuffer, - Buffer.from([0x02, 0x00, 0x00, 0x00]), // roles - Buffer.from([0xDC, 0x1E]), // port - Buffer.from([0x90]), // network identifier - Buffer.from([hostBuffer.length]), // host size - Buffer.from([friendlyNameBufferPeerB.length]), // friendly name size - hostBuffer, - friendlyNameBufferPeerB - ]); - binaryParser.push(Buffer.from(packetBufferPeerA)); - binaryParser.push(Buffer.from(packetBufferPeerB)); - - // Act: - const deserializedData = nodePeersCodec.deserialize(binaryParser); - - // Assert: - expect(deserializedData).to.deep.equal([{ - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: friendlyNameBufferPeerA, - host: hostBuffer - }, - { - version: 23, - publicKey: publicKeyBuffer, - networkGenerationHashSeed: networkGenerationHashSeedBuffer, - roles: 2, - port: 7900, - networkIdentifier: 144, - friendlyName: friendlyNameBufferPeerB, - host: hostBuffer - }]); - }); -}); diff --git a/rest/test/sockets/nodeTimeCodec_spec.js b/rest/test/sockets/nodeTimeCodec_spec.js deleted file mode 100644 index 6f479b44c..000000000 --- a/rest/test/sockets/nodeTimeCodec_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const nodeTimeCodec = require('../../src/sockets/nodeTimeCodec'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const { BinaryParser } = catapult.parser; - -describe('deserialize', () => { - it('returns a deserialized node time object', () => { - // Arrange: - const binaryParser = new BinaryParser(); - const packet = [0x90, 0xFA, 0x6D, 0x06, 0x01, 0x00, 0x00, 0x00, 0x90, 0xF8, 0x6D, 0x06, 0x10, 0x00, 0x00, 0x00]; - binaryParser.push(Buffer.from(packet)); - - // Assert: - expect(nodeTimeCodec.deserialize(binaryParser)).to.deep.equal({ - communicationTimestamps: { - receiveTimestamp: [107870352, 16], - sendTimestamp: [107870864, 1] - } - }); - }); -}); diff --git a/rest/test/sockets/stateTreeCodec_spec.js b/rest/test/sockets/stateTreeCodec_spec.js deleted file mode 100644 index a54a96045..000000000 --- a/rest/test/sockets/stateTreeCodec_spec.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const stateTreesCodec = require('../../src/sockets/stateTreesCodec'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const { BinaryParser } = catapult.parser; -const { convert } = catapult.utils; - -describe('deserialize', () => { - it('returns a deserialized state tree object', () => { - // Arrange: - const tree = [ - '9922093F19F7160BDCBCA8AA48499DA8DF532D4102745670B85AA4BDF63B8D59', - 'E8FCFD95CA220D442BE748F5494001A682DC8015A152EBC433222136E99A96B8', - 'C1C1062C63CAB4197C87B366052ECE3F4FEAE575D81A7F728F4E3704613AF876', - 'F8E8FCDAD1B94D2C76D769B113FF5CAC5D5170772F2D80E466EB04FCA23D6887', - '2D3418274BBC250616223C162534B460216AED82C4FA9A87B53083B7BA7A9391', - 'AEAF30ED55BBE4805C53E5232D88242F0CF719F99A8E6D339BCBF5D5DE85E1FB', - 'AFE6C917BABA60ADC1512040CC35033B563DAFD1718FA486AB1F3D9B84866B27' - ].map((treeNode => Buffer.from(convert.hexToUint8(treeNode)))); - - const binaryParser = new BinaryParser(); - binaryParser.push(Buffer.concat(tree)); - - // Assert: - expect(stateTreesCodec.deserialize(binaryParser)).to.deep.equal({ tree }); - }); -}); diff --git a/rest/test/testUtils.js b/rest/test/testUtils.js deleted file mode 100644 index a23f87b08..000000000 --- a/rest/test/testUtils.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); -const MongoDb = require('mongodb'); -const winston = require('winston'); -const crypto = require('crypto'); - -const { sizes } = catapult.constants; -const random = { - bytes: size => crypto.randomBytes(size), - publicKey: () => crypto.randomBytes(sizes.signerPublicKey), - hash: () => crypto.randomBytes(sizes.hash256), - secret: () => crypto.randomBytes(sizes.hash256), - signature: () => crypto.randomBytes(sizes.signature), - address: () => crypto.randomBytes(sizes.addressDecoded), - account: () => ({ - publicKey: random.publicKey(), - address: random.address() - }) -}; - -module.exports = { - constants: { sizes }, - random, - factory: { - createBinary: buffer => new MongoDb.Binary(buffer), - createObjectIdFromHexString: id => new MongoDb.ObjectID(id) - }, - log: (...args) => { - winston.debug(...args); - }, - createLogger: () => winston, - createMockLogger: () => { - const logger = {}; - logger.numLogs = 0; - ['debug', 'info', 'warn', 'error'].forEach(level => { - logger[level] = () => { ++logger.numLogs; }; - }); - return logger; - } -}; diff --git a/rest/yarn.lock b/rest/yarn.lock deleted file mode 100644 index 0ff9dae24..000000000 --- a/rest/yarn.lock +++ /dev/null @@ -1,7440 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/generator@^7.15.4", "@babel/generator@^7.4.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.4.tgz#85acb159a267ca6324f9793986991ee2022a05b0" - integrity sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw== - dependencies: - "@babel/types" "^7.15.4" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-function-name@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" - integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== - dependencies: - "@babel/helper-get-function-arity" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/helper-get-function-arity@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" - integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-hoist-variables@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" - integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-split-export-declaration@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" - integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.15.4", "@babel/parser@^7.4.3": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae" - integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g== - -"@babel/runtime-corejs3@^7.10.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz#403139af262b9a6e8f9ba04a6fdcebf8de692bf1" - integrity sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg== - dependencies: - core-js-pure "^3.16.0" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.15.4", "@babel/template@^7.4.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" - integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/traverse@^7.4.3": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" - integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.15.4", "@babel/types@^7.4.0": - version "7.15.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" - integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== - dependencies: - "@babel/helper-validator-identifier" "^7.14.9" - to-fast-properties "^2.0.0" - -"@dabh/diagnostics@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" - integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== - dependencies: - colorspace "1.1.x" - enabled "2.0.x" - kuler "^2.0.0" - -"@iarna/cli@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641" - integrity sha512-ukITQAqVs2n9HGmn3car/Ir7d3ta650iXhrG7pjr3EWdFmJuuOVWgYsu7ftsSe5VifEFFhjxVuX9+8F7L8hwcA== - dependencies: - signal-exit "^3.0.2" - update-notifier "^2.2.0" - yargs "^8.0.2" - -"@js-joda/core@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" - integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== - -"@netflix/nerror@^1.0.0": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@netflix/nerror/-/nerror-1.1.3.tgz#9d88eccca442f1d544f2761d15ea557dc0a44ed2" - integrity sha512-b+MGNyP9/LXkapreJzNUzcvuzZslj/RGgdVVJ16P2wSlYatfLycPObImqVJSmNAdyeShvNeM/pl3sVZsObFueg== - dependencies: - assert-plus "^1.0.0" - extsprintf "^1.4.0" - lodash "^4.17.15" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@oclif/command@^1.5.13", "@oclif/command@^1.5.20", "@oclif/command@^1.6.0", "@oclif/command@^1.7.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.8.0.tgz#c1a499b10d26e9d1a611190a81005589accbb339" - integrity sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw== - dependencies: - "@oclif/config" "^1.15.1" - "@oclif/errors" "^1.3.3" - "@oclif/parser" "^3.8.3" - "@oclif/plugin-help" "^3" - debug "^4.1.1" - semver "^7.3.2" - -"@oclif/config@^1.13.0", "@oclif/config@^1.15.1", "@oclif/config@^1.16.0": - version "1.17.0" - resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.17.0.tgz#ba8639118633102a7e481760c50054623d09fcab" - integrity sha512-Lmfuf6ubjQ4ifC/9bz1fSCHc6F6E653oyaRXxg+lgT4+bYf9bk+nqrUpAbrXyABkCqgIBiFr3J4zR/kiFdE1PA== - dependencies: - "@oclif/errors" "^1.3.3" - "@oclif/parser" "^3.8.0" - debug "^4.1.1" - globby "^11.0.1" - is-wsl "^2.1.1" - tslib "^2.0.0" - -"@oclif/errors@^1.2.1", "@oclif/errors@^1.2.2", "@oclif/errors@^1.3.3": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@oclif/errors/-/errors-1.3.5.tgz#a1e9694dbeccab10fe2fe15acb7113991bed636c" - integrity sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ== - dependencies: - clean-stack "^3.0.0" - fs-extra "^8.1" - indent-string "^4.0.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -"@oclif/linewrap@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" - integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw== - -"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.3": - version "3.8.5" - resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.5.tgz#c5161766a1efca7343e1f25d769efbefe09f639b" - integrity sha512-yojzeEfmSxjjkAvMRj0KzspXlMjCfBzNRPkWw8ZwOSoNWoJn+OCS/m/S+yfV6BvAM4u2lTzX9Y5rCbrFIgkJLg== - dependencies: - "@oclif/errors" "^1.2.2" - "@oclif/linewrap" "^1.0.0" - chalk "^2.4.2" - tslib "^1.9.3" - -"@oclif/plugin-autocomplete@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@oclif/plugin-autocomplete/-/plugin-autocomplete-0.3.0.tgz#eec788596a88a4ca5170a9103b6c2835119a8fbd" - integrity sha512-gCuIUCswvoU1BxDDvHSUGxW8rFagiacle8jHqE49+WnuniXD/N8NmJvnzmlNyc8qLE192CnKK+qYyAF+vaFQBg== - dependencies: - "@oclif/command" "^1.5.13" - "@oclif/config" "^1.13.0" - chalk "^4.1.0" - cli-ux "^5.2.1" - debug "^4.0.0" - fs-extra "^9.0.1" - moment "^2.22.1" - -"@oclif/plugin-help@^3", "@oclif/plugin-help@^3.1.0": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-3.2.3.tgz#cd24010e7eb326782843d3aa6d6b5a4affebb2c3" - integrity sha512-l2Pd0lbOMq4u/7xsl9hqISFqyR9gWEz/8+05xmrXFr67jXyS6EUCQB+mFBa0wepltrmJu0sAFg9AvA2mLaMMqQ== - dependencies: - "@oclif/command" "^1.5.20" - "@oclif/config" "^1.15.1" - "@oclif/errors" "^1.2.2" - chalk "^4.1.0" - indent-string "^4.0.0" - lodash.template "^4.4.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - widest-line "^3.1.0" - wrap-ansi "^4.0.0" - -"@oclif/screen@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@oclif/screen/-/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493" - integrity sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw== - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/formatio@^3.2.1": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c" - integrity sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ== - dependencies: - "@sinonjs/commons" "^1" - "@sinonjs/samsam" "^3.1.0" - -"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.3": - version "3.3.3" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.3.tgz#46682efd9967b259b81136b9f120fd54585feb4a" - integrity sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ== - dependencies: - "@sinonjs/commons" "^1.3.0" - array-from "^2.1.1" - lodash "^4.17.15" - -"@sinonjs/text-encoding@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" - integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@types/bn.js@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@types/node@*": - version "16.10.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.2.tgz#5764ca9aa94470adb4e1185fe2e9f19458992b2e" - integrity sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -JSONStream@^1.3.4, JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abbrev@1, abbrev@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn-jsx@^5.2.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -agent-base@4, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - -agent-base@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" - integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== - dependencies: - es6-promisify "^5.0.0" - -agentkeepalive@^3.4.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" - integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== - dependencies: - humanize-ms "^1.2.1" - -ajv@^5.1.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= - dependencies: - string-width "^2.0.0" - -ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - -ansistyles@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" - integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk= - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== - dependencies: - default-require-extensions "^2.0.0" - -aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -"aproba@^1.1.2 || 2", aproba@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -archiver-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" - integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== - dependencies: - glob "^7.1.4" - graceful-fs "^4.2.0" - lazystream "^1.0.0" - lodash.defaults "^4.2.0" - lodash.difference "^4.5.0" - lodash.flatten "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.union "^4.6.0" - normalize-path "^3.0.0" - readable-stream "^2.0.0" - -archiver@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.0.tgz#dd3e097624481741df626267564f7dd8640a45ba" - integrity sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg== - dependencies: - archiver-utils "^2.1.0" - async "^3.2.0" - buffer-crc32 "^0.2.1" - readable-stream "^3.6.0" - readdir-glob "^1.0.0" - tar-stream "^2.2.0" - zip-stream "^4.1.0" - -archy@^1.0.0, archy@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - -array-from@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" - integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= - -array-includes@^3.1.1, array-includes@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.flat@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" - integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -array.prototype.flatmap@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" - integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -asap@^2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error@^1.1.0, assertion-error@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async@^3.1.0, async@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" - integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.6.0, aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -axe-core@^4.0.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" - integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bignumber.js@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== - -bin-links@^1.1.2, bin-links@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.8.tgz#bd39aadab5dc4bdac222a07df5baf1af745b2228" - integrity sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ== - dependencies: - bluebird "^3.5.3" - cmd-shim "^3.0.0" - gentle-fs "^2.3.0" - graceful-fs "^4.1.15" - npm-normalize-package-bin "^1.0.0" - write-file-atomic "^2.3.0" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bl@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5" - integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -blakejs@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702" - integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg== - -bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= - -bn.js@^4.11.1, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - -boxen@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -bson@^1.1.4: - version "1.1.6" - resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a" - integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg== - -buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-reverse@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-reverse/-/buffer-reverse-1.0.1.tgz#49283c8efa6f901bc01fa3304d06027971ae2f60" - integrity sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A= - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= - -bunyan@^1.8.12: - version "1.8.15" - resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" - integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== - optionalDependencies: - dtrace-provider "~0.8" - moment "^2.19.3" - mv "~2" - safe-json-stringify "~1" - -byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= - -byte-size@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191" - integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw== - -cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -caching-transform@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-3.0.2.tgz#601d46b91eca87687a281e71cef99791b0efca70" - integrity sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w== - dependencies: - hasha "^3.0.0" - make-dir "^2.0.0" - package-hash "^3.0.0" - write-file-atomic "^2.4.2" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-limit@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4" - integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^4.0.0, camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0, camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== - -cardinal@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" - integrity sha1-fMEFXYItISlU0HsIXeolHMe8VQU= - dependencies: - ansicolors "~0.3.2" - redeyed "~2.1.0" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -"catapult-sdk@link:../catapult-sdk": - version "0.0.0" - uid "" - -catbuffer-typescript@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/catbuffer-typescript/-/catbuffer-typescript-0.1.1.tgz#152746d7ec07af28da31c2f4ad9e00cc27133d5a" - integrity sha512-r/z3UKG3YCCdsTEHRXGe3IQxA8OaBRBE31e9du2LOaLStGxYCmxUjfRtJ/DyKfgpS55fJPl3w/VFMnsfwIHmkA== - -chai@^4.2.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.5.2, chokidar@^3.2.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cidr-regex@^2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.10.tgz#af13878bd4ad704de77d6dc800799358b3afa70d" - integrity sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q== - dependencies: - ip-regex "^2.1.0" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -clean-stack@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-3.0.1.tgz#155bf0b2221bf5f4fba89528d24c5953f17fe3a8" - integrity sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg== - dependencies: - escape-string-regexp "4.0.0" - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= - -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cli-columns@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e" - integrity sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4= - dependencies: - string-width "^2.0.0" - strip-ansi "^3.0.1" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-progress@^3.4.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.9.1.tgz#a22eba6a20f53289fdd05d5ee8cb2cc8c28f866e" - integrity sha512-AXxiCe2a0Lm0VN+9L0jzmfQSkcZm5EYspfqXKaSIQKqIk+0hnkZ3/v1E9B39mkD6vYhKih3c/RPsJBSwq9O99Q== - dependencies: - colors "^1.1.2" - string-width "^4.2.0" - -cli-table3@^0.5.0, cli-table3@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== - dependencies: - object-assign "^4.1.0" - string-width "^2.1.1" - optionalDependencies: - colors "^1.1.2" - -cli-ux@^5.2.1: - version "5.6.3" - resolved "https://registry.yarnpkg.com/cli-ux/-/cli-ux-5.6.3.tgz#eecdb2e0261171f2b28f2be6b18c490291c3a287" - integrity sha512-/oDU4v8BiDjX2OKcSunGH0iGDiEtj2rZaGyqNuv9IT4CgcSMyVWAMfn0+rEHaOc4n9ka78B0wo1+N1QX89f7mw== - dependencies: - "@oclif/command" "^1.6.0" - "@oclif/errors" "^1.2.1" - "@oclif/linewrap" "^1.0.0" - "@oclif/screen" "^1.0.3" - ansi-escapes "^4.3.0" - ansi-styles "^4.2.0" - cardinal "^2.1.1" - chalk "^4.1.0" - clean-stack "^3.0.0" - cli-progress "^3.4.0" - extract-stack "^2.0.0" - fs-extra "^8.1" - hyperlinker "^1.0.0" - indent-string "^4.0.0" - is-wsl "^2.2.0" - js-yaml "^3.13.1" - lodash "^4.17.11" - natural-orderby "^2.0.1" - object-treeify "^1.1.4" - password-prompt "^1.1.2" - semver "^7.3.2" - string-width "^4.2.0" - strip-ansi "^6.0.0" - supports-color "^8.1.0" - supports-hyperlinks "^2.1.0" - tslib "^2.0.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -cmd-shim@^3.0.0, cmd-shim@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb" - integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA== - dependencies: - graceful-fs "^4.1.2" - mkdirp "~0.5.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312" - integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -colors@^1.1.2, colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - -columnify@~1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" - integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= - dependencies: - strip-ansi "^3.0.0" - wcwidth "^1.0.0" - -combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -compress-commons@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d" - integrity sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ== - dependencies: - buffer-crc32 "^0.2.13" - crc32-stream "^4.0.2" - normalize-path "^3.0.0" - readable-stream "^3.6.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -config-chain@^1.1.12: - version "1.1.13" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" - integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -configstore@^3.0.0: - version "3.1.5" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.5.tgz#e9af331fadc14dabd544d3e7e76dc446a09a530f" - integrity sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA== - dependencies: - dot-prop "^4.2.1" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - -confusing-browser-globals@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" - integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== - -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -convert-source-map@^1.6.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -core-js-pure@^3.16.0: - version "3.18.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.1.tgz#097d34d24484be45cea700a448d1e74622646c80" - integrity sha512-kmW/k8MaSuqpvA1xm2l3TVlBuvW+XBkcaOroFUpO3D4lsTGQWBTb/tBDCf/PNkkPLrwgrkQRIYNPB0CeqGJWGQ== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -coveralls@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.1.tgz#f5d4431d8b5ae69c5079c8f8ca00d64ac77cf081" - integrity sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww== - dependencies: - js-yaml "^3.13.1" - lcov-parse "^1.0.0" - log-driver "^1.2.7" - minimist "^1.2.5" - request "^2.88.2" - -cp-file@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.2.0.tgz#40d5ea4a1def2a9acdd07ba5c0b0246ef73dc10d" - integrity sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA== - dependencies: - graceful-fs "^4.1.2" - make-dir "^2.0.0" - nested-error-stacks "^2.0.0" - pify "^4.0.1" - safe-buffer "^5.0.1" - -crc-32@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - -crc32-stream@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007" - integrity sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w== - dependencies: - crc-32 "^1.2.0" - readable-stream "^3.4.0" - -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= - dependencies: - capture-stack-trace "^1.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-env@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d" - integrity sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ== - dependencies: - cross-spawn "^6.0.5" - -cross-fetch@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" - integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== - dependencies: - node-fetch "2.6.1" - -cross-spawn@^4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-js@^3.1.9-1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== - -crypto-js@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" - integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== - -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= - -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -csv-generate@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.4.3.tgz#bc42d943b45aea52afa896874291da4b9108ffff" - integrity sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw== - -csv-parse@^4.16.3: - version "4.16.3" - resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.16.3.tgz#7ca624d517212ebc520a36873c3478fa66efbaf7" - integrity sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg== - -csv-stringify@^5.6.5: - version "5.6.5" - resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.5.tgz#c6d74badda4b49a79bf4e72f91cce1e33b94de00" - integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== - -csv@^5.1.1: - version "5.5.3" - resolved "https://registry.yarnpkg.com/csv/-/csv-5.5.3.tgz#cd26c1e45eae00ce6a9b7b27dcb94955ec95207d" - integrity sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g== - dependencies: - csv-generate "^3.4.3" - csv-parse "^4.16.3" - csv-stringify "^5.6.5" - stream-transform "^2.1.3" - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -damerau-levenshtein@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" - integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9, debug@^2.2.0, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@4.3.2, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= - -decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -deep-eql@^3.0.1, deep-eql@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -denque@^1.4.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf" - integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-indent@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= - -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -dezalgo@^1.0.0, dezalgo@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= - dependencies: - asap "^2.0.0" - wrappy "1" - -diff@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-prop@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" - integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ== - dependencies: - is-obj "^1.0.0" - -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -dotenv@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" - integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== - -dtrace-provider@^0.8.1, dtrace-provider@~0.8: - version "0.8.8" - resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" - integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== - dependencies: - nan "^2.14.0" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -editor@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" - integrity sha1-YMf4e9YrzGqJT6jM1q+3gjok90I= - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -elliptic@^6.5.2: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.0.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -enabled@2.0.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" - integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -err-code@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" - integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= - -errno@~0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -es6-promise@^4.0.3, es6-promise@~4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-regexp-component@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz#9c63b6d0b25ff2a88c3adbd18c5b61acc3b9faa2" - integrity sha1-nGO20LJf8qiMOtvRjFthrMO5+qI= - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-airbnb-base@^14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" - integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-config-airbnb@^18.1.0: - version "18.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9" - integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== - dependencies: - eslint-config-airbnb-base "^14.2.1" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== - dependencies: - debug "^3.2.7" - pkg-dir "^2.0.0" - -eslint-plugin-import@^2.19.1: - version "2.24.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" - integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== - dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" - has "^1.0.3" - is-core-module "^2.6.0" - minimatch "^3.0.4" - object.values "^1.1.4" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" - resolve "^1.20.0" - tsconfig-paths "^3.11.0" - -eslint-plugin-jsx-a11y@^6.2.3: - version "6.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" - integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== - dependencies: - "@babel/runtime" "^7.11.2" - aria-query "^4.2.2" - array-includes "^3.1.1" - ast-types-flow "^0.0.7" - axe-core "^4.0.2" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.6" - emoji-regex "^9.0.0" - has "^1.0.3" - jsx-ast-utils "^3.1.0" - language-tags "^1.0.5" - -eslint-plugin-react-hooks@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0" - integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g== - -eslint-plugin-react@^7.19.0: - version "7.26.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e" - integrity sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ== - dependencies: - array-includes "^3.1.3" - array.prototype.flatmap "^1.2.4" - doctrine "^2.1.0" - estraverse "^5.2.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.0.4" - object.entries "^1.1.4" - object.fromentries "^2.0.4" - object.hasown "^1.0.0" - object.values "^1.1.4" - prop-types "^15.7.2" - resolve "^2.0.0-next.3" - semver "^6.3.0" - string.prototype.matchall "^4.0.5" - -eslint-scope@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== - dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -esprima@^4.0.0, esprima@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== - dependencies: - js-sha3 "^0.8.0" - -ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereumjs-util@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.2.tgz#cfd79a9a3f5cdc042d1abf29964de9caf10ec238" - integrity sha512-xCV3PTAhW8Q2k88XZn9VcO4OrjpeXAlDm5LQTaOLp81SjNSSY6+MwuGXrx6vafOMheWSmZGxIXUbue5e9UvUBw== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.4" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -ewma@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ewma/-/ewma-2.0.1.tgz#9876c1c491ac5733c8666001a3961a04c97cf1e8" - integrity sha512-MYYK17A76cuuyvkR7MnqLW4iFYPEi5Isl2qb8rXiWpLiwFS9dxW/rncuNnjjgSENuVqZQkIuR4+DChVL4g1lnw== - dependencies: - assert-plus "^1.0.0" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== - -extend@~3.0.1, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extract-stack@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/extract-stack/-/extract-stack-2.0.0.tgz#11367bc865bfcd9bc0db3123e5edb57786f11f9b" - integrity sha512-AEo4zm+TenK7zQorGK1f9mJ8L14hnTDi2ZQPR+Mub1NX8zimka1mXpV5LpH8x9HoUmFSHZCfLHqWvp0Y4FxxzQ== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0, extsprintf@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-decode-uri-component@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" - integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== - -fast-deep-equal@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" - integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fecha@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" - integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== - -figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== - -figlet@^1.2.4: - version "1.5.2" - resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.2.tgz#dda34ff233c9a48e36fcff6741aeb5bafe49b634" - integrity sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ== - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= - -find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-my-way@^2.0.1: - version "2.2.5" - resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-2.2.5.tgz#86ce825266fa28cd962e538a45ec2aaa84c3d514" - integrity sha512-GjRZZlGcGmTh9t+6Xrj5K0YprpoAFCAiCPgmAH9Kb09O4oX6hYuckDfnDipYj+Q7B1GtYWSzDI5HEecNYscLQg== - dependencies: - fast-decode-uri-component "^1.0.0" - safe-regex2 "^2.0.0" - semver-store "^0.3.0" - -find-npm-prefix@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" - integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -fn.name@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" - integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== - -foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.1, form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -formidable@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" - integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -from2@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd" - integrity sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0= - dependencies: - inherits "~2.0.1" - readable-stream "~1.1.10" - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^8.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^9.0.1: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs-vacuum@^1.2.10, fs-vacuum@~1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" - integrity sha1-t2Kb7AekAxolSP35n17PHMizHjY= - dependencies: - graceful-fs "^4.1.2" - path-is-inside "^1.0.1" - rimraf "^2.5.2" - -fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -futoin-hkdf@^1.3.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/futoin-hkdf/-/futoin-hkdf-1.4.2.tgz#fd534e848e0e50339b8bfbd81250b09cbff10ba3" - integrity sha512-2BggwLEJOTfXzKq4Tl2bIT37p0IqqKkblH4e0cMp2sXTdmwg/ADBKMxvxaEytYYcgdxgng8+acsi3WgMVUl6CQ== - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -genfun@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" - integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== - -gentle-fs@^2.3.0, gentle-fs@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1" - integrity sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q== - dependencies: - aproba "^1.1.2" - chownr "^1.1.2" - cmd-shim "^3.0.3" - fs-vacuum "^1.2.10" - graceful-fs "^4.1.11" - iferr "^0.1.5" - infer-owner "^1.0.4" - mkdirp "^0.5.1" - path-is-inside "^1.0.2" - read-cmd-shim "^1.0.1" - slide "^1.1.6" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0, get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^6.0.1: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= - dependencies: - ini "^1.3.4" - -global-dirs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" - integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== - dependencies: - ini "2.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -globby@^11.0.1: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-unicode@^2.0.0, has-unicode@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasha@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" - integrity sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk= - dependencies: - is-stream "^1.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hippie@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/hippie/-/hippie-0.6.1.tgz#ef58a04afd5fb0027cd545baa81af70080c84411" - integrity sha512-R7en0nUIGn1eckmkaeEbXb4lJDg3gP7qxs/Tx/wLXzW4QmDCogxpBhhwFi5f6Z3/XTJISY0Jif0pKXQ2oYjkHw== - dependencies: - assertion-error "~1.1.0" - deep-eql "~3.0.1" - es6-promise "~4.2.4" - npm "^6.14.7" - pathval "~1.1.0" - qs "~6.5.2" - request "~2.87.0" - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.9: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-cache-semantics@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== - dependencies: - agent-base "4" - debug "3.1.0" - -http-signature@^1.2.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.5.tgz#9f19496ffbf3227298d7b5f156e0e1a948678683" - integrity sha512-NwoTQYSJoFt34jSBbwzDHDofoA61NGXzu6wXh95o1Ry62EnmKjXb/nR/RknLeZ3G/uGwrlKNY2z7uPt+Cdl7Tw== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.14.1" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^2.2.3: - version "2.2.4" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" - integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== - dependencies: - agent-base "^4.3.0" - debug "^3.1.0" - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= - dependencies: - ms "^2.0.0" - -hyperlinker@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e" - integrity sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ== - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -iferr@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-1.0.2.tgz#e9fde49a9da06dc4a4194c6c9ed6d08305037a6d" - integrity sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg== - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= - -ignore-walk@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" - integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== - dependencies: - minimatch "^3.0.4" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -import-fresh@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4, inflight@~1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - -ini@^1.3.4, ini@^1.3.5, ini@^1.3.8, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -init-package-json@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" - integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== - dependencies: - glob "^7.1.1" - npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" - promzard "^0.3.0" - read "~1.0.1" - read-package-json "1 || 2" - semver "2.x || 3.x || 4 || 5" - validate-npm-package-license "^3.0.1" - validate-npm-package-name "^3.0.0" - -inquirer@^7.0.0, inquirer@^7.3.3: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-cidr@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.1.tgz#e92ef121bdec2782271a77ce487a8b8df3718ab7" - integrity sha512-Gx+oErgq1j2jAKCR2Kbq0b3wbH0vQKqZ0wOlHxm0o56nq51Cs/DZA8oz9dMDhbHyHEGgJ86eTeVudtgMMOx3Mw== - dependencies: - cidr-regex "^2.0.10" - -is-core-module@^2.2.0, is-core-module@^2.6.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= - -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-installed-globally@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= - -is-npm@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" - integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= - dependencies: - path-is-inside "^1.0.1" - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== - dependencies: - call-bind "^1.0.0" - -is-wsl@^2.1.1, is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== - -istanbul-lib-hook@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz#c95695f383d4f8f60df1f04252a9550e15b5b133" - integrity sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA== - dependencies: - append-transform "^1.0.0" - -istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" - -istanbul-lib-report@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== - dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" - -istanbul-lib-source-maps@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" - source-map "^0.6.1" - -istanbul-reports@^2.2.4: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== - dependencies: - html-escaper "^2.0.0" - -js-sha256@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" - integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== - -js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-sha512@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.8.0.tgz#dd22db8d02756faccf19f218e3ed61ec8249f7d4" - integrity sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.13.1, js-yaml@^3.14.0: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" - integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== - dependencies: - array-includes "^3.1.3" - object.assign "^4.1.2" - -just-extend@^4.0.2: - version "4.2.1" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" - integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== - -keccak@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" - integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -kuler@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" - integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== - -language-subtag-registry@~0.3.2: - version "0.3.21" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" - integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= - dependencies: - language-subtag-registry "~0.3.2" - -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= - dependencies: - package-json "^4.0.0" - -latest-version@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - -lazy-property@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147" - integrity sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc= - -lazystream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= - dependencies: - readable-stream "^2.0.5" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -lcov-parse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" - integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -libcipm@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89" - integrity sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA== - dependencies: - bin-links "^1.1.2" - bluebird "^3.5.1" - figgy-pudding "^3.5.1" - find-npm-prefix "^1.0.2" - graceful-fs "^4.1.11" - ini "^1.3.5" - lock-verify "^2.1.0" - mkdirp "^0.5.1" - npm-lifecycle "^3.0.0" - npm-logical-tree "^1.2.1" - npm-package-arg "^6.1.0" - pacote "^9.1.0" - read-package-json "^2.0.13" - rimraf "^2.6.2" - worker-farm "^1.6.0" - -libnpm@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-3.0.1.tgz#0be11b4c9dd4d1ffd7d95c786e92e55d65be77a2" - integrity sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ== - dependencies: - bin-links "^1.1.2" - bluebird "^3.5.3" - find-npm-prefix "^1.0.2" - libnpmaccess "^3.0.2" - libnpmconfig "^1.2.1" - libnpmhook "^5.0.3" - libnpmorg "^1.0.1" - libnpmpublish "^1.1.2" - libnpmsearch "^2.0.2" - libnpmteam "^1.0.2" - lock-verify "^2.0.2" - npm-lifecycle "^3.0.0" - npm-logical-tree "^1.2.1" - npm-package-arg "^6.1.0" - npm-profile "^4.0.2" - npm-registry-fetch "^4.0.0" - npmlog "^4.1.2" - pacote "^9.5.3" - read-package-json "^2.0.13" - stringify-package "^1.0.0" - -libnpmaccess@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923" - integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ== - dependencies: - aproba "^2.0.0" - get-stream "^4.0.0" - npm-package-arg "^6.1.0" - npm-registry-fetch "^4.0.0" - -libnpmconfig@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/libnpmconfig/-/libnpmconfig-1.2.1.tgz#c0c2f793a74e67d4825e5039e7a02a0044dfcbc0" - integrity sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA== - dependencies: - figgy-pudding "^3.5.1" - find-up "^3.0.0" - ini "^1.3.5" - -libnpmhook@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.3.tgz#4020c0f5edbf08ebe395325caa5ea01885b928f7" - integrity sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmorg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.1.tgz#5d2503f6ceb57f33dbdcc718e6698fea6d5ad087" - integrity sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmpublish@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280" - integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.5.1" - get-stream "^4.0.0" - lodash.clonedeep "^4.5.0" - normalize-package-data "^2.4.0" - npm-package-arg "^6.1.0" - npm-registry-fetch "^4.0.0" - semver "^5.5.1" - ssri "^6.0.1" - -libnpmsearch@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.2.tgz#9a4f059102d38e3dd44085bdbfe5095f2a5044cf" - integrity sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg== - dependencies: - figgy-pudding "^3.5.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmteam@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.2.tgz#8b48bcbb6ce70dd8150c950fcbdbf3feb6eec820" - integrity sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpx@^10.2.4: - version "10.2.4" - resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.4.tgz#ef0e3258e29aef2ec7ee3276115e20e67f67d4ee" - integrity sha512-BPc0D1cOjBeS8VIBKUu5F80s6njm0wbVt7CsGMrIcJ+SI7pi7V0uVPGpEMH9H5L8csOcclTxAXFE2VAsJXUhfA== - dependencies: - dotenv "^5.0.1" - npm-package-arg "^6.0.0" - rimraf "^2.6.2" - safe-buffer "^5.1.0" - update-notifier "^2.3.0" - which "^1.3.0" - y18n "^4.0.0" - yargs "^14.2.3" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lock-verify@^2.0.2, lock-verify@^2.1.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.1.tgz#81107948c51ed16f97b96ff8b60675affb243fc1" - integrity sha512-n0Zw2DVupKfZMazy/HIFVNohJ1z8fIoZ77WBnyyBGG6ixw83uJNyrbiJvvHWe1QKkGiBCjj8RCPlymltliqEww== - dependencies: - "@iarna/cli" "^1.2.0" - npm-package-arg "^6.1.0" - semver "^5.4.1" - -lockfile@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" - integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== - dependencies: - signal-exit "^3.0.2" - -lodash._baseuniq@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" - integrity sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg= - dependencies: - lodash._createset "~4.0.0" - lodash._root "~3.0.0" - -lodash._createset@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" - integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash._root@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= - -lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - -lodash.difference@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= - -lodash.template@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - -lodash.union@^4.6.0, lodash.union@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= - -lodash.uniq@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - -lodash.without@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" - integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-driver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" - integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -logform@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.0.tgz#a3997a05985de2ebd325ae0d166dffc9c6fe6b57" - integrity sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ== - dependencies: - colors "^1.2.1" - fecha "^4.2.0" - ms "^2.1.1" - safe-stable-stringify "^1.1.0" - triple-beam "^1.3.0" - -lolex@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.2.0.tgz#ddbd7f6213ca1ea5826901ab1222b65d714b3cd7" - integrity sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg== - -lolex@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== - dependencies: - "@sinonjs/commons" "^1.7.0" - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-fetch-happen@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd" - integrity sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag== - dependencies: - agentkeepalive "^3.4.1" - cacache "^12.0.0" - http-cache-semantics "^3.8.1" - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - node-fetch-npm "^2.0.2" - promise-retry "^1.1.1" - socks-proxy-agent "^4.0.0" - ssri "^6.0.0" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -meant@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c" - integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw== - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - -memory-pager@^1.0.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" - integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merkletreejs@^0.2.9: - version "0.2.24" - resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.2.24.tgz#6dc52b3e0946846c25816216f1b60094a18a5e7a" - integrity sha512-JUv2zSFuTpMj9uxqNXAOAQz6LKXL/AUalyuDzvqyf0fV09VeU7WjNDMDD+wbdtrA1mNEbV5w1XDWXMud8aNYTg== - dependencies: - bignumber.js "^9.0.1" - buffer-reverse "^1.0.1" - crypto-js "^3.1.9-1" - treeify "^1.1.0" - web3-utils "^1.3.4" - -micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mime-db@1.50.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== - dependencies: - mime-db "1.50.0" - -mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== - -mime@^2.4.3: - version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minipass@^2.3.5, minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixme@^0.5.1: - version "0.5.4" - resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.5.4.tgz#8cb3bd0cd32a513c161bf1ca99d143f0bcf2eff3" - integrity sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw== - -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha-jenkins-reporter@^0.4.3: - version "0.4.7" - resolved "https://registry.yarnpkg.com/mocha-jenkins-reporter/-/mocha-jenkins-reporter-0.4.7.tgz#59505d59a9fdeb64ee8270f13d8ca6c48c1dfad7" - integrity sha512-ek05WBoGX9G5B29QmFw67H92ZcvZcp62RASaHWqiZOWjc/G2YlKBeu7t60J5wpaQP1rFS8T9S85ed/3iDdf/2A== - dependencies: - diff "4.0.1" - mkdirp "^0.5.4" - xml "^1.0.1" - -mocha@^9.1.0: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -moment@^2.19.3, moment@^2.22.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - -mongodb@^3.3.0-beta2: - version "3.7.1" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.7.1.tgz#492afe1e870eb11b2d98f7e302146d176bda1ed4" - integrity sha512-iSVgexYr8ID0ieeNFUbRfQeOZxOchRck6kEDVySQRaa8VIw/1Pm+/LgcpZcl/BWV6nT0L8lP9qyl7dRPJ6mnLw== - dependencies: - bl "^2.2.1" - bson "^1.1.4" - denque "^1.4.1" - optional-require "^1.0.3" - safe-buffer "^5.1.2" - optionalDependencies: - saslprep "^1.0.0" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.0.0, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.8, mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -mv@~2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" - integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= - dependencies: - mkdirp "~0.5.1" - ncp "~2.0.0" - rimraf "~2.4.0" - -nan@2.14.2: - version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" - integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== - -nan@^2.14.0: - version "2.15.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" - integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== - -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -natural-orderby@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/natural-orderby/-/natural-orderby-2.0.3.tgz#8623bc518ba162f8ff1cdb8941d74deb0fdcc016" - integrity sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q== - -ncp@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" - integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= - -negotiator@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -nested-error-stacks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" - integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -nise@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7" - integrity sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ== - dependencies: - "@sinonjs/formatio" "^3.2.1" - "@sinonjs/text-encoding" "^0.7.1" - just-extend "^4.0.2" - lolex "^5.0.1" - path-to-regexp "^1.7.0" - -noble-ed25519@^1.0.3: - version "1.2.6" - resolved "https://registry.yarnpkg.com/noble-ed25519/-/noble-ed25519-1.2.6.tgz#a55b75c61da000498abb43ffd81caaa370bfed22" - integrity sha512-zfnWqg9FVMp8CnzUpAjbt1nDXpDjCvxYiCXdnW1mY8zQHw/6twUlkFm14VPdojVzc0kcd+i9zT79+26GcNbsuQ== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-fetch-npm@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4" - integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg== - dependencies: - encoding "^0.1.11" - json-parse-better-errors "^1.0.0" - safe-buffer "^5.1.1" - -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@^2.6.0: - version "2.6.5" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" - integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.2.0, node-gyp-build@^4.2.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" - integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== - -node-gyp@^5.0.2, node-gyp@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" - integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.1.2" - request "^2.88.0" - rimraf "^2.6.3" - semver "^5.7.1" - tar "^4.4.12" - which "^1.3.1" - -node-stream-zip@^1.12.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" - integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw== - -nodemon@^2.0.6: - version "2.0.13" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.13.tgz#67d40d3a4d5bd840aa785c56587269cfcf5d24aa" - integrity sha512-UMXMpsZsv1UXUttCn6gv8eQPhn6DR4BW+txnL3IN5IHqrCwcrT/yWHfL35UsClGXknTH79r5xbu+6J1zNHuSyA== - dependencies: - chokidar "^3.2.2" - debug "^3.2.6" - ignore-by-default "^1.0.1" - minimatch "^3.0.4" - pstree.remy "^1.1.7" - semver "^5.7.1" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.3" - update-notifier "^5.1.0" - -nopt@^4.0.1, nopt@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= - dependencies: - abbrev "1" - -normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== - -npm-audit-report@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed" - integrity sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw== - dependencies: - cli-table3 "^0.5.0" - console-control-strings "^1.1.0" - -npm-bundled@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" - integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-cache-filename@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" - integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE= - -npm-install-checks@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" - integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg== - dependencies: - semver "^2.3.0 || 3.x || 4 || 5" - -npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309" - integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g== - dependencies: - byline "^5.0.0" - graceful-fs "^4.1.15" - node-gyp "^5.0.2" - resolve-from "^4.0.0" - slide "^1.1.6" - uid-number "0.0.6" - umask "^1.1.0" - which "^1.3.1" - -npm-logical-tree@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88" - integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg== - -npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0, npm-package-arg@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" - integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== - dependencies: - hosted-git-info "^2.7.1" - osenv "^0.1.5" - semver "^5.6.0" - validate-npm-package-name "^3.0.0" - -npm-packlist@^1.1.12, npm-packlist@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-normalize-package-bin "^1.0.1" - -npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" - integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== - dependencies: - figgy-pudding "^3.5.1" - npm-package-arg "^6.0.0" - semver "^5.4.1" - -npm-profile@^4.0.2, npm-profile@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.4.tgz#28ee94390e936df6d084263ee2061336a6a1581b" - integrity sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ== - dependencies: - aproba "^1.1.2 || 2" - figgy-pudding "^3.4.1" - npm-registry-fetch "^4.0.0" - -npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.7.tgz#57951bf6541e0246b34c9f9a38ab73607c9449d7" - integrity sha512-cny9v0+Mq6Tjz+e0erFAB+RYJ/AVGzkjnISiobqP8OWj9c9FLoZZu8/SPSKJWE17F1tk4018wfjV+ZbIbqC7fQ== - dependencies: - JSONStream "^1.3.4" - bluebird "^3.5.1" - figgy-pudding "^3.4.1" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - npm-package-arg "^6.1.0" - safe-buffer "^5.2.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npm-user-validate@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561" - integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw== - -npm@^6.14.7: - version "6.14.15" - resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.15.tgz#97dd51af5b5d6225b611b40c5cb4d31da1d467fe" - integrity sha512-dkcQc4n+DiJAMYG2haNAMyJbmuvevjXz+WC9dCUzodw8EovwTIc6CATSsTEplCY6c0jG4OshxFGFJsrnKJguWA== - dependencies: - JSONStream "^1.3.5" - abbrev "~1.1.1" - ansicolors "~0.3.2" - ansistyles "~0.1.3" - aproba "^2.0.0" - archy "~1.0.0" - bin-links "^1.1.8" - bluebird "^3.5.5" - byte-size "^5.0.1" - cacache "^12.0.3" - call-limit "^1.1.1" - chownr "^1.1.4" - ci-info "^2.0.0" - cli-columns "^3.1.2" - cli-table3 "^0.5.1" - cmd-shim "^3.0.3" - columnify "~1.5.4" - config-chain "^1.1.12" - detect-indent "~5.0.0" - detect-newline "^2.1.0" - dezalgo "~1.0.3" - editor "~1.0.0" - figgy-pudding "^3.5.1" - find-npm-prefix "^1.0.2" - fs-vacuum "~1.2.10" - fs-write-stream-atomic "~1.0.10" - gentle-fs "^2.3.1" - glob "^7.1.6" - graceful-fs "^4.2.4" - has-unicode "~2.0.1" - hosted-git-info "^2.8.9" - iferr "^1.0.2" - infer-owner "^1.0.4" - inflight "~1.0.6" - inherits "^2.0.4" - ini "^1.3.8" - init-package-json "^1.10.3" - is-cidr "^3.0.0" - json-parse-better-errors "^1.0.2" - lazy-property "~1.0.0" - libcipm "^4.0.8" - libnpm "^3.0.1" - libnpmaccess "^3.0.2" - libnpmhook "^5.0.3" - libnpmorg "^1.0.1" - libnpmsearch "^2.0.2" - libnpmteam "^1.0.2" - libnpx "^10.2.4" - lock-verify "^2.1.0" - lockfile "^1.0.4" - lodash._baseuniq "~4.6.0" - lodash.clonedeep "~4.5.0" - lodash.union "~4.6.0" - lodash.uniq "~4.5.0" - lodash.without "~4.4.0" - lru-cache "^5.1.1" - meant "^1.0.2" - mississippi "^3.0.0" - mkdirp "^0.5.5" - move-concurrently "^1.0.1" - node-gyp "^5.1.0" - nopt "^4.0.3" - normalize-package-data "^2.5.0" - npm-audit-report "^1.3.3" - npm-cache-filename "~1.0.2" - npm-install-checks "^3.0.2" - npm-lifecycle "^3.1.5" - npm-package-arg "^6.1.1" - npm-packlist "^1.4.8" - npm-pick-manifest "^3.0.2" - npm-profile "^4.0.4" - npm-registry-fetch "^4.0.7" - npm-user-validate "^1.0.1" - npmlog "~4.1.2" - once "~1.4.0" - opener "^1.5.2" - osenv "^0.1.5" - pacote "^9.5.12" - path-is-inside "~1.0.2" - promise-inflight "~1.0.1" - qrcode-terminal "^0.12.0" - query-string "^6.8.2" - qw "~1.0.1" - read "~1.0.7" - read-cmd-shim "^1.0.5" - read-installed "~4.0.3" - read-package-json "^2.1.1" - read-package-tree "^5.3.1" - readable-stream "^3.6.0" - readdir-scoped-modules "^1.1.0" - request "^2.88.0" - retry "^0.12.0" - rimraf "^2.7.1" - safe-buffer "^5.1.2" - semver "^5.7.1" - sha "^3.0.0" - slide "~1.1.6" - sorted-object "~2.0.1" - sorted-union-stream "~2.1.3" - ssri "^6.0.2" - stringify-package "^1.0.1" - tar "^4.4.19" - text-table "~0.2.0" - tiny-relative-date "^1.3.0" - uid-number "0.0.6" - umask "~1.1.0" - unique-filename "^1.1.1" - unpipe "~1.0.0" - update-notifier "^2.5.0" - uuid "^3.3.3" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "~3.0.0" - which "^1.3.1" - worker-farm "^1.7.0" - write-file-atomic "^2.4.3" - -npmlog@^4.1.2, npmlog@~4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -nyc@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-14.1.1.tgz#151d64a6a9f9f5908a1b73233931e4a0a3075eeb" - integrity sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw== - dependencies: - archy "^1.0.0" - caching-transform "^3.0.2" - convert-source-map "^1.6.0" - cp-file "^6.2.0" - find-cache-dir "^2.1.0" - find-up "^3.0.0" - foreground-child "^1.5.6" - glob "^7.1.3" - istanbul-lib-coverage "^2.0.5" - istanbul-lib-hook "^2.0.7" - istanbul-lib-instrument "^3.3.0" - istanbul-lib-report "^2.0.8" - istanbul-lib-source-maps "^3.0.6" - istanbul-reports "^2.2.4" - js-yaml "^3.13.1" - make-dir "^2.1.0" - merge-source-map "^1.1.0" - resolve-from "^4.0.0" - rimraf "^2.6.3" - signal-exit "^3.0.2" - spawn-wrap "^1.4.2" - test-exclude "^5.2.3" - uuid "^3.3.2" - yargs "^13.2.2" - yargs-parser "^13.0.0" - -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-treeify@^1.1.4: - version "1.1.33" - resolved "https://registry.yarnpkg.com/object-treeify/-/object-treeify-1.1.33.tgz#f06fece986830a3cba78ddd32d4c11d1f76cdf40" - integrity sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.entries@^1.1.2, object.entries@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.fromentries@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" - integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.hasown@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" - integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.values@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0, once@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -one-time@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" - integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== - dependencies: - fn.name "1.x.x" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - -optional-require@^1.0.3: - version "1.1.8" - resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.1.8.tgz#16364d76261b75d964c482b2406cb824d8ec44b7" - integrity sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA== - dependencies: - require-at "^1.0.6" - -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4, osenv@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-hash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e" - integrity sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA== - dependencies: - graceful-fs "^4.1.15" - hasha "^3.0.0" - lodash.flattendeep "^4.4.0" - release-zalgo "^1.0.0" - -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" - -pacote@^9.1.0, pacote@^9.5.12, pacote@^9.5.3: - version "9.5.12" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" - integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== - dependencies: - bluebird "^3.5.3" - cacache "^12.0.2" - chownr "^1.1.2" - figgy-pudding "^3.5.1" - get-stream "^4.1.0" - glob "^7.1.3" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - minimatch "^3.0.4" - minipass "^2.3.5" - mississippi "^3.0.0" - mkdirp "^0.5.1" - normalize-package-data "^2.4.0" - npm-normalize-package-bin "^1.0.0" - npm-package-arg "^6.1.0" - npm-packlist "^1.1.12" - npm-pick-manifest "^3.0.0" - npm-registry-fetch "^4.0.0" - osenv "^0.1.5" - promise-inflight "^1.0.1" - promise-retry "^1.1.1" - protoduck "^5.0.1" - rimraf "^2.6.2" - safe-buffer "^5.1.2" - semver "^5.6.0" - ssri "^6.0.1" - tar "^4.4.10" - unique-filename "^1.1.1" - which "^1.3.1" - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -password-prompt@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/password-prompt/-/password-prompt-1.1.2.tgz#85b2f93896c5bd9e9f2d6ff0627fa5af3dc00923" - integrity sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA== - dependencies: - ansi-escapes "^3.1.0" - cross-spawn "^6.0.5" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^1.1.1, pathval@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -pbkdf2@^3.0.17: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pidusage@^2.0.17: - version "2.0.21" - resolved "https://registry.yarnpkg.com/pidusage/-/pidusage-2.0.21.tgz#7068967b3d952baea73e57668c98b9eaa876894e" - integrity sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA== - dependencies: - safe-buffer "^5.2.1" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -printj@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise-inflight@^1.0.1, promise-inflight@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -promise-retry@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" - integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= - dependencies: - err-code "^1.0.0" - retry "^0.10.0" - -promzard@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= - dependencies: - read "1" - -prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -protoduck@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" - integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== - dependencies: - genfun "^5.0.0" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -pstree.remy@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -pupa@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" - integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== - dependencies: - escape-goat "^2.0.0" - -qrcode-terminal@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" - integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== - -qs@^6.7.0: - version "6.10.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" - integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== - dependencies: - side-channel "^1.0.4" - -qs@~6.5.1, qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@^6.8.2: - version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" - integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== - dependencies: - decode-uri-component "^0.2.0" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -qw@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4" - integrity sha1-77/cdA+a0FQwRCassYNBLMi5ltQ= - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@~1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" - integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA== - dependencies: - graceful-fs "^4.1.2" - -read-installed@~4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" - integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= - dependencies: - debuglog "^1.0.1" - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - semver "2 || 3 || 4 || 5" - slide "~1.1.3" - util-extend "^1.0.1" - optionalDependencies: - graceful-fs "^4.1.2" - -"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13, read-package-json@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" - integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== - dependencies: - glob "^7.1.1" - json-parse-even-better-errors "^2.3.0" - normalize-package-data "^2.0.0" - npm-normalize-package-bin "^1.0.0" - -read-package-tree@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636" - integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw== - dependencies: - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - util-promisify "^2.1.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -read@1, read@~1.0.1, read@~1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= - dependencies: - mute-stream "~0.0.4" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~1.1.10: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readdir-glob@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.1.tgz#f0e10bb7bf7bfa7e0add8baffdc54c3f7dbee6c4" - integrity sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA== - dependencies: - minimatch "^3.0.4" - -readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -redeyed@~2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b" - integrity sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs= - dependencies: - esprima "~4.0.0" - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexp.prototype.flags@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -registry-auth-token@^3.0.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" - integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-auth-token@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" - integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== - dependencies: - rc "^1.2.8" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= - dependencies: - rc "^1.0.1" - -registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= - dependencies: - es6-error "^4.0.1" - -request@^2.88.0, request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -request@~2.87.0: - version "2.87.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" - integrity sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -require-at@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/require-at/-/require-at-1.0.6.tgz#9eb7e3c5e00727f5a4744070a7f560d4de4f6e6a" - integrity sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -resolve@^2.0.0-next.3: - version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" - integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -restify-errors@^8.0.0, restify-errors@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/restify-errors/-/restify-errors-8.0.2.tgz#0b9678738e37888e4fefe52aa6ee92771ec954e9" - integrity sha512-UsXUVQo7M26xoQzeUcZQ0+H8L2t9DGzrXcAgR3WB/1vnbl+UdI4tZ1PqYsN+sS5WnqHKZ0Xy9w0CKf83bbrwYA== - dependencies: - "@netflix/nerror" "^1.0.0" - assert-plus "^1.0.0" - lodash "^4.17.15" - optionalDependencies: - safe-json-stringify "^1.0.4" - -restify@^8.3.3: - version "8.6.0" - resolved "https://registry.yarnpkg.com/restify/-/restify-8.6.0.tgz#b2a9a32b68160d4f352c71d7b4e63dd3e76f46e9" - integrity sha512-vLorgPD6j6bqmBqsBjKHa12c963jYESjJ2MOKK/+9nVlS7if/yl5GJ4/Vvty8qHecCtA2vZ3uejlczL+cv2mmg== - dependencies: - assert-plus "^1.0.0" - bunyan "^1.8.12" - csv "^5.1.1" - escape-regexp-component "^1.0.2" - ewma "^2.0.1" - find-my-way "^2.0.1" - formidable "^1.2.1" - http-signature "^1.2.0" - lodash "^4.17.11" - lru-cache "^5.1.1" - mime "^2.4.3" - negotiator "^0.6.2" - once "^1.4.0" - pidusage "^2.0.17" - qs "^6.7.0" - restify-errors "^8.0.2" - semver "^6.1.1" - send "^0.16.2" - spdy "^4.0.0" - uuid "^3.3.2" - vasync "^2.2.0" - optionalDependencies: - dtrace-provider "^0.8.1" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.2.2.tgz#b6861782a1f4762dce43402a71eb7a283f44573c" - integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ== - -retry@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@~2.4.0: - version "2.4.5" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" - integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= - dependencies: - glob "^6.0.1" - -ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.2.4: - version "2.2.6" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" - integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== - dependencies: - bn.js "^4.11.1" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -rxjs-compat@^6.6.3: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs-compat/-/rxjs-compat-6.6.7.tgz#6eb4ef75c0a58ea672854a701ccc8d49f41e69cb" - integrity sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw== - -rxjs@^6.6.0, rxjs@^6.6.3: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-json-stringify@^1.0.4, safe-json-stringify@~1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" - integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== - -safe-regex2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-2.0.0.tgz#b287524c397c7a2994470367e0185e1916b1f5b9" - integrity sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ== - dependencies: - ret "~0.2.0" - -safe-stable-stringify@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a" - integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -saslprep@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" - integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== - dependencies: - sparse-bitfield "^3.0.3" - -scrypt-js@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= - dependencies: - semver "^5.0.3" - -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - -semver-store@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9" - integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg== - -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -send@^0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.4.0" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -sha@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/sha/-/sha-3.0.0.tgz#b2f2f90af690c16a3a839a6a6c680ea51fedd1ae" - integrity sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw== - dependencies: - graceful-fs "^4.1.2" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shelljs@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" - integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shx@^0.3.2: - version "0.3.3" - resolved "https://registry.yarnpkg.com/shx/-/shx-0.3.3.tgz#681a88c7c10db15abe18525349ed474f0f1e7b9f" - integrity sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA== - dependencies: - minimist "^1.2.3" - shelljs "^0.8.4" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -sinon@^7.3.2: - version "7.5.0" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.5.0.tgz#e9488ea466070ea908fd44a3d6478fd4923c67ec" - integrity sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q== - dependencies: - "@sinonjs/commons" "^1.4.0" - "@sinonjs/formatio" "^3.2.1" - "@sinonjs/samsam" "^3.3.3" - diff "^3.5.0" - lolex "^4.2.0" - nise "^1.5.2" - supports-color "^5.5.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= - -smart-buffer@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -socks-proxy-agent@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" - integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== - dependencies: - agent-base "~4.2.1" - socks "~2.3.2" - -socks@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" - integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== - dependencies: - ip "1.1.5" - smart-buffer "^4.1.0" - -sorted-object@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" - integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw= - -sorted-union-stream@~2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7" - integrity sha1-x3lMfgd4gAUv9xqNSi27Sppjisc= - dependencies: - from2 "^1.3.0" - stream-iterate "^1.1.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sparse-bitfield@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" - integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= - dependencies: - memory-pager "^1.0.2" - -spawn-wrap@^1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.3.tgz#81b7670e170cca247d80bf5faf0cfb713bdcf848" - integrity sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw== - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.6.2" - signal-exit "^3.0.2" - which "^1.3.0" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" - integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@1.16.1, sshpk@^1.14.1, sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.0, ssri@^6.0.1, ssri@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" - integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== - dependencies: - figgy-pudding "^3.5.1" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -statuses@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-iterate@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1" - integrity sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE= - dependencies: - readable-stream "^2.1.5" - stream-shift "^1.0.0" - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -stream-transform@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-2.1.3.tgz#a1c3ecd72ddbf500aa8d342b0b9df38f5aa598e3" - integrity sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ== - dependencies: - mixme "^0.5.1" - -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.matchall@^4.0.5: - version "4.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" - integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.3.1" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringify-package@^1.0.0, stringify-package@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" - integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= - dependencies: - is-hex-prefixed "1.0.0" - -strip-json-comments@3.1.1, strip-json-comments@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -supports-color@8.1.1, supports-color@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -symbol-bootstrap@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/symbol-bootstrap/-/symbol-bootstrap-1.1.0.tgz#4136fe704fdfe38dc77d33efa6d8d4b7d424e0ad" - integrity sha512-av4Znw8TqMjMeS3hEtTDw9pS6v/Hl4aJsWWOw/z9QEBlmL1PLAQh6LuS3M43jJWI8FaKJnUzvaJm5Y/TwQduYQ== - dependencies: - "@oclif/command" "^1.7.0" - "@oclif/config" "^1.16.0" - "@oclif/plugin-autocomplete" "^0.3.0" - "@oclif/plugin-help" "^3.1.0" - archiver "^5.2.0" - cross-fetch "^3.1.4" - figlet "^1.2.4" - handlebars "^4.7.7" - inquirer "^7.3.3" - js-yaml "^3.14.0" - lodash "^4.17.21" - memorystream "^0.3.1" - noble-ed25519 "^1.0.3" - node-stream-zip "^1.12.0" - rxjs "^6.6.3" - semver "^7.3.5" - shx "^0.3.2" - symbol-sdk "^1.0.1" - symbol-statistics-service-typescript-fetch-client "^1.1.1-SNAPSHOT.202110302303" - tslib "^1.13.0" - utf8 "^2.1.2" - winston "^3.3.3" - -symbol-openapi-typescript-fetch-client@0.11.2: - version "0.11.2" - resolved "https://registry.yarnpkg.com/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.11.2.tgz#c34b1a2345b567645b802b79b6e8431281a4c938" - integrity sha512-A1MAN8/UWlaCEibBf6zxkduZwDNSvWwLPp6JB0GeYI/FAOrw/9nLyuS/NJQ3siGAUclnuejH1wG7KdUg0/4RSw== - -symbol-sdk@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-sdk/-/symbol-sdk-1.0.1.tgz#d401bad7deccdb4a9ea225bb30847fbffd31e698" - integrity sha512-G4sdGBfggTSqKs9XchMQAtOfl80Z2eARafxZnzje5qxzfUSQUCFYdBP7IJiA2PDoeyfXJJpzWWTlgq9EzvKm1A== - dependencies: - "@js-joda/core" "^3.2.0" - bluebird "^3.7.2" - catbuffer-typescript "0.1.1" - crypto-js "^4.0.0" - diff "^4.0.2" - futoin-hkdf "^1.3.2" - js-sha256 "^0.9.0" - js-sha3 "^0.8.0" - js-sha512 "^0.8.0" - long "^4.0.0" - merkletreejs "^0.2.9" - minimist "^1.2.5" - node-fetch "^2.6.0" - ripemd160 "^2.0.2" - rxjs "^6.6.3" - rxjs-compat "^6.6.3" - symbol-openapi-typescript-fetch-client "0.11.2" - tweetnacl "^1.0.3" - utf8 "^2.1.2" - ws "^7.3.1" - -symbol-statistics-service-typescript-fetch-client@^1.1.1-SNAPSHOT.202110302303: - version "1.1.1-SNAPSHOT.202110302303" - resolved "https://registry.yarnpkg.com/symbol-statistics-service-typescript-fetch-client/-/symbol-statistics-service-typescript-fetch-client-1.1.1-SNAPSHOT.202110302303.tgz#586785ec277c16c4c5b27325b3865807d9395714" - integrity sha512-rFhjyOzkerFCk5S7enq6ugSf72Pa5ck3Cna6lXOBFFEiIKVkecQKm/anrcNFhs1ijhY53N6cJta/45mMJGXgiw== - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tar-stream@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@^4.4.10, tar@^4.4.12, tar@^4.4.19: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= - dependencies: - execa "^0.7.0" - -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" - -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - -text-table@^0.2.0, text-table@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -"through@>=2.2.7 <3", through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tiny-relative-date@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" - integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -tough-cookie@~2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== - dependencies: - punycode "^1.4.1" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -treeify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" - integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== - -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== - -tsconfig-paths@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" - integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@^1.13.0, tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -tweetnacl@^1.0.1, tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -uglify-js@^3.1.4: - version "3.14.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99" - integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A== - -uid-number@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= - -umask@^1.1.0, umask@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" - integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -undefsafe@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" - integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== - dependencies: - debug "^2.2.0" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= - -update-notifier@^2.2.0, update-notifier@^2.3.0, update-notifier@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -update-notifier@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" - integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== - dependencies: - boxen "^5.0.0" - chalk "^4.1.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.4.0" - is-npm "^5.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.1.0" - pupa "^2.1.1" - semver "^7.3.4" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -utf8@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -utf8@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" - integrity sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY= - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util-extend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= - -util-promisify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53" - integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM= - dependencies: - object.getownpropertydescriptors "^2.0.3" - -uuid@^3.1.0, uuid@^3.3.2, uuid@^3.3.3: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= - dependencies: - builtins "^1.0.3" - -vasync@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/vasync/-/vasync-2.2.0.tgz#cfde751860a15822db3b132bc59b116a4adaf01b" - integrity sha1-z951GGChWCLbOxMrxZsRakra8Bs= - dependencies: - verror "1.10.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -wcwidth@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -web3-utils@^1.3.4: - version "1.6.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.6.0.tgz#1975c5ee5b7db8a0836eb7004848a7cd962d1ddc" - integrity sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg== - dependencies: - bn.js "^4.11.9" - ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.2.9, which@^1.3.0, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== - dependencies: - string-width "^2.1.1" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -winston-transport@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== - dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" - -winston@^3.2.1, winston@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== - dependencies: - "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" - is-stream "^2.0.0" - logform "^2.2.0" - one-time "^1.0.0" - readable-stream "^3.4.0" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.4.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -worker-farm@^1.6.0, worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-4.0.0.tgz#b3570d7c70156159a2d42be5cc942e957f7b1131" - integrity sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg== - dependencies: - ansi-styles "^3.2.0" - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2, write-file-atomic@^2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@^7.1.0, ws@^7.3.1: - version "7.5.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" - integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== - -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" - integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^13.0.0, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^15.0.1: - version "15.0.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.3.tgz#316e263d5febe8b38eef61ac092b33dfcc9b1115" - integrity sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= - dependencies: - camelcase "^4.1.0" - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^13.2.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@^14.2.3: - version "14.2.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" - integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== - dependencies: - cliui "^5.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^15.0.1" - -yargs@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zeromq@^5.2.8: - version "5.2.8" - resolved "https://registry.yarnpkg.com/zeromq/-/zeromq-5.2.8.tgz#94b0b85e4152e98b8bb163f1db4a34280d44d9d0" - integrity sha512-bXzsk7KOmgLSv1tC0Ms1VXBy90+Rz27ZYf27cLuldRYbpqYpuWJfxxHFhO710t22zgWBnmdUP0m3SKFpLI0u5g== - dependencies: - nan "2.14.2" - node-gyp-build "^4.2.3" - -zip-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79" - integrity sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A== - dependencies: - archiver-utils "^2.1.0" - compress-commons "^4.1.0" - readable-stream "^3.6.0" diff --git a/scripts/.pylintrc b/scripts/.pylintrc deleted file mode 100644 index bffcdda83..000000000 --- a/scripts/.pylintrc +++ /dev/null @@ -1,426 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. -jobs=1 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -#disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call -disable=missing-docstring,misplaced-comparison-constant - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable= - - -[REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio).You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[BASIC] - -# Naming hint for argument names -argument-name-hint=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct argument names -argument-rgx=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Naming hint for attribute names -attr-name-hint=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct attribute names -attr-rgx=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(t_[A-Z0-9_]+)|(__.*__))$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(t_[A-Z0-9_]+)|(__.*__))$ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=100 - -# Naming hint for function names -function-name-hint=(([a-z][a-zA-Z0-9_]{2,40})|(_[a-z0-9_]*))$ - -# Regular expression matching correct function names -function-rgx=(([a-z][a-zA-Z0-9_]{2,40})|(_[a-z0-9_]*))$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for method names -method-name-hint=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-zA-Z0-9_]*))$ - -# Regular expression matching correct method names -method-rgx=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-zA-Z0-9_]*))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct module names -module-rgx=([A-Za-z][a-zA-Z0-9]+)$ - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=. - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty - -# Naming hint for variable names -variable-name-hint=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct variable names -variable-rgx=(([a-z][a-zA-Z0-9_]{2,30})|(_[a-z0-9_]*))$ - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=140 - -# Maximum number of lines in a module -max-module-lines=1000 - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,future.builtins - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=8 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of statements in function / method body -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[IMPORTS] - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception diff --git a/scripts/eslint-templates/src.eslintrc b/scripts/eslint-templates/src.eslintrc deleted file mode 100644 index 2a759174a..000000000 --- a/scripts/eslint-templates/src.eslintrc +++ /dev/null @@ -1,116 +0,0 @@ ---- -extends: airbnb -parserOptions: - sourceType: module - -rules: - indent: - - error - - tab - linebreak-style: - - error - - unix - quotes: - - error - - single - semi: - - error - - always - yoda: - - error - - always - curly: - - error - - multi-or-nest - - consistent - max-len: - - error - - code: 140 - - nonblock-statement-body-position: - - error - - below - implicit-arrow-linebreak: - - off - - no-tabs: - - off - no-bitwise: - - off - no-plusplus: - - off - no-mixed-operators: - - error - - allowSamePrecedence: true - no-param-reassign: - - error - - props: false - no-underscore-dangle: - - error - - allow: - - _id # mongodb identifier - - camelcase: - - off # for consts, e.g. Foo_Bar - comma-dangle: - - error - - never - default-case: - - off - - arrow-parens: - - error - - as-needed - func-names: - - error - - never - func-style: - - error - - expression - wrap-iife: - - error - - inside - - prefer-destructuring: - - error - - object: true - array: false - - valid-jsdoc: - - error - - requireReturn: false - prefer: - arg: param - argument: param - class: constructor - return: returns - preferType: - Boolean: boolean - Number: number - Object: object - String: string - - import/order: - - error - - newlines-between: never - groups: - - index - - sibling - - parent - - internal - - external - - builtin - alphabetize: - order: asc - - import/extensions: - - error - - never - import/no-absolute-path: - - error - import/no-unresolved: - - 2 - import/no-deprecated: - - error - import/named: - - error diff --git a/scripts/eslint-templates/test.eslintrc b/scripts/eslint-templates/test.eslintrc deleted file mode 100644 index a7e146518..000000000 --- a/scripts/eslint-templates/test.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ ---- -env: - mocha: true -rules: - import/no-extraneous-dependencies: - - error - - devDependencies: true diff --git a/scripts/refreshEslintConfiguration.py b/scripts/refreshEslintConfiguration.py deleted file mode 100644 index aa17597d9..000000000 --- a/scripts/refreshEslintConfiguration.py +++ /dev/null @@ -1,79 +0,0 @@ -from enum import Enum -import os -import shutil - - -TEMPLATE_DIRECTORY = os.path.join("scripts", "eslint-templates") - - -class Options(Enum): - NONE = 0 - MONGO_SUPPORT = 1 - NO_TEST = 2 - - -def mutate_file_lines(filename, mutator): - with open(filename, 'r') as input_file: - lines = input_file.readlines() - - mutator(lines) - - with open(filename, 'w') as output_file: - output_file.writelines(lines) - - -def update_eslint_src(package_name, environments): - dest_eslint_filename = os.path.join(package_name, ".eslintrc") - shutil.copy(os.path.join(TEMPLATE_DIRECTORY, "src.eslintrc"), dest_eslint_filename) - - def mutator(lines): - index = 1 - lines.insert(index, "env:\n") - for environment in environments: - index += 1 - lines.insert(index, " {0}: true\n".format(environment)) - - mutate_file_lines(dest_eslint_filename, mutator) - - -def update_eslint_test(package_name, options): - dest_eslint_filename = os.path.join(package_name, "test", ".eslintrc") - shutil.copy(os.path.join(TEMPLATE_DIRECTORY, "test.eslintrc"), dest_eslint_filename) - - if Options.MONGO_SUPPORT != options: - return - - def mutator(lines): - additional_mongo_rule_lines = [ - "", - " no-underscore-dangle:", - " - error", - " - allow:", - " - _id # mongodb identifier", - " - high_ # MongoDb.Timestamp", - " - low_ # MongoDb.Timestamp" - ] - - for line in additional_mongo_rule_lines: - lines.append('{0}\n'.format(line)) - - mutate_file_lines(dest_eslint_filename, mutator) - - -def update_eslint(package_name, environments, options=Options.NONE): - print('processing {0}...'.format(package_name)) - update_eslint_src(package_name, environments) - if Options.NO_TEST != options: - update_eslint_test(package_name, options) - - -def main(): - update_eslint("catapult-sdk", ["es6"]) - update_eslint("rest", ["es6", "node"], Options.MONGO_SUPPORT) - update_eslint("tools", ["es6", "browser"], Options.NO_TEST) - for package_name in ["monitor", "spammer"]: - update_eslint(package_name, ["es6", "node"]) - - -if __name__ == '__main__': - main() diff --git a/spammer/.eslintrc b/spammer/.eslintrc deleted file mode 100644 index b26dd9960..000000000 --- a/spammer/.eslintrc +++ /dev/null @@ -1,124 +0,0 @@ ---- -env: - es6: true - node: true -extends: airbnb -parserOptions: - sourceType: module - -rules: - indent: - - error - - tab - linebreak-style: - - error - - unix - quotes: - - error - - single - semi: - - error - - always - yoda: - - error - - always - curly: - - error - - multi-or-nest - - consistent - max-len: - - error - - code: 140 - - max-classes-per-file: - - off - prefer-object-spread: - - off - - nonblock-statement-body-position: - - error - - below - implicit-arrow-linebreak: - - off - - no-tabs: - - off - no-bitwise: - - off - no-plusplus: - - off - no-mixed-operators: - - error - - allowSamePrecedence: true - no-param-reassign: - - error - - props: false - no-underscore-dangle: - - error - - allow: - - _id # mongodb identifier - - camelcase: - - off # for consts, e.g. Foo_Bar - comma-dangle: - - error - - never - default-case: - - off - - arrow-parens: - - error - - as-needed - func-names: - - error - - never - func-style: - - error - - expression - wrap-iife: - - error - - inside - - prefer-destructuring: - - error - - object: true - array: false - - valid-jsdoc: - - error - - requireReturn: false - prefer: - arg: param - argument: param - class: constructor - return: returns - preferType: - Boolean: boolean - Number: number - Object: object - String: string - - import/order: - - error - - newlines-between: never - groups: - - index - - sibling - - parent - - internal - - external - - builtin - alphabetize: - order: asc - - import/extensions: - - error - - never - import/no-absolute-path: - - error - import/no-unresolved: - - 2 - import/no-deprecated: - - error - import/named: - - error diff --git a/spammer/package.json b/spammer/package.json deleted file mode 100644 index 9a8252642..000000000 --- a/spammer/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "catapult-api-spammer", - "version": "0.0.0", - "description": "", - "main": "src/index.js", - "scripts": { - "start": "node src/index.js", - "start:debug": "node src/index.js", - "test": "mocha --full-trace --recursive", - "test:coverage": "nyc npm test && nyc report --reporter=text-lcov", - "test:jenkins": "cross-env JUNIT_REPORT_PATH=test-results.xml mocha --reporter mocha-jenkins-reporter --forbid-only --full-trace --recursive test || exit 0", - "test:travis": "nyc npm test && nyc report --reporter=text-lcov | coveralls", - "lint": "eslint src test", - "lint:jenkins": "eslint -o tests.catapult.lint.xml -f junit src test || exit 0" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "chai": "^4.2.0", - "coveralls": "^3.1.1", - "cross-env": "^5.2.0", - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.1.0", - "eslint-plugin-import": "^2.19.1", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.19.0", - "eslint-plugin-react-hooks": "^2.5.0", - "mocha": "^9.1.0", - "mocha-jenkins-reporter": "^0.4.1", - "nyc": "^14.1.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "catapult-sdk": "link:../catapult-sdk", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.0.2", - "restify": "^8.3.3", - "winston": "^3.2.1" - } -} diff --git a/spammer/src/index.js b/spammer/src/index.js deleted file mode 100644 index 0a8c41af7..000000000 --- a/spammer/src/index.js +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const spammerUtils = require('./model/spammerUtils'); -const transactionFactory = require('./model/transactionFactory'); -const random = require('./utils/random'); -const spammerOptions = require('./utils/spammerOptions'); -const catapult = require('catapult-sdk'); -const restify = require('restify'); -const winston = require('winston'); -const crypto = require('crypto'); - -const { address } = catapult.model; -const { serialize, transactionExtensions } = catapult.modelBinary; -const modelCodec = catapult.plugins.catapultModelSystem.configure(['transfer', 'aggregate'], {}).codec; -const { uint64 } = catapult.utils; - -(() => { - const Testnet_Network = catapult.model.networkInfo.networks.testnet.id; - const options = spammerOptions.options(); - - const client = restify.createJsonClient({ - url: `http://${options.address}:${options.port}`, - connectTimeout: 1000 - }); - - const Private_Keys = [ - '8473645728B15F007385CE2889D198D26369D2806DCDED4A9B219FD0DE23A505', - 'BBC3E5BE46A953070B0B9636E386C2006DA9EA8840596B601D4A1B92A9F93330', - '46C83EE87DAB6588DD82D1059140D3E5A7FAFF78C3A0C4CE4802486D71C69E40', - 'FA19F42DDD6E757B3A2E39E75A7487F8FEC19C0E872153EC0EFD9AC2E5A84E58' - ]; - - const txCounters = { initiated: 0, successful: 0 }; - const timer = (() => { - const startTime = new Date().getTime(); - return { elapsed: () => new Date().getTime() - startTime }; - })(); - - const logStats = spammerStats => { - if (0 !== spammerStats.successful % 10) - return; - - const throughput = (spammerStats.successful * 1000 / timer.elapsed()).toFixed(2); - winston.info(`transactions successfully sent so far: ${spammerStats.successful} (${throughput} txes / s)`); - }; - - const predefinedRecipient = (() => { - const Seed_Private_Key = '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF'; - const recipients = []; - let curPrivateKey = Seed_Private_Key; - for (let i = 0; i < options.predefinedRecipients; ++i) { - const keyPair = catapult.crypto.createKeyPairFromPrivateKeyString(curPrivateKey); - curPrivateKey = catapult.utils.convert.uint8ToHex(keyPair.publicKey); - recipients.push(address.publicKeyToAddress(keyPair.publicKey, Testnet_Network)); - } - - return () => recipients[random.uint32(options.predefinedRecipients - 1)]; - })(); - - const randomRecipient = () => { - const keySize = 32; - const privateKey = crypto.randomBytes(keySize); - const keyPair = catapult.crypto.createKeyPairFromPrivateKeyString(catapult.utils.convert.uint8ToHex(privateKey)); - return address.publicKeyToAddress(keyPair.publicKey, Testnet_Network); - }; - - const pickKeyPair = (privateKeys => { - const keyPairs = privateKeys.map(privateKey => catapult.crypto.createKeyPairFromPrivateKeyString(privateKey)); - return () => keyPairs[crypto.randomBytes(1)[0] % privateKeys.length]; - })(Private_Keys); - - const createPayload = transfer => ({ payload: serialize.toHex(modelCodec, transfer) }); - - const prepareTransferTransaction = txId => { - const keyPair = pickKeyPair(); - const transfer = transactionFactory.createRandomTransfer( - { signerPublicKey: keyPair.publicKey, networkId: Testnet_Network, transferId: txId }, - 0 === options.predefinedRecipients ? randomRecipient : predefinedRecipient - ); - transactionExtensions.sign(modelCodec, keyPair, transfer); - return transfer; - }; - - const sendTransaction = createAndPrepareTransaction => new Promise(resolve => { - // don't initiate more transactions than wanted. If a send fails txCounters.initiated will be decremented - // and thus another transaction will be sent. - if (txCounters.initiated >= options.total) - return; - - ++txCounters.initiated; - const transaction = createAndPrepareTransaction(txCounters.initiated); - - const txData = createPayload(transaction); - client.put('/transaction', txData, err => { - if (err) { - winston.error(`an error occurred while sending the transaction with id ${txCounters.initiated}`, err); - --txCounters.initiated; - } else { - ++txCounters.successful; - logStats(txCounters); - } - - resolve(txCounters.successful); - }); - }); - - const randomKeyPair = () => { - const keySize = 32; - const privateKey = crypto.randomBytes(keySize); - return catapult.crypto.createKeyPairFromPrivateKeyString(catapult.utils.convert.uint8ToHex(privateKey)); - }; - - const createTransfer = (signerPublicKey, recipientAddress, transferId, amount) => { - const transfer = transactionFactory.createRandomTransfer( - { signerPublicKey, networkId: Testnet_Network, transferId }, - () => recipientAddress - ); - - transfer.mosaics[0].amount = amount; - return transfer; - }; - - const prepareAggregateTransaction = txId => { - const keyPairSender = pickKeyPair(); - const numProxies = 1 + random.uint32(5); - const keyPairs = Array.from(Array(numProxies), randomKeyPair); - keyPairs.unshift(keyPairSender); - - const addresses = keyPairs.map(keyPair => address.publicKeyToAddress(keyPair.publicKey, Testnet_Network)); - const transfers = []; - - for (let i = 0; i < numProxies; ++i) { - transfers.push(createTransfer( - keyPairs[i].publicKey, - addresses[i + 1], - txId, - uint64.fromUint(((numProxies + 1 - i) * 1000000) + random.uint32(1000000)) - )); - } - - transfers.push(createTransfer( - keyPairs[keyPairs.length - 1].publicKey, - randomRecipient(), - txId, - uint64.fromUint(random.uint32(1000000)) - )); - - const aggregate = transactionFactory.createAggregateTransaction( - { signerPublicKey: keyPairSender.publicKey, networkId: Testnet_Network }, - transfers - ); - - keyPairs.shift(); - spammerUtils.signAndStitchAggregateTransaction(modelCodec, keyPairSender, keyPairs, aggregate); - return aggregate; - }; - - if (options.help) { - winston.info(spammerOptions.usage()); - process.exit(); - } - - (() => { - const transactionFactories = { - transfer: prepareTransferTransaction, - aggregate: prepareAggregateTransaction - }; - - const mode = options.mode in transactionFactories ? options.mode : 'transfer'; - const timerId = setInterval( - () => sendTransaction(transactionFactories[mode]).then(numSuccessfulTransactions => { - if (numSuccessfulTransactions < options.total) - return; - - clearInterval(timerId); - winston.info('finished'); - process.exit(); - }), - 1000 / options.rate - ); - })(); -})(); diff --git a/spammer/src/model/spammerUtils.js b/spammer/src/model/spammerUtils.js deleted file mode 100644 index 6f2fccdf2..000000000 --- a/spammer/src/model/spammerUtils.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const catapult = require('catapult-sdk'); - -module.exports = { - signAndStitchAggregateTransaction: (codec, aggregateSignerKeyPair, keyPairs, transaction) => { - // note: signed data does not contain cosignatures because transaction does not contain them - const { transactionExtensions } = catapult.modelBinary; - transactionExtensions.sign(codec, aggregateSignerKeyPair, transaction); - const aggregateHash = transactionExtensions.hash(codec, transaction); - - if (keyPairs.find(keyPair => aggregateSignerKeyPair.publicKey === keyPair.publicKey)) - throw Error('aggregate signer public key present in list of cosigners'); - - transaction.cosignatures = keyPairs.map(keyPair => ({ - signerPublicKey: keyPair.publicKey, - signature: catapult.crypto.sign(keyPair, aggregateHash) - })); - } -}; diff --git a/spammer/src/model/transactionFactory.js b/spammer/src/model/transactionFactory.js deleted file mode 100644 index ba93e7ff6..000000000 --- a/spammer/src/model/transactionFactory.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const networkTime = require('../utils/networkTime'); -const random = require('../utils/random'); -const catapult = require('catapult-sdk'); - -const { uint64 } = catapult.utils; - -const createTransaction = (options, type) => ({ - verifiableEntityHeader_Reserved1: 0, - signature: new Uint8Array(catapult.constants.sizes.signature), - signerPublicKey: options.signerPublicKey, - entityBody_Reserved1: 0, - version: 1, - network: options.networkId, - type, - transactionsHash: new Uint8Array(catapult.constants.sizes.hash256), - aggregateTransactionHeader_Reserved1: 0, - maxFee: uint64.fromUint(0), - deadline: uint64.fromUint(networkTime.getNetworkTime() + (60 * 60 * 1000)) -}); - -module.exports = { - createRandomTransfer: (options, recipientSelector) => Object.assign(createTransaction(options, catapult.model.EntityType.transfer), { - recipientAddress: recipientSelector(), - message: Buffer.from(uint64.toHex(uint64.fromUint(options.transferId)), 'hex'), - mosaics: [ - { id: [0xD95FCF29, 0xD525AD41], amount: uint64.fromUint(random.uint32(1000000)) } - ] - }), - - createAggregateTransaction: (options, transactions) => Object.assign( - createTransaction(options, catapult.model.EntityType.aggregateComplete), - { transactions } - ) -}; diff --git a/spammer/src/utils/networkTime.js b/spammer/src/utils/networkTime.js deleted file mode 100644 index cd1b3455e..000000000 --- a/spammer/src/utils/networkTime.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -module.exports = { - // 1459468800000 is the number of milliseconds from 1970-01-01 till epoch time (2016-04-01) - getNetworkTime: () => new Date().getTime() - 1459468800000 -}; diff --git a/spammer/src/utils/random.js b/spammer/src/utils/random.js deleted file mode 100644 index 164d43d21..000000000 --- a/spammer/src/utils/random.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -module.exports = { - uint32: max => { - if (0 > max || 0xFFFFFFFF < max) - throw Error(`${max} does not fit into 32 bits`); - - return Math.floor(Math.random() * max); - } -}; diff --git a/spammer/src/utils/spammerOptions.js b/spammer/src/utils/spammerOptions.js deleted file mode 100644 index 866370a80..000000000 --- a/spammer/src/utils/spammerOptions.js +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const commandLineArgs = require('command-line-args'); -const commandLineUsage = require('command-line-usage'); - -const optionDefinitions = [ - { - name: 'help', alias: 'h', type: Boolean, defaultValue: false - }, - { - name: 'predefinedRecipients', alias: 'd', type: Number, defaultValue: 0 - }, - { - name: 'address', alias: 'a', type: String, defaultValue: '127.0.0.1' - }, - { - name: 'port', alias: 'p', type: Number, defaultValue: 3000 - }, - { - name: 'rate', alias: 'r', type: Number, defaultValue: 1 - }, - { - name: 'total', alias: 't', type: Number, defaultValue: 10 - }, - { - name: 'mode', alias: 'm', type: String, defaultValue: 'transfer' - } -]; - -const sections = [ - { - header: 'Catapult spammer', - content: 'Tool to spam a rest server with random transactions.' - }, - { - header: 'Options', - optionList: [ - { - name: 'mode', - alias: 'm', - description: 'Available spamming modes: transfer (default), aggregate' - }, - { - name: 'predefinedRecipients', - alias: 'd', - description: 'The number of predefined recipients or 0 for random recipients.' - }, - { - name: 'address', - alias: 'a', - description: 'The host ip address.' - }, - { - name: 'port', - alias: 'p', - description: 'The port on which to connect.' - }, - { - name: 'rate', - alias: 'r', - description: 'The desired transaction rate (tx / s).' - }, - { - name: 'total', - alias: 't', - description: 'The total number of transactions.' - } - ] - } -]; - -module.exports = { - options: () => commandLineArgs(optionDefinitions), - usage: () => commandLineUsage(sections) -}; diff --git a/spammer/test/.eslintrc b/spammer/test/.eslintrc deleted file mode 100644 index a7e146518..000000000 --- a/spammer/test/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ ---- -env: - mocha: true -rules: - import/no-extraneous-dependencies: - - error - - devDependencies: true diff --git a/spammer/test/model/spammerUtils_spec.js b/spammer/test/model/spammerUtils_spec.js deleted file mode 100644 index 532edd7b7..000000000 --- a/spammer/test/model/spammerUtils_spec.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const spammerUtils = require('../../src/model/spammerUtils'); -const transactionFactory = require('../../src/model/transactionFactory'); -const test = require('../testUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const createKey = catapult.crypto.createKeyPairFromPrivateKeyString; -const modelCodec = catapult.plugins.catapultModelSystem.configure(['transfer', 'aggregate'], {}).codec; - -describe('spammer utils', () => { - describe('sign and stitch aggregate transaction', () => { - const createTransaction = signer => transactionFactory.createAggregateTransaction({ - signerPublicKey: signer.publicKey, networkId: 0xA5 - }, []); - - const createRandomKey = () => createKey( - catapult.utils.convert.uint8ToHex(test.random.bytes(catapult.constants.sizes.signerPublicKey)) - ); - - it('adds expected number of cosignatures', () => { - // Arrange: - const signerPublicKey = createRandomKey(); - const cosigners = [createRandomKey(), createRandomKey()]; - const transaction = createTransaction(signerPublicKey); - - // Sanity: - expect(transaction.cosignatures).to.equal(undefined); - - // Act: - spammerUtils.signAndStitchAggregateTransaction(modelCodec, signerPublicKey, cosigners, transaction); - - // Assert: - expect(transaction.cosignatures.length).to.equal(cosigners.length); - cosigners.forEach((keyPair, i) => { - expect(keyPair.publicKey).to.deep.equal(transaction.cosignatures[i].signerPublicKey); - }); - }); - - it('throws if signer key is in cosigners', () => { - // Arrange: - const signerPublicKey = createRandomKey(); - const cosigners = [createRandomKey(), signerPublicKey, createRandomKey()]; - const transaction = createTransaction(signerPublicKey); - - // Act: - expect(() => spammerUtils.signAndStitchAggregateTransaction(modelCodec, signerPublicKey, cosigners, transaction)) - .to.throw('aggregate signer public key present in list of cosigners'); - }); - }); -}); diff --git a/spammer/test/model/transactionFactory_spec.js b/spammer/test/model/transactionFactory_spec.js deleted file mode 100644 index 972f5ce0b..000000000 --- a/spammer/test/model/transactionFactory_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const transactionFactory = require('../../src/model/transactionFactory'); -const networkTime = require('../../src/utils/networkTime'); -const test = require('../testUtils'); -const catapult = require('catapult-sdk'); -const { expect } = require('chai'); - -const Signature_Size = catapult.constants.sizes.signature; -const Address_Decoded_Size = catapult.constants.sizes.addressDecoded; -const createKey = catapult.crypto.createKeyPairFromPrivateKeyString; - -describe('transaction factory', () => { - const Private_Key = '8D31B712AB28D49591EAF5066E9E967B44507FC19C3D54D742F7B3A255CFF4AB'; - const Testnet_Network = catapult.model.networkInfo.networks.testnet.id; - - const assertTransactionData = (transaction, keyPair, version, type) => { - const txDeadline = catapult.utils.uint64.compact(transaction.deadline); - expect(transaction.signerPublicKey).to.deep.equal(keyPair.publicKey); - expect(transaction.signature).to.deep.equal(new Uint8Array(Signature_Size)); - expect(transaction.version).to.equal(version); - expect(transaction.type).to.equal(type); - expect(transaction.maxFee).to.deep.equal([0x00, 0x00]); - expect(txDeadline).to.be.at.least(networkTime.getNetworkTime()); - expect(txDeadline).to.be.at.most(networkTime.getNetworkTime() + (24 * 60 * 60 * 1000)); - }; - - describe('random transfer', () => { - it('can be created with reasonable data', () => { - // Arrange: - const keyPair = createKey(Private_Key); - const recipientAddress = test.random.bytes(Address_Decoded_Size); - - // Act: - const transaction = transactionFactory.createRandomTransfer( - { signerPublicKey: keyPair.publicKey, networkId: Testnet_Network, transferId: 0x1234 }, - () => recipientAddress - ); - - // Assert: - assertTransactionData(transaction, keyPair, 1, 0x4154); - expect(transaction.recipientAddress).to.deep.equal(recipientAddress); - expect(transaction.message).to.deep.equal(Buffer.of(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34)); - expect(transaction.mosaics[0].id).to.deep.equal([0xD95FCF29, 0xD525AD41]); - }); - }); - - describe('aggregate transaction', () => { - it('can be created with reasonable data', () => { - // Arrange: - const keyPair = createKey(Private_Key); - const transactions = [1, 2, 3]; - - // Act: - const transaction = transactionFactory.createAggregateTransaction( - { signerPublicKey: keyPair.publicKey, networkId: 0xA5 }, - transactions - ); - - // Assert: - assertTransactionData(transaction, keyPair, 1, 0x4141); - expect(transaction.transactions).to.equal(transactions); - expect(transactions.cosignatures).to.equal(undefined); - }); - }); -}); diff --git a/spammer/test/testUtils.js b/spammer/test/testUtils.js deleted file mode 100644 index e81b27fa4..000000000 --- a/spammer/test/testUtils.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const crypto = require('crypto'); - -module.exports = { - random: { - bytes: size => crypto.randomBytes(size) - }, - - buffer: { - fromSize: size => { - const buffer = Buffer.allocUnsafe(4); - buffer.writeUInt32LE(size); - return buffer; - } - } -}; diff --git a/spammer/test/utils/networkTime_spec.js b/spammer/test/utils/networkTime_spec.js deleted file mode 100644 index a98688925..000000000 --- a/spammer/test/utils/networkTime_spec.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const networkTime = require('../../src/utils/networkTime'); -const { expect } = require('chai'); - -describe('network time', () => { - it('is positive', () => { - // Act: - const time = networkTime.getNetworkTime(); - - // Assert: - expect(time).to.be.at.least(1); - }); - - it('is increasing', () => { - // Arrange: - const time1 = networkTime.getNetworkTime(); - - // Act: - setTimeout(() => { - const time2 = networkTime.getNetworkTime(); - - // Assert: - expect(time1).to.be.below(time2); - }, 10); - }); -}); diff --git a/spammer/test/utils/random_spec.js b/spammer/test/utils/random_spec.js deleted file mode 100644 index 0d55b08bf..000000000 --- a/spammer/test/utils/random_spec.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -const random = require('../../src/utils/random'); -const { expect } = require('chai'); - -describe('random', () => { - const bigNumbers = [0x0100000000, 0x0100000001, 0x123456789, Number.MAX_SAFE_INTEGER]; - - describe('uint32', () => { - it('respects limits', () => { - // Arrange: - const max = 1234; - const values = []; - - // Act: - for (let i = 0; 10 > i; ++i) - values.push(random.uint32(max)); - - // Assert: - values.forEach(value => { - expect(value).to.be.within(0, max); - }); - }); - - it('accepts max uint32', () => { - // Arrange: - const max = 0xFFFFFFFF; - - // Act: - const value = random.uint32(max); - - // Assert: - expect(value).to.be.within(0, max); - }); - - it('throws if param does not fit into 32 bit', () => { - // Assert: - bigNumbers.forEach(value => { - expect(() => { random.uint32(value); }, `${value} is too large`).to.throw(`${value} does not fit into 32 bits`); - }); - }); - }); -}); diff --git a/spammer/yarn.lock b/spammer/yarn.lock deleted file mode 100644 index b0e15b7e3..000000000 --- a/spammer/yarn.lock +++ /dev/null @@ -1,3634 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/generator@^7.15.4", "@babel/generator@^7.4.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.4.tgz#85acb159a267ca6324f9793986991ee2022a05b0" - integrity sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw== - dependencies: - "@babel/types" "^7.15.4" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-function-name@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" - integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== - dependencies: - "@babel/helper-get-function-arity" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/helper-get-function-arity@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" - integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-hoist-variables@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" - integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-split-export-declaration@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" - integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.15.4", "@babel/parser@^7.4.3": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae" - integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g== - -"@babel/runtime-corejs3@^7.10.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz#403139af262b9a6e8f9ba04a6fdcebf8de692bf1" - integrity sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg== - dependencies: - core-js-pure "^3.16.0" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.15.4", "@babel/template@^7.4.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" - integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/traverse@^7.4.3": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" - integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.15.4", "@babel/types@^7.4.0": - version "7.15.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" - integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== - dependencies: - "@babel/helper-validator-identifier" "^7.14.9" - to-fast-properties "^2.0.0" - -"@dabh/diagnostics@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" - integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== - dependencies: - colorspace "1.1.x" - enabled "2.0.x" - kuler "^2.0.0" - -"@netflix/nerror@^1.0.0": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@netflix/nerror/-/nerror-1.1.3.tgz#9d88eccca442f1d544f2761d15ea557dc0a44ed2" - integrity sha512-b+MGNyP9/LXkapreJzNUzcvuzZslj/RGgdVVJ16P2wSlYatfLycPObImqVJSmNAdyeShvNeM/pl3sVZsObFueg== - dependencies: - assert-plus "^1.0.0" - extsprintf "^1.4.0" - lodash "^4.17.15" - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -acorn-jsx@^5.2.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== - dependencies: - default-require-extensions "^2.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -array-includes@^3.1.1, array-includes@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array.prototype.flat@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" - integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -array.prototype.flatmap@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" - integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" - integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -axe-core@^4.0.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" - integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -bunyan@^1.8.12: - version "1.8.15" - resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" - integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== - optionalDependencies: - dtrace-provider "~0.8" - moment "^2.19.3" - mv "~2" - safe-json-stringify "~1" - -caching-transform@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-3.0.2.tgz#601d46b91eca87687a281e71cef99791b0efca70" - integrity sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w== - dependencies: - hasha "^3.0.0" - make-dir "^2.0.0" - package-hash "^3.0.0" - write-file-atomic "^2.4.2" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -"catapult-sdk@link:../catapult-sdk": - version "0.0.0" - uid "" - -chai@^4.2.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312" - integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-line-args@^5.1.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.0.tgz#087b02748272169741f1fd7c785b295df079b9be" - integrity sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.0.2: - version "6.1.1" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.1.tgz#c908e28686108917758a49f45efb4f02f76bc03f" - integrity sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA== - dependencies: - array-back "^4.0.1" - chalk "^2.4.2" - table-layout "^1.0.1" - typical "^5.2.0" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -confusing-browser-globals@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" - integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== - -convert-source-map@^1.6.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -core-js-pure@^3.16.0: - version "3.18.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.1.tgz#097d34d24484be45cea700a448d1e74622646c80" - integrity sha512-kmW/k8MaSuqpvA1xm2l3TVlBuvW+XBkcaOroFUpO3D4lsTGQWBTb/tBDCf/PNkkPLrwgrkQRIYNPB0CeqGJWGQ== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -coveralls@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.1.tgz#f5d4431d8b5ae69c5079c8f8ca00d64ac77cf081" - integrity sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww== - dependencies: - js-yaml "^3.13.1" - lcov-parse "^1.0.0" - log-driver "^1.2.7" - minimist "^1.2.5" - request "^2.88.2" - -cp-file@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.2.0.tgz#40d5ea4a1def2a9acdd07ba5c0b0246ef73dc10d" - integrity sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA== - dependencies: - graceful-fs "^4.1.2" - make-dir "^2.0.0" - nested-error-stacks "^2.0.0" - pify "^4.0.1" - safe-buffer "^5.0.1" - -cross-env@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d" - integrity sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ== - dependencies: - cross-spawn "^6.0.5" - -cross-spawn@^4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -csv-generate@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.4.3.tgz#bc42d943b45aea52afa896874291da4b9108ffff" - integrity sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw== - -csv-parse@^4.16.3: - version "4.16.3" - resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.16.3.tgz#7ca624d517212ebc520a36873c3478fa66efbaf7" - integrity sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg== - -csv-stringify@^5.6.5: - version "5.6.5" - resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.5.tgz#c6d74badda4b49a79bf4e72f91cce1e33b94de00" - integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== - -csv@^5.1.1: - version "5.5.3" - resolved "https://registry.yarnpkg.com/csv/-/csv-5.5.3.tgz#cd26c1e45eae00ce6a9b7b27dcb94955ec95207d" - integrity sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g== - dependencies: - csv-generate "^3.4.3" - csv-parse "^4.16.3" - csv-stringify "^5.6.5" - stream-transform "^2.1.3" - -damerau-levenshtein@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" - integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4.3.2, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -diff@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dtrace-provider@^0.8.1, dtrace-provider@~0.8: - version "0.8.8" - resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" - integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== - dependencies: - nan "^2.14.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.0.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -enabled@2.0.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" - integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-regexp-component@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz#9c63b6d0b25ff2a88c3adbd18c5b61acc3b9faa2" - integrity sha1-nGO20LJf8qiMOtvRjFthrMO5+qI= - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-airbnb-base@^14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" - integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-config-airbnb@^18.1.0: - version "18.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9" - integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== - dependencies: - eslint-config-airbnb-base "^14.2.1" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== - dependencies: - debug "^3.2.7" - pkg-dir "^2.0.0" - -eslint-plugin-import@^2.19.1: - version "2.24.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" - integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== - dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" - has "^1.0.3" - is-core-module "^2.6.0" - minimatch "^3.0.4" - object.values "^1.1.4" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" - resolve "^1.20.0" - tsconfig-paths "^3.11.0" - -eslint-plugin-jsx-a11y@^6.2.3: - version "6.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" - integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== - dependencies: - "@babel/runtime" "^7.11.2" - aria-query "^4.2.2" - array-includes "^3.1.1" - ast-types-flow "^0.0.7" - axe-core "^4.0.2" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.6" - emoji-regex "^9.0.0" - has "^1.0.3" - jsx-ast-utils "^3.1.0" - language-tags "^1.0.5" - -eslint-plugin-react-hooks@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0" - integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g== - -eslint-plugin-react@^7.19.0: - version "7.26.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e" - integrity sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ== - dependencies: - array-includes "^3.1.3" - array.prototype.flatmap "^1.2.4" - doctrine "^2.1.0" - estraverse "^5.2.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.0.4" - object.entries "^1.1.4" - object.fromentries "^2.0.4" - object.hasown "^1.0.0" - object.values "^1.1.4" - prop-types "^15.7.2" - resolve "^2.0.0-next.3" - semver "^6.3.0" - string.prototype.matchall "^4.0.5" - -eslint-scope@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== - dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -ewma@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ewma/-/ewma-2.0.1.tgz#9876c1c491ac5733c8666001a3961a04c97cf1e8" - integrity sha512-MYYK17A76cuuyvkR7MnqLW4iFYPEi5Isl2qb8rXiWpLiwFS9dxW/rncuNnjjgSENuVqZQkIuR4+DChVL4g1lnw== - dependencies: - assert-plus "^1.0.0" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0, extsprintf@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-decode-uri-component@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" - integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fecha@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" - integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-my-way@^2.0.1: - version "2.2.5" - resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-2.2.5.tgz#86ce825266fa28cd962e538a45ec2aaa84c3d514" - integrity sha512-GjRZZlGcGmTh9t+6Xrj5K0YprpoAFCAiCPgmAH9Kb09O4oX6hYuckDfnDipYj+Q7B1GtYWSzDI5HEecNYscLQg== - dependencies: - fast-decode-uri-component "^1.0.0" - safe-regex2 "^2.0.0" - semver-store "^0.3.0" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -fn.name@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" - integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== - -foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -formidable@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" - integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^6.0.1: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hasha@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" - integrity sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk= - dependencies: - is-stream "^1.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-signature@^1.2.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.5.tgz#9f19496ffbf3227298d7b5f156e0e1a948678683" - integrity sha512-NwoTQYSJoFt34jSBbwzDHDofoA61NGXzu6wXh95o1Ry62EnmKjXb/nR/RknLeZ3G/uGwrlKNY2z7uPt+Cdl7Tw== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.14.1" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -import-fresh@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-core-module@^2.2.0, is-core-module@^2.6.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - -is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== - dependencies: - call-bind "^1.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== - -istanbul-lib-hook@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz#c95695f383d4f8f60df1f04252a9550e15b5b133" - integrity sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA== - dependencies: - append-transform "^1.0.0" - -istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" - -istanbul-lib-report@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== - dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" - -istanbul-lib-source-maps@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" - source-map "^0.6.1" - -istanbul-reports@^2.2.4: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== - dependencies: - html-escaper "^2.0.0" - -js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" - integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== - dependencies: - array-includes "^3.1.3" - object.assign "^4.1.2" - -kuler@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" - integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== - -language-subtag-registry@~0.3.2: - version "0.3.21" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" - integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= - dependencies: - language-subtag-registry "~0.3.2" - -lcov-parse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" - integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-driver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" - integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -logform@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.0.tgz#a3997a05985de2ebd325ae0d166dffc9c6fe6b57" - integrity sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ== - dependencies: - colors "^1.2.1" - fecha "^4.2.0" - ms "^2.1.1" - safe-stable-stringify "^1.1.0" - triple-beam "^1.3.0" - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - -mime-db@1.50.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== - dependencies: - mime-db "1.50.0" - -mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== - -mime@^2.4.3: - version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mixme@^0.5.1: - version "0.5.4" - resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.5.4.tgz#8cb3bd0cd32a513c161bf1ca99d143f0bcf2eff3" - integrity sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw== - -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha-jenkins-reporter@^0.4.1: - version "0.4.7" - resolved "https://registry.yarnpkg.com/mocha-jenkins-reporter/-/mocha-jenkins-reporter-0.4.7.tgz#59505d59a9fdeb64ee8270f13d8ca6c48c1dfad7" - integrity sha512-ek05WBoGX9G5B29QmFw67H92ZcvZcp62RASaHWqiZOWjc/G2YlKBeu7t60J5wpaQP1rFS8T9S85ed/3iDdf/2A== - dependencies: - diff "4.0.1" - mkdirp "^0.5.4" - xml "^1.0.1" - -mocha@^9.1.0: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -moment@^2.19.3: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -mv@~2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" - integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= - dependencies: - mkdirp "~0.5.1" - ncp "~2.0.0" - rimraf "~2.4.0" - -nan@^2.14.0: - version "2.15.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" - integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== - -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -ncp@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" - integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= - -negotiator@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -nested-error-stacks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" - integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -nyc@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-14.1.1.tgz#151d64a6a9f9f5908a1b73233931e4a0a3075eeb" - integrity sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw== - dependencies: - archy "^1.0.0" - caching-transform "^3.0.2" - convert-source-map "^1.6.0" - cp-file "^6.2.0" - find-cache-dir "^2.1.0" - find-up "^3.0.0" - foreground-child "^1.5.6" - glob "^7.1.3" - istanbul-lib-coverage "^2.0.5" - istanbul-lib-hook "^2.0.7" - istanbul-lib-instrument "^3.3.0" - istanbul-lib-report "^2.0.8" - istanbul-lib-source-maps "^3.0.6" - istanbul-reports "^2.2.4" - js-yaml "^3.13.1" - make-dir "^2.1.0" - merge-source-map "^1.1.0" - resolve-from "^4.0.0" - rimraf "^2.6.3" - signal-exit "^3.0.2" - spawn-wrap "^1.4.2" - test-exclude "^5.2.3" - uuid "^3.3.2" - yargs "^13.2.2" - yargs-parser "^13.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.entries@^1.1.2, object.entries@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.fromentries@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.hasown@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" - integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.values@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -one-time@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" - integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== - dependencies: - fn.name "1.x.x" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-hash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e" - integrity sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA== - dependencies: - graceful-fs "^4.1.15" - hasha "^3.0.0" - lodash.flattendeep "^4.4.0" - release-zalgo "^1.0.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pidusage@^2.0.17: - version "2.0.21" - resolved "https://registry.yarnpkg.com/pidusage/-/pidusage-2.0.21.tgz#7068967b3d952baea73e57668c98b9eaa876894e" - integrity sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA== - dependencies: - safe-buffer "^5.2.1" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@^6.7.0: - version "6.10.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" - integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== - dependencies: - side-channel "^1.0.4" - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@~1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -readable-stream@^2.0.1, readable-stream@^2.3.7: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexp.prototype.flags@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= - dependencies: - es6-error "^4.0.1" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.10.0, resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -resolve@^2.0.0-next.3: - version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" - integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -restify-errors@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/restify-errors/-/restify-errors-8.0.2.tgz#0b9678738e37888e4fefe52aa6ee92771ec954e9" - integrity sha512-UsXUVQo7M26xoQzeUcZQ0+H8L2t9DGzrXcAgR3WB/1vnbl+UdI4tZ1PqYsN+sS5WnqHKZ0Xy9w0CKf83bbrwYA== - dependencies: - "@netflix/nerror" "^1.0.0" - assert-plus "^1.0.0" - lodash "^4.17.15" - optionalDependencies: - safe-json-stringify "^1.0.4" - -restify@^8.3.3: - version "8.6.0" - resolved "https://registry.yarnpkg.com/restify/-/restify-8.6.0.tgz#b2a9a32b68160d4f352c71d7b4e63dd3e76f46e9" - integrity sha512-vLorgPD6j6bqmBqsBjKHa12c963jYESjJ2MOKK/+9nVlS7if/yl5GJ4/Vvty8qHecCtA2vZ3uejlczL+cv2mmg== - dependencies: - assert-plus "^1.0.0" - bunyan "^1.8.12" - csv "^5.1.1" - escape-regexp-component "^1.0.2" - ewma "^2.0.1" - find-my-way "^2.0.1" - formidable "^1.2.1" - http-signature "^1.2.0" - lodash "^4.17.11" - lru-cache "^5.1.1" - mime "^2.4.3" - negotiator "^0.6.2" - once "^1.4.0" - pidusage "^2.0.17" - qs "^6.7.0" - restify-errors "^8.0.2" - semver "^6.1.1" - send "^0.16.2" - spdy "^4.0.0" - uuid "^3.3.2" - vasync "^2.2.0" - optionalDependencies: - dtrace-provider "^0.8.1" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.2.2.tgz#b6861782a1f4762dce43402a71eb7a283f44573c" - integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ== - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.6.2, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@~2.4.0: - version "2.4.5" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" - integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= - dependencies: - glob "^6.0.1" - -ripemd160@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -rxjs@^6.6.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-json-stringify@^1.0.4, safe-json-stringify@~1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" - integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== - -safe-regex2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-2.0.0.tgz#b287524c397c7a2994470367e0185e1916b1f5b9" - integrity sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ== - dependencies: - ret "~0.2.0" - -safe-stable-stringify@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a" - integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw== - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -semver-store@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9" - integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg== - -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -send@^0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.4.0" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spawn-wrap@^1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.3.tgz#81b7670e170cca247d80bf5faf0cfb713bdcf848" - integrity sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw== - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.6.2" - signal-exit "^3.0.2" - which "^1.3.0" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" - integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.14.1, sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -statuses@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== - -stream-transform@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-2.1.3.tgz#a1c3ecd72ddbf500aa8d342b0b9df38f5aa598e3" - integrity sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ== - dependencies: - mixme "^0.5.1" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.matchall@^4.0.5: - version "4.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" - integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.3.1" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-json-comments@3.1.1, strip-json-comments@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -table-layout@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" - -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== - -tsconfig-paths@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" - integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -tweetnacl@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vasync@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/vasync/-/vasync-2.2.0.tgz#cfde751860a15822db3b132bc59b116a4adaf01b" - integrity sha1-z951GGChWCLbOxMrxZsRakra8Bs= - dependencies: - verror "1.10.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.2.9, which@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -winston-transport@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== - dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" - -winston@^3.2.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== - dependencies: - "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" - is-stream "^2.0.0" - logform "^2.2.0" - one-time "^1.0.0" - readable-stream "^3.4.0" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.4.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" - -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^2.4.2: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^13.0.0, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^13.2.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/tools/.eslintrc b/tools/.eslintrc deleted file mode 100644 index 92a534dd9..000000000 --- a/tools/.eslintrc +++ /dev/null @@ -1,124 +0,0 @@ ---- -env: - es6: true - browser: true -extends: airbnb -parserOptions: - sourceType: module - -rules: - indent: - - error - - tab - linebreak-style: - - error - - unix - quotes: - - error - - single - semi: - - error - - always - yoda: - - error - - always - curly: - - error - - multi-or-nest - - consistent - max-len: - - error - - code: 140 - - max-classes-per-file: - - off - prefer-object-spread: - - off - - nonblock-statement-body-position: - - error - - below - implicit-arrow-linebreak: - - off - - no-tabs: - - off - no-bitwise: - - off - no-plusplus: - - off - no-mixed-operators: - - error - - allowSamePrecedence: true - no-param-reassign: - - error - - props: false - no-underscore-dangle: - - error - - allow: - - _id # mongodb identifier - - camelcase: - - off # for consts, e.g. Foo_Bar - comma-dangle: - - error - - never - default-case: - - off - - arrow-parens: - - error - - as-needed - func-names: - - error - - never - func-style: - - error - - expression - wrap-iife: - - error - - inside - - prefer-destructuring: - - error - - object: true - array: false - - valid-jsdoc: - - error - - requireReturn: false - prefer: - arg: param - argument: param - class: constructor - return: returns - preferType: - Boolean: boolean - Number: number - Object: object - String: string - - import/order: - - error - - newlines-between: never - groups: - - index - - sibling - - parent - - internal - - external - - builtin - alphabetize: - order: asc - - import/extensions: - - error - - never - import/no-absolute-path: - - error - import/no-unresolved: - - 2 - import/no-deprecated: - - error - import/named: - - error diff --git a/tools/package.json b/tools/package.json deleted file mode 100644 index 479bc9cbb..000000000 --- a/tools/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "catapult-api-tools", - "version": "1.0.0", - "description": "", - "main": "", - "scripts": { - "test:jenkins": "echo \"test is not supported\"", - "lint": "eslint websocket", - "lint:jenkins": "eslint -o tests.catapult.lint.xml -f junit websocket || exit 0" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.1.0", - "eslint-plugin-import": "^2.19.1", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.19.0", - "eslint-plugin-react-hooks": "^2.5.0" - }, - "dependencies": {} -} diff --git a/tools/websocket/.eslintrc b/tools/websocket/.eslintrc deleted file mode 100644 index fbb7df5de..000000000 --- a/tools/websocket/.eslintrc +++ /dev/null @@ -1,4 +0,0 @@ ---- -globals: - bigInt: true - Vue: true diff --git a/tools/websocket/client.html b/tools/websocket/client.html deleted file mode 100644 index 1457fd1a0..000000000 --- a/tools/websocket/client.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - WebSocket Test Harness - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - diff --git a/tools/websocket/client.js b/tools/websocket/client.js deleted file mode 100644 index 0266b29b8..000000000 --- a/tools/websocket/client.js +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2016-2019, Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. - * Copyright (c) 2020-present, Jaguar0625, gimre, BloodyRookie. - * All rights reserved. - * - * This file is part of Catapult. - * - * Catapult is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Catapult is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Catapult. If not, see . - */ - -// eslint no-new workaround -Vue.create = options => new Vue(options); - -Vue.component('subscription-group-item', { - template: '#subscription-group-item-template', - props: ['group'], - methods: { - remove(subscription) { - this.$emit('remove', subscription.index); - } - } -}); - -Vue.component('subscription-groups-control', { - template: '#subscription-groups-control-template', - props: ['groups'], - methods: { - remove(index) { - this.$emit('remove', index); - } - } -}); - -Vue.component('text-or-select-control', { - template: '#text-or-select-control-template', - props: ['value', 'options'], - methods: { - updateValue(value) { - this.$emit('input', value); - } - } -}); - -Vue.component('subscription-selection-control', { - template: '#subscription-selection-control-template', - data: () => ({ - allChannels: [ - 'block', - 'confirmedAdded', 'unconfirmedAdded', 'unconfirmedRemoved', 'status', - 'partialAdded', 'partialRemoved', 'cosignature' - ], - wellKnownAddresses: [ - { name: 'host4', value: 'SAAAIBC7AM65HOFDLYGFUT46H44TROZ7MUWCW6I' }, - { name: 'host5', value: 'SAAA57DREOPYKUFX4OG7IQXKITMBWKD6KXTVBBQ' }, - { name: 'host6', value: 'SAAA467G4ZDNOEGLNXLGWUAXZKC6VAES74J7N3Y' }, - { name: 'host7', value: 'SAAAMZYSPE5TRAVH7I3VSF7ZD542EVDLB7JT7ZY' }, - - { name: 'BloodyRookie', value: 'SAAAZY5C3L6ONXRAPH2WYAPC3FKYFIPBBPFMLAQ' }, - { name: 'Jaguar0625', value: 'SDALCF7EXRBX2FH4ZJUKYA334MZJVB2TOAE5OKY' }, - { name: 'gimre', value: 'SAAA66EEZKK3HGBRV57E6TOK335NK22BF2KGOEA' } - ], - - address: 'SAAAIBC7AM65HOFDLYGFUT46H44TROZ7MUWCW6I', // host4 - selectedChannels: ['block'], - - subscriptions: [] - }), - computed: { - channelInfos() { - return this.allChannels.map(channel => ({ - name: channel, active: this.isSelected(channel), disabled: !this.canSubscribe(channel) - })); - }, - subscriptionGroups() { - const subscriptionGroups = {}; - - this.subscriptions.forEach((subscription, index) => { - // move all that are not address-dependent into 'global' group - const group = subscription.channel === subscription.fullChannelPath ? 'global' : subscription.address; - if (!(group in subscriptionGroups)) - subscriptionGroups[group] = { name: group, subscriptions: [] }; - - subscriptionGroups[group].subscriptions.push({ channel: subscription.channel, index }); - }); - - return subscriptionGroups; - } - }, - methods: { - fullChannelPath(channel) { - return 'block' === channel ? 'block' : `${channel}/${this.address}`; - }, - isSelected(channel) { - return this.selectedChannels.includes(channel); - }, - canSubscribe(channel) { - const fullChannelPath = this.fullChannelPath(channel); - return this.subscriptions.every(subscription => fullChannelPath !== subscription.fullChannelPath); - }, - subscribe() { - this.selectedChannels.forEach(channel => { - if (!this.canSubscribe(channel)) - throw Error(`cannot subscribe to selected channel ${channel}`); - - const fullChannelPath = this.fullChannelPath(channel); - this.subscriptions.push({ fullChannelPath, address: this.address, channel }); - this.$emit('message', 'subscribe', fullChannelPath); - }); - - // subscriptions have been made to all selected channels, so they can be unselected - this.selectedChannels.splice(0, this.selectedChannels.length); - }, - unsubscribe(index) { - const subscription = this.subscriptions[index]; - this.subscriptions.splice(index, 1); - this.$emit('message', 'unsubscribe', subscription.fullChannelPath); - } - } -}); - -Vue.component('web-socket-connection-control', { - template: '#web-socket-connection-control-template', - data: () => ({ - wellKnownHosts: [ - { name: 'host1', value: 'set-proper-hostname' }, - { name: 'host2', value: 'set-proper-hostname' }, - { name: 'host3', value: 'set-proper-hostname' }, - { name: 'host4', value: 'set-proper-hostname' }, - { name: 'Localhost', value: 'localhost' } - ], - - canConnect: true, - - host: 'set-proper-hostname', - - uid: '', - wsConnection: undefined - }), - computed: { - wsHost() { - return `ws://${this.host}:3000/ws`; - } - }, - methods: { - connect() { - this.canConnect = false; - - this.wsConnection = new WebSocket(this.wsHost); - this.wsConnection.onopen = () => { - this.raiseStatus({ level: 'info', type: 'websocket', message: 'connected' }); - }; - this.wsConnection.onmessage = e => { - const json = JSON.parse(e.data); - if ('uid' in json) { - this.uid = json.uid; - this.raiseStatus({ level: 'info', type: 'websocket', message: `negotiated uid ${this.uid}` }); - } else { - this.raiseStatus({ level: 'info', type: 'message', message: json }); - } - }; - this.wsConnection.onerror = () => { - this.raiseStatus({ level: 'danger', type: 'websocket', message: 'encountered error' }); - }; - this.wsConnection.onclose = e => { - this.raiseStatus({ level: 'warning', type: 'websocket', message: `closed with code ${e.code}` }); - this.reset(); - }; - }, - disconnect() { - this.wsConnection.close(); - }, - sendMessage(action, channel) { - this.raiseStatus({ level: 'light', type: 'subscription', message: { action, channel } }); - this.wsConnection.send(JSON.stringify({ uid: this.uid, [action]: channel })); - }, - reset() { - this.uid = ''; - this.canConnect = true; - }, - raiseStatus(data) { - // augment with host - data.host = this.wsHost; - this.$emit('message', data); - } - } -}); - -Vue.component('status-messages-panel', { - template: '#status-messages-panel-template', - props: ['messages'] -}); - -const formatTimestamp = date => { - const formatUnit = (unit, len = 2) => date[`get${unit}`]().toString().padStart(len, '0'); - return `${formatUnit('Hours')}:${formatUnit('Minutes')}:${formatUnit('Seconds')}.${formatUnit('Milliseconds', 3)}`; -}; - -const formatUint64 = value => bigInt(value[1]).shiftLeft(32).add(value[0]).toString(); - -Vue.component('web-socket-control', { - template: '#web-socket-control-template', - props: ['name'], - data: () => ({ - messages: [] - }), - methods: { - addMessage(data) { - let formattedData = {}; - - if ('subscription' === data.type) { - const message = `sending ${data.message.action} message for channel ${data.message.channel.replace('/', ' / ')}`; - formattedData = { message }; - } else if ('message' === data.type) { - if ('block' in data.message) { - const message = `block received with height ${formatUint64(data.message.block.height)}`; - formattedData = { level: 'light', message }; - } else { - const message = `received unknown data with key(s): ${Object.keys(data.message)}`; - formattedData = { level: 'warning', message }; - } - } - - const timestamp = formatTimestamp(new Date()); - this.messages.unshift(Object.assign({ timestamp }, data, formattedData)); - - const maxMessages = 100; - if (maxMessages < this.messages.length) - this.messages.splice(maxMessages, this.messages.length - maxMessages); - } - } -}); - -Vue.create({ - el: '#app' -}); diff --git a/tools/yarn.lock b/tools/yarn.lock deleted file mode 100644 index 8a3966cef..000000000 --- a/tools/yarn.lock +++ /dev/null @@ -1,1656 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/runtime-corejs3@^7.10.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz#403139af262b9a6e8f9ba04a6fdcebf8de692bf1" - integrity sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg== - dependencies: - core-js-pure "^3.16.0" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== - dependencies: - regenerator-runtime "^0.13.4" - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -acorn-jsx@^5.2.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -ajv@^6.10.0, ajv@^6.10.2: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - -array-includes@^3.1.1, array-includes@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array.prototype.flat@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" - integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -array.prototype.flatmap@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" - integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -axe-core@^4.0.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" - integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -chalk@^2.0.0, chalk@^2.1.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -confusing-browser-globals@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" - integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== - -core-js-pure@^3.16.0: - version "3.18.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.1.tgz#097d34d24484be45cea700a448d1e74622646c80" - integrity sha512-kmW/k8MaSuqpvA1xm2l3TVlBuvW+XBkcaOroFUpO3D4lsTGQWBTb/tBDCf/PNkkPLrwgrkQRIYNPB0CeqGJWGQ== - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -damerau-levenshtein@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" - integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.0.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-airbnb-base@^14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" - integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-config-airbnb@^18.1.0: - version "18.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9" - integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== - dependencies: - eslint-config-airbnb-base "^14.2.1" - object.assign "^4.1.2" - object.entries "^1.1.2" - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== - dependencies: - debug "^3.2.7" - pkg-dir "^2.0.0" - -eslint-plugin-import@^2.19.1: - version "2.24.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" - integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== - dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" - has "^1.0.3" - is-core-module "^2.6.0" - minimatch "^3.0.4" - object.values "^1.1.4" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" - resolve "^1.20.0" - tsconfig-paths "^3.11.0" - -eslint-plugin-jsx-a11y@^6.2.3: - version "6.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" - integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== - dependencies: - "@babel/runtime" "^7.11.2" - aria-query "^4.2.2" - array-includes "^3.1.1" - ast-types-flow "^0.0.7" - axe-core "^4.0.2" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.6" - emoji-regex "^9.0.0" - has "^1.0.3" - jsx-ast-utils "^3.1.0" - language-tags "^1.0.5" - -eslint-plugin-react-hooks@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0" - integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g== - -eslint-plugin-react@^7.19.0: - version "7.26.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e" - integrity sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ== - dependencies: - array-includes "^3.1.3" - array.prototype.flatmap "^1.2.4" - doctrine "^2.1.0" - estraverse "^5.2.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.0.4" - object.entries "^1.1.4" - object.fromentries "^2.0.4" - object.hasown "^1.0.0" - object.values "^1.1.4" - prop-types "^15.7.2" - resolve "^2.0.0-next.3" - semver "^6.3.0" - string.prototype.matchall "^4.0.5" - -eslint-scope@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== - dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -glob-parent@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.3: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -graceful-fs@^4.1.2: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -import-fresh@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-core-module@^2.2.0, is-core-module@^2.6.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== - dependencies: - call-bind "^1.0.0" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" - integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== - dependencies: - array-includes "^3.1.3" - object.assign "^4.1.2" - -language-subtag-registry@~0.3.2: - version "0.3.21" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" - integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= - dependencies: - language-subtag-registry "~0.3.2" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash@^4.17.14, lodash@^4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.entries@^1.1.2, object.entries@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.fromentries@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.hasown@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" - integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.values@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexp.prototype.flags@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.10.0, resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -resolve@^2.0.0-next.3: - version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" - integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -rxjs@^6.6.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -"semver@2 || 3 || 4 || 5", semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" - integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.matchall@^4.0.5: - version "4.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" - integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.3.1" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-json-comments@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tsconfig-paths@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" - integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" diff --git a/travis b/travis deleted file mode 160000 index 522f452e1..000000000 --- a/travis +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 522f452e19332bdea3c1d7823c7d8b1fda70ee16 diff --git a/version.txt b/version.txt deleted file mode 100644 index 005119baa..000000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -2.4.1 diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fb57ccd13..000000000 --- a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - diff --git a/yarn_setup.sh b/yarn_setup.sh deleted file mode 100755 index 74ab6b360..000000000 --- a/yarn_setup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# install servers -for module in 'catapult-sdk' 'rest' 'spammer' 'tools' -do - cd "${module}" - yarn install - cd .. -done