From fb40086c918f24088f4bc43d5292f054edbec051 Mon Sep 17 00:00:00 2001 From: Jan Bevers Date: Fri, 23 Nov 2018 11:55:48 +0100 Subject: [PATCH 1/2] Start using typescript --- .gitignore | 1 + package-lock.json | 43 +++++++++++++------ package.json | 8 +++- src/{index.js => index.ts} | 0 .../{createChannel.js => createChannel.ts} | 10 +++-- src/utils/{createPeers.js => createPeers.ts} | 6 +-- src/utils/{isGrpcs.js => isGrpcs.ts} | 2 +- src/utils/{loadCert.js => loadCert.ts} | 12 ++++-- src/utils/{logger.js => logger.ts} | 4 +- ...seErrorMessage.js => parseErrorMessage.ts} | 6 ++- ...ntListener.js => registerEventListener.ts} | 6 ++- src/utils/serializeArg.js | 10 ----- src/utils/serializeArg.ts | 13 ++++++ .../{setUserContext.js => setUserContext.ts} | 6 ++- tsconfig.json | 9 ++++ 15 files changed, 91 insertions(+), 45 deletions(-) rename src/{index.js => index.ts} (100%) rename src/utils/{createChannel.js => createChannel.ts} (90%) rename src/utils/{createPeers.js => createPeers.ts} (81%) rename src/utils/{isGrpcs.js => isGrpcs.ts} (68%) rename src/utils/{loadCert.js => loadCert.ts} (64%) rename src/utils/{logger.js => logger.ts} (89%) rename src/utils/{parseErrorMessage.js => parseErrorMessage.ts} (91%) rename src/utils/{registerEventListener.js => registerEventListener.ts} (94%) delete mode 100644 src/utils/serializeArg.js create mode 100644 src/utils/serializeArg.ts rename src/utils/{setUserContext.js => setUserContext.ts} (79%) create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 7c78742..6515f99 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode node_modules +dist diff --git a/package-lock.json b/package-lock.json index c52f24b..ea0816c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -210,9 +210,9 @@ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" } }, "fs-extra": { @@ -221,9 +221,9 @@ "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" } }, "jsonfile": { @@ -232,7 +232,7 @@ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "lodash": { @@ -247,9 +247,9 @@ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" } }, "yargs": { @@ -311,7 +311,16 @@ "integrity": "sha512-ktTBUX8hHsosJbt3Pxx5/pUpEFkLlimJLeddGFz7illfm/gTk43Ln7lAdr0rEPi8QIJjuFuV0bvVSa1sKcYszg==", "requires": { "@types/long": "4.0.0", - "@types/node": "10.12.8" + "@types/node": "8.10.38" + } + }, + "@types/log4js": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/log4js/-/log4js-2.3.5.tgz", + "integrity": "sha512-SwF8LkSHqHy9A8GQ67NAYJiGl8zzP4Qtx65Wa+IOxDGdMHxKeoQZjg7m2M1erIT6VK0DYHpu2aTbdLkdkuMHjw==", + "dev": true, + "requires": { + "log4js": "2.11.0" } }, "@types/long": { @@ -320,9 +329,9 @@ "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" }, "@types/node": { - "version": "10.12.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.8.tgz", - "integrity": "sha512-INamyRZG4rW3lDCUmwVd5Xho/bXvQm/v1yP8V0UN1RuInU7RoWoaO570b+yLX4Ia/0szsx1wa8VzcsVlsvbWLA==" + "version": "8.10.38", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.38.tgz", + "integrity": "sha512-EibsnbJerd0hBFaDjJStFrVbVBAtOy4dgL8zZFw0uOvPqzBAX59Ci8cgjg3+RgJIWhsB5A4c+pi+D4P9tQQh/A==" }, "abab": { "version": "1.0.4", @@ -10717,6 +10726,12 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typescript": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", + "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", + "dev": true + }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", diff --git a/package.json b/package.json index b400fa0..ebfd9c5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "lint": "eslint .", "test": "npm run lint && jest --runInBand", "start-dev-network": "node test/startDevNetwork.js", - "test-watch": "jest --watch --runInBand" + "test-watch": "jest --watch --runInBand", + "build": "tsc" }, "repository": { "type": "git", @@ -26,11 +27,14 @@ "homepage": "https://github.com/Kunstmaan/hyperledger-fabric-client-utils#readme", "devDependencies": { "@kunstmaan/hyperledger-fabric-chaincode-dev-setup": "^0.5.2", + "@types/log4js": "^2.3.5", + "@types/node": "^8.10.38", "eslint": "^4.19.1", "eslint-config-airbnb-base": "^12.1.0", "eslint-plugin-import": "^2.11.0", "eslint-plugin-jest": "^21.15.1", - "jest": "^22.4.3" + "jest": "^22.4.3", + "typescript": "^3.1.6" }, "dependencies": { "fabric-client": "^1.3.0", diff --git a/src/index.js b/src/index.ts similarity index 100% rename from src/index.js rename to src/index.ts diff --git a/src/utils/createChannel.js b/src/utils/createChannel.ts similarity index 90% rename from src/utils/createChannel.js rename to src/utils/createChannel.ts index 3d7d8d6..6146ee3 100644 --- a/src/utils/createChannel.js +++ b/src/utils/createChannel.ts @@ -1,8 +1,10 @@ -const loadCert = require('../utils/loadCert'); -const logger = require('./logger').getLogger('utils/createChannel'); -const isGrpcs = require('../utils/isGrpcs'); +import loadCert from '../utils/loadCert'; +import getLogger from './logger'; +import isGrpcs from './isGrpcs'; -module.exports = function createChannel({ +const logger = getLogger('utils/createChannel'); + +export default function createChannel({ fabricClient, channelId, peers = [], diff --git a/src/utils/createPeers.js b/src/utils/createPeers.ts similarity index 81% rename from src/utils/createPeers.js rename to src/utils/createPeers.ts index c6e4b4f..e2ac44a 100644 --- a/src/utils/createPeers.js +++ b/src/utils/createPeers.ts @@ -1,7 +1,7 @@ -const loadCert = require('./loadCert'); -const isGrpcs = require('./isGrpcs'); +import loadCert from './loadCert'; +import isGrpcs from './isGrpcs'; -module.exports = function createPeers(fabricClient, peers) { +export default function createPeers(fabricClient, peers) { const createPeerPromises = []; if (Array.isArray(peers)) { peers.forEach((peer) => { diff --git a/src/utils/isGrpcs.js b/src/utils/isGrpcs.ts similarity index 68% rename from src/utils/isGrpcs.js rename to src/utils/isGrpcs.ts index 8f1252f..b2926f2 100644 --- a/src/utils/isGrpcs.js +++ b/src/utils/isGrpcs.ts @@ -1,4 +1,4 @@ -module.exports = function isGrpcs(url) { +export default function isGrpcs(url: string) { if (url.toLowerCase().indexOf('grpc://') === 0) { return false; } diff --git a/src/utils/loadCert.js b/src/utils/loadCert.ts similarity index 64% rename from src/utils/loadCert.js rename to src/utils/loadCert.ts index 12e2c75..c4c396f 100644 --- a/src/utils/loadCert.js +++ b/src/utils/loadCert.ts @@ -1,7 +1,13 @@ -const fs = require('fs'); -const logger = require('./logger').getLogger('fabric/loadCert'); +import fs from 'fs'; +import getLogger from './logger'; -module.exports = function loadCert(certPath, certOptions = {}) { +const logger = getLogger('fabric/loadCert'); + +interface CertOptions { + +} + +export default function loadCert(certPath: string, certOptions: CertOptions = {}) { return new Promise((resolve, reject) => { logger.info(`Loading certificate for path: ${certPath}`); fs.readFile(certPath, 'utf8', (err, ordererCert) => { diff --git a/src/utils/logger.js b/src/utils/logger.ts similarity index 89% rename from src/utils/logger.js rename to src/utils/logger.ts index 854007e..088df6a 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.ts @@ -1,6 +1,6 @@ -const log4js = require('log4js'); +import log4js from 'log4js'; -module.exports.getLogger = (name) => { +export default function getLogger(name: string) { const logger = log4js.getLogger(name); // set the logging level based on the environment variable diff --git a/src/utils/parseErrorMessage.js b/src/utils/parseErrorMessage.ts similarity index 91% rename from src/utils/parseErrorMessage.js rename to src/utils/parseErrorMessage.ts index b0f339c..297e7e1 100644 --- a/src/utils/parseErrorMessage.js +++ b/src/utils/parseErrorMessage.ts @@ -1,4 +1,6 @@ -const logger = require('./logger').getLogger('fabric/parseErrorMessage'); +import getLogger from './logger'; + +const logger = getLogger('fabric/parseErrorMessage'); const ERROR_REGEX_COLLECTION = [ /^.*?Calling\s+chaincode\s+Invoke\(\)\s+returned\s+error\s+response\s+(.*)\..*?$/i, // Invoke @@ -6,7 +8,7 @@ const ERROR_REGEX_COLLECTION = [ ]; const DEFAULT_ERROR_REGEX = /^\[Error:\s+(.*?)\]$/i; -module.exports = function parseErrorMessage(message) { +export default function parseErrorMessage(message: string): Error { try { const errorMessageMatches = ERROR_REGEX_COLLECTION.map((ERROR_REGEX) => { const normalizedMessage = message.replace(/\n/gm, ' '); diff --git a/src/utils/registerEventListener.js b/src/utils/registerEventListener.ts similarity index 94% rename from src/utils/registerEventListener.js rename to src/utils/registerEventListener.ts index 95dfd48..83d5242 100644 --- a/src/utils/registerEventListener.js +++ b/src/utils/registerEventListener.ts @@ -1,6 +1,8 @@ -const logger = require('./logger').getLogger('utils/registerEventListener'); +import getLogger from './logger'; -module.exports = function registerEventListener({ +const logger = getLogger('utils/registerEventListener'); + +export default function registerEventListener({ channel, peer, type, diff --git a/src/utils/serializeArg.js b/src/utils/serializeArg.js deleted file mode 100644 index fac9510..0000000 --- a/src/utils/serializeArg.js +++ /dev/null @@ -1,10 +0,0 @@ - -module.exports = function serializeArg(arg) { - if (arg instanceof Date) { - return `${arg.getTime()}`; - } - if (typeof arg !== 'string') { - return JSON.stringify(arg); - } - return arg; -}; diff --git a/src/utils/serializeArg.ts b/src/utils/serializeArg.ts new file mode 100644 index 0000000..54b707d --- /dev/null +++ b/src/utils/serializeArg.ts @@ -0,0 +1,13 @@ + +type ArgType = Date | object | string | number | boolean; + +export default function serializeArg(arg: ArgType | ArgType[]) { + if (arg instanceof Date) { + return `${arg.getTime()}`; + } + // TODO: what about nested dates? eg in an object, array of dates + if (typeof arg !== 'string') { + return JSON.stringify(arg); + } + return arg; +}; diff --git a/src/utils/setUserContext.js b/src/utils/setUserContext.ts similarity index 79% rename from src/utils/setUserContext.js rename to src/utils/setUserContext.ts index b694a5c..d41a5b9 100644 --- a/src/utils/setUserContext.js +++ b/src/utils/setUserContext.ts @@ -1,6 +1,8 @@ -const logger = require('./logger').getLogger('fabric/setUserContext'); +import getLogger from './logger'; -module.exports = function setUserContext(fabricClient, userId) { +const logger = getLogger('fabric/setUserContext'); + +export default function setUserContext(fabricClient, userId) { return Promise.resolve() .then(() => { // get the enrolled user from persistence, this user will sign all requests diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4191d0c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "declaration": true, + "outDir": "./dist", + "strict": true + } +} From a079e7d1186192b9ad74cfc88b5c9ca59ffb085b Mon Sep 17 00:00:00 2001 From: Jan Bevers Date: Fri, 23 Nov 2018 18:52:59 +0100 Subject: [PATCH 2/2] Migration to typescript --- package-lock.json | 82 +++++++++++++++ package.json | 4 +- src/index.ts | 12 +-- src/lib/baseService.spec.js | 2 +- src/lib/{baseService.js => baseService.ts} | 63 +++++++++--- ...eFabricClient.js => createFabricClient.ts} | 8 +- src/lib/invoke.spec.js | 6 +- src/lib/{invoke.js => invoke.ts} | 91 +++++++++++------ src/lib/query.spec.js | 4 +- src/lib/{query.js => query.ts} | 37 ++++--- .../registerChaincodeEventListener.spec.js | 6 +- ...r.js => registerChaincodeEventListener.ts} | 46 ++++++--- src/typings/index.d.ts | 23 +++++ src/utils/createChannel.ts | 17 +++- src/utils/createPeers.ts | 7 +- src/utils/{logger.ts => getLogger.ts} | 2 +- src/utils/loadCert.ts | 13 +-- src/utils/parseErrorMessage.spec.js | 2 +- src/utils/parseErrorMessage.ts | 4 +- src/utils/registerEventListener.ts | 99 +++++++++++++------ src/utils/setUserContext.ts | 5 +- test/testSetup.js | 2 +- tsconfig.json | 10 +- 23 files changed, 402 insertions(+), 143 deletions(-) rename src/lib/{baseService.js => baseService.ts} (55%) rename src/lib/{createFabricClient.js => createFabricClient.ts} (84%) rename src/lib/{invoke.js => invoke.ts} (77%) rename src/lib/{query.js => query.ts} (68%) rename src/lib/{registerChaincodeEventListener.js => registerChaincodeEventListener.ts} (50%) create mode 100644 src/typings/index.d.ts rename src/utils/{logger.ts => getLogger.ts} (95%) diff --git a/package-lock.json b/package-lock.json index ea0816c..02e7720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -314,6 +314,21 @@ "@types/node": "8.10.38" } }, + "@types/lodash": { + "version": "4.14.118", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.118.tgz", + "integrity": "sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==", + "dev": true + }, + "@types/lodash.droprightwhile": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@types/lodash.droprightwhile/-/lodash.droprightwhile-4.6.4.tgz", + "integrity": "sha512-bE/j32e4u62+TfSbMRdpRhn7OEQBabbHL37d/qseePJiBcncHsZnniqOSgA1bm+zBt3yYY6a7yp8pw5mFLm/ug==", + "dev": true, + "requires": { + "@types/lodash": "4.14.118" + } + }, "@types/log4js": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/@types/log4js/-/log4js-2.3.5.tgz", @@ -2499,6 +2514,35 @@ "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" }, + "fabric-ca-client": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fabric-ca-client/-/fabric-ca-client-1.3.0.tgz", + "integrity": "sha512-XVSfVrLlI89/RMCFoLAWLPLC042rCtokIeYdm7TIbpAJQ8gzTsFgt8DKk9QSJPzOGy0mik7yJhSI8QbZqLLL0A==", + "dev": true, + "requires": { + "@types/bytebuffer": "5.0.37", + "bn.js": "4.11.8", + "elliptic": "6.4.0", + "fs-extra": "6.0.1", + "js-sha3": "0.7.0", + "jsrsasign": "7.2.2", + "jssha": "2.3.1", + "long": "4.0.0", + "nconf": "0.10.0", + "sjcl": "1.0.7", + "url": "0.11.0", + "util": "0.10.3", + "winston": "2.4.1" + }, + "dependencies": { + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true + } + } + }, "fabric-client": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/fabric-client/-/fabric-client-1.3.0.tgz", @@ -3422,6 +3466,17 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5900,6 +5955,12 @@ "merge-stream": "1.0.1" } }, + "js-sha3": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", + "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==", + "dev": true + }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -5995,6 +6056,15 @@ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -6686,6 +6756,18 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, + "nconf": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.10.0.tgz", + "integrity": "sha512-fKiXMQrpP7CYWJQzKkPPx9hPgmq+YLDyxcG9N8RpiE9FoCkCbzD0NyW0YhE3xn3Aupe7nnDeIx4PFzYehpHT9Q==", + "dev": true, + "requires": { + "async": "1.5.2", + "ini": "1.3.5", + "secure-keys": "1.0.0", + "yargs": "3.32.0" + } + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", diff --git a/package.json b/package.json index ebfd9c5..55a6bd7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "./src/index.js", "scripts": { "lint": "eslint .", - "test": "npm run lint && jest --runInBand", + "test": "jest --runInBand", "start-dev-network": "node test/startDevNetwork.js", "test-watch": "jest --watch --runInBand", "build": "tsc" @@ -27,12 +27,14 @@ "homepage": "https://github.com/Kunstmaan/hyperledger-fabric-client-utils#readme", "devDependencies": { "@kunstmaan/hyperledger-fabric-chaincode-dev-setup": "^0.5.2", + "@types/lodash.droprightwhile": "^4.6.4", "@types/log4js": "^2.3.5", "@types/node": "^8.10.38", "eslint": "^4.19.1", "eslint-config-airbnb-base": "^12.1.0", "eslint-plugin-import": "^2.11.0", "eslint-plugin-jest": "^21.15.1", + "fabric-ca-client": "^1.3.0", "jest": "^22.4.3", "typescript": "^3.1.6" }, diff --git a/src/index.ts b/src/index.ts index 976243d..b1b800c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,10 @@ -const baseService = require('./lib/baseService'); -const createFabricClient = require('./lib/createFabricClient'); -const invoke = require('./lib/invoke'); -const query = require('./lib/query'); -const registerChaincodeEventListener = require('./lib/registerChaincodeEventListener'); +import baseService from './lib/baseService'; +import createFabricClient from './lib/createFabricClient'; +import invoke from './lib/invoke'; +import query from './lib/query'; +import registerChaincodeEventListener from './lib/registerChaincodeEventListener'; -module.exports = { +export default { baseService, createFabricClient, invoke, diff --git a/src/lib/baseService.spec.js b/src/lib/baseService.spec.js index 5cb4353..d77b02a 100644 --- a/src/lib/baseService.spec.js +++ b/src/lib/baseService.spec.js @@ -1,4 +1,4 @@ -const baseService = require('./baseService'); +const baseService = require('../../dist/lib/baseService').default; const testSetup = require('../../test/testSetup'); const { keyStorePath, channelId, peer, chaincodeId, orderer, userId: defaultUserId diff --git a/src/lib/baseService.js b/src/lib/baseService.ts similarity index 55% rename from src/lib/baseService.js rename to src/lib/baseService.ts index 7e1a350..b1e0b81 100644 --- a/src/lib/baseService.js +++ b/src/lib/baseService.ts @@ -1,19 +1,49 @@ -const invoke = require('./invoke'); -const query = require('./query'); -const logger = require('../utils/logger').getLogger('lib/baseService'); -const createFabricClient = require('./createFabricClient'); +import invoke from './invoke'; +import query from './query'; +import getLogger from '../utils/getLogger'; +import createFabricClient from './createFabricClient'; -module.exports = ( - keyStorePath, - chaincodeId, - getServices = () => {}, +interface Options { + channelId?: string; + peers?: Peer[]; + orderer?: Orderer; +} + +interface QueryOptions { + chaincode: Chaincode; + userId: string; + peer?: Peer; + channelId?: string; +} + +interface InvokeOptions { + chaincode: Chaincode; + userId: string; + peers?: Peer[]; + channelId?: string; + orderer?: Orderer; +} + +type getServicesFunction = ( + query: (options: QueryOptions) => Promise<{} | string>, + invoke: (options: InvokeOptions) => Promise<{} | string> +) => Services | {}; + +const logger = getLogger('lib/baseService'); + +export default function baseService( + keyStorePath: string, + chaincodeId: string, + getServices: getServicesFunction = () => ({}), { channelId: defaultChannelId, peers: defaultPeers = [], orderer: defaultOrderer - } = {} -) => { - const setChaincodeOption = (chaincode) => { + }: Options = {} +): { + getChaincodeId: () => string; +} & Services { + const setChaincodeOption = (chaincode: Chaincode) => { const updatedChaincode = {...chaincode}; if (typeof chaincode.id !== 'string') { updatedChaincode.id = chaincodeId; @@ -26,9 +56,9 @@ module.exports = ( }; const services = getServices( - async ({ + async({ chaincode, channelId = defaultChannelId, peer = defaultPeers[0], userId - }) => { + }: QueryOptions) => { const fabricClient = await createFabricClient(keyStorePath); const options = { chaincode: setChaincodeOption(chaincode), @@ -44,7 +74,7 @@ module.exports = ( }, async ({ chaincode, channelId = defaultChannelId, peers = defaultPeers, orderer = defaultOrderer, userId - }) => { + }: InvokeOptions) => { const fabricClient = await createFabricClient(keyStorePath); const options = { chaincode: setChaincodeOption(chaincode), @@ -61,8 +91,9 @@ module.exports = ( } ); + return { getChaincodeId: () => chaincodeId, - ...services - }; + ...(services as object), + } as Services & { getChaincodeId: () => string }; }; diff --git a/src/lib/createFabricClient.js b/src/lib/createFabricClient.ts similarity index 84% rename from src/lib/createFabricClient.js rename to src/lib/createFabricClient.ts index a0cb81b..35ebe6b 100644 --- a/src/lib/createFabricClient.js +++ b/src/lib/createFabricClient.ts @@ -1,7 +1,9 @@ -const FabricClient = require('fabric-client'); -const logger = require('../utils/logger').getLogger('lib/createFabricClient'); +import * as FabricClient from 'fabric-client'; +import getLogger from '../utils/getLogger'; -module.exports = function createFabricClient(keyStorePath) { +const logger = getLogger('lib/createFabricClient'); + +export default function createFabricClient(keyStorePath: string): Promise { const fabricClient = new FabricClient(); return new Promise((resolve, reject) => { diff --git a/src/lib/invoke.spec.js b/src/lib/invoke.spec.js index 04008c5..236d528 100644 --- a/src/lib/invoke.spec.js +++ b/src/lib/invoke.spec.js @@ -1,6 +1,6 @@ -const createFabricClient = require('./createFabricClient'); -const invoke = require('./invoke'); -const query = require('./query'); +const createFabricClient = require('../../dist/lib/createFabricClient').default; +const invoke = require('../../dist/lib/invoke').default; +const query = require('../../dist/lib/query').default; const testSetup = require('../../test/testSetup'); const { keyStorePath, channelId, peer, chaincodeId, userId, orderer diff --git a/src/lib/invoke.js b/src/lib/invoke.ts similarity index 77% rename from src/lib/invoke.js rename to src/lib/invoke.ts index e66fc12..720f214 100644 --- a/src/lib/invoke.js +++ b/src/lib/invoke.ts @@ -1,19 +1,38 @@ -const util = require('util'); -const dropRightWhile = require('lodash.droprightwhile'); -const {URL} = require('url'); -const loadCert = require('../utils/loadCert'); -const setUserContext = require('../utils/setUserContext'); -const serializeArg = require('../utils/serializeArg'); -const parseErrorMessage = require('../utils/parseErrorMessage'); -const logger = require('../utils/logger').getLogger('lib/invoke'); -const isGrpcs = require('../utils/isGrpcs'); -const createChannel = require('../utils/createChannel'); -const registerEventListener = require('../utils/registerEventListener'); +import * as util from 'util'; +import dropRightWhileType from 'lodash.droprightwhile'; +import {URL} from 'url'; +import loadCert from '../utils/loadCert'; +import setUserContext from '../utils/setUserContext'; +import serializeArg from '../utils/serializeArg'; +import parseErrorMessage from '../utils/parseErrorMessage'; +import getLogger from '../utils/getLogger'; +import isGrpcs from '../utils/isGrpcs'; +import createChannel from '../utils/createChannel'; +import registerEventListener from '../utils/registerEventListener'; +import FabricClient from 'fabric-client'; +const dropRightWhile = require('lodash.droprightwhile') as typeof dropRightWhileType; + +interface Options { + fabricClient: FabricClient; + chaincode: Chaincode; + channelId: string; + peers?: Peer[]; + orderer: Orderer; + userId: string; + maxTimeout?: number; +} + +interface EndorsmentResult { + event_status: string; + tx_id: string; +} + +const logger = getLogger('lib/invoke'); const MAX_RETRIES_EVENT_HUB = 5; const MAX_TIMEOUT = 30000; -module.exports = function invoke({ +export default function invoke({ fabricClient, chaincode, channelId, @@ -21,8 +40,8 @@ module.exports = function invoke({ orderer, userId, maxTimeout = MAX_TIMEOUT -}) { - const peersMap = {}; +}: Options) { + const peersMap: {[key: string]: Peer} = {}; (peers || []).forEach((peer) => { const peerUrl = new URL(peer.url); peersMap[peerUrl.host.toLowerCase()] = peer; @@ -34,8 +53,8 @@ module.exports = function invoke({ } return new Promise((resolve, reject) => { - let txId = null; - let channel = null; + let txId: FabricClient.TransactionId = null; + let channel: FabricClient.Channel = null; Promise.resolve() .then(() => createChannel({ fabricClient, @@ -63,7 +82,7 @@ module.exports = function invoke({ }; logger.info(`Invoking ${chaincode.fcn} on chaincode ${chaincode.id}/${channelId}`); - logger.info(`- transaction id: ${txId._transaction_id}`); // eslint-disable-line + logger.info(`- transaction id: ${txId.getTransactionID()}`); logger.debug(`- arguments: ${JSON.stringify(chaincodeArgs)}`); // only print this when debugging ... can be large if (uniquePeers && uniquePeers.length > 0) { logger.info(`- endorsed by: ${uniquePeers.map((peer) => peer.url).join(', ')}`); @@ -73,14 +92,14 @@ module.exports = function invoke({ return channel.sendTransactionProposal(request); }) .then((results) => { - let transactionProposalResponse = null; + let transactionProposalResponse: string | object = null; const proposalResponses = results[0]; const proposal = results[1]; // validate each proposal response separatly - proposalResponses.forEach((proposalResponse, index) => { + proposalResponses.forEach((proposalResponse: FabricClient.ProposalResponse & {message?: string}, index) => { let error; - if (proposalResponses && proposalResponse.response) { + if (proposalResponse.response) { const payload = proposalResponse.response.payload.toString(); try { @@ -97,7 +116,7 @@ module.exports = function invoke({ } error = new Error(`status: ${proposalResponse.response.status}, payload: "${payload}"`); - } else if (proposalResponses && proposalResponse.message) { + } else if (proposalResponse.message) { error = parseErrorMessage(proposalResponse.message); } else { error = new Error('invalid response'); @@ -122,7 +141,10 @@ module.exports = function invoke({ } const peerForListening = uniquePeers[0]; - const waitForTransactionCompleted = () => { + const waitForTransactionCompleted = (): Promise<{ + transactionProposalResponse: string | object, + results: [FabricClient.BroadcastResponse, EndorsmentResult] + }> => { logger.info(util.format( 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s"', proposalResponses[0].response.status, @@ -139,28 +161,28 @@ module.exports = function invoke({ // if the transaction did not get committed within the timeout period, // report a TIMEOUT status const transactionIdString = txId.getTransactionID(); // Get the transaction ID string to be used by the event processing - const promises = []; const sendPromise = channel.sendTransaction(request); - promises.push(sendPromise); // we want the send transaction first, so that we know where to check status // using resolve the promise so that result status may be processed // under the then clause rather than having the catch clause process // the status - const txPromise = new Promise((txPromiseResolve, txPromiseReject) => { + const txPromise: Promise = new Promise((txPromiseResolve, txPromiseReject) => { // In the next step we will setup an event listener to the network // For this we need to use the admin user instead of the incoming user // Otherwise we'll get a mismatch on the certificate // See https://jira.hyperledger.org/browse/FAB-6101 setUserContext(fabricClient, peerForListening.adminUserId) .then(() => { - let handle = null; + let handle: NodeJS.Timer = null; + const peerForListeningInstance = channel.getPeers().find((item) => item.getUrl() === uniquePeers[0].url); const eventListener = registerEventListener({ channel, type: 'Tx', args: [transactionIdString], - onEvent: (tx, code) => { + peer: peerForListeningInstance && peerForListeningInstance.getPeer(), + onEvent: ({code}) => { // this is the callback for transaction event status // first some clean up of event listener if (handle) { @@ -168,10 +190,11 @@ module.exports = function invoke({ } // now let the application know what happened - const returnStatus = {event_status: code, tx_id: transactionIdString}; + const returnStatus: EndorsmentResult = {event_status: code, tx_id: transactionIdString}; if (code !== 'VALID') { - logger.error(`The transaction was invalid, code = ${code}`); - txPromiseReject(new Error(returnStatus)); + const errorMessage = `The transaction was invalid, code = ${code}`; + logger.error(errorMessage); + txPromiseReject(new Error(errorMessage)); } else { logger.info('The transaction has been committed on peer'); txPromiseResolve(returnStatus); @@ -197,7 +220,10 @@ module.exports = function invoke({ .catch((err) => txPromiseReject(err)); }); - promises.push(txPromise); + const promises: [Promise, Promise] = [ + sendPromise, + txPromise, + ]; return Promise.all(promises).then((endorsementResults) => { return { @@ -224,11 +250,12 @@ module.exports = function invoke({ logger.info('Successfully sent transaction to the orderer.'); transactionSucceeded = true; } else { - const message = `Failed to order the transaction. Error code: ${results.status}`; + const message = `Failed to order the transaction. Error code: ${results[0].status}`; logger.error(message); errors.push(message); } + // TODO: this logic can be removed? already handled inside the previous step (txPromise) if (results && results[1] && results[1].event_status === 'VALID') { logger.info('Successfully committed the change to the ledger by the peer'); commitSucceeded = true; diff --git a/src/lib/query.spec.js b/src/lib/query.spec.js index b982a56..846d334 100644 --- a/src/lib/query.spec.js +++ b/src/lib/query.spec.js @@ -1,5 +1,5 @@ -const createFabricClient = require('./createFabricClient'); -const query = require('./query'); +const createFabricClient = require('../../dist/lib/createFabricClient').default; +const query = require('../../dist/lib/query').default; const testSetup = require('../../test/testSetup'); const { keyStorePath, channelId, peer, chaincodeId, userId diff --git a/src/lib/query.js b/src/lib/query.ts similarity index 68% rename from src/lib/query.js rename to src/lib/query.ts index 9e5e77a..487dca9 100644 --- a/src/lib/query.js +++ b/src/lib/query.ts @@ -1,15 +1,27 @@ -const dropRightWhile = require('lodash.droprightwhile'); -const setUserContext = require('../utils/setUserContext'); -const createChannel = require('../utils/createChannel'); -const serializeArg = require('../utils/serializeArg'); -const logger = require('../utils/logger').getLogger('lib/query'); -const parseErrorMessage = require('../utils/parseErrorMessage'); +import FabricClient from 'fabric-client'; +import dropRightWhileType from 'lodash.droprightwhile'; +import setUserContext from '../utils/setUserContext'; +import createChannel from '../utils/createChannel'; +import serializeArg from '../utils/serializeArg'; +import getLogger from '../utils/getLogger'; +import parseErrorMessage from '../utils/parseErrorMessage'; +const dropRightWhile = require('lodash.droprightwhile') as typeof dropRightWhileType; -module.exports = function query({ +interface Options { + fabricClient: FabricClient; + chaincode: Chaincode; + channelId: string; + peer: Peer; + userId: string; +} + +const logger = getLogger('lib/query'); + +export default function query({ fabricClient, chaincode, channelId, peer, userId -}) { +}: Options): Promise { return new Promise((resolve, reject) => { - let channel = null; + let channel: FabricClient.Channel = null; Promise.resolve() .then(() => @@ -43,9 +55,12 @@ module.exports = function query({ logger.info('Query has completed, checking results'); // query_responses could have more than one results if there multiple peers were used as targets if (queryResponses && queryResponses.length === 1) { + if (queryResponses[0] instanceof Error) { - logger.error('error from query = ', queryResponses[0]); - reject(parseErrorMessage(queryResponses[0].message)); + // TODO: not possible following typings? + const errorResponse = queryResponses[0] as Object as Error; + logger.error('error from query = ', errorResponse); + reject(parseErrorMessage(errorResponse.message)); } else { logger.info('Response is ', queryResponses[0].toString()); const response = queryResponses[0].toString(); diff --git a/src/lib/registerChaincodeEventListener.spec.js b/src/lib/registerChaincodeEventListener.spec.js index 153bc52..3169b21 100644 --- a/src/lib/registerChaincodeEventListener.spec.js +++ b/src/lib/registerChaincodeEventListener.spec.js @@ -1,6 +1,6 @@ -const createFabricClient = require('./createFabricClient'); -const invoke = require('./invoke'); -const registerChaincodeEventListener = require('./registerChaincodeEventListener'); +const createFabricClient = require('../../dist/lib/createFabricClient').default; +const invoke = require('../../dist/lib/invoke').default; +const registerChaincodeEventListener = require('../../dist/lib/registerChaincodeEventListener').default; const testSetup = require('../../test/testSetup'); const { keyStorePath, channelId, peer, chaincodeId, userId, orderer diff --git a/src/lib/registerChaincodeEventListener.js b/src/lib/registerChaincodeEventListener.ts similarity index 50% rename from src/lib/registerChaincodeEventListener.js rename to src/lib/registerChaincodeEventListener.ts index 1375a0b..618710b 100644 --- a/src/lib/registerChaincodeEventListener.js +++ b/src/lib/registerChaincodeEventListener.ts @@ -1,9 +1,29 @@ -const setUserContext = require('../utils/setUserContext'); -const logger = require('../utils/logger').getLogger('libs/registerChaincodeEventListener'); -const registerEventListener = require('../utils/registerEventListener'); -const createChannel = require('../utils/createChannel'); +import setUserContext from '../utils/setUserContext'; +import getLogger from '../utils/getLogger'; +import registerEventListener from '../utils/registerEventListener'; +import createChannel from '../utils/createChannel'; +import FabricClient from 'fabric-client'; -module.exports = async function registerChaincodeEventListener({ +interface Options{ + fabricClient: FabricClient; + peer: Peer; + channelId: string; + chaincode: string; + eventId: string; + onEvent: (eventId: string, payload?: Payload) => void; + onDisconnect: (error: Error, eventId: string) => void; + timeoutForReconnect?: number; + maxReconnects?: number; + fullBlock?: boolean; + startBlock?: number; + endBlock?: number; + unregister?: boolean; + disconnect?: boolean; +} + +const logger = getLogger('libs/registerChaincodeEventListener'); + +export default async function registerChaincodeEventListener({ fabricClient, peer, channelId, @@ -18,7 +38,7 @@ module.exports = async function registerChaincodeEventListener({ endBlock, unregister, disconnect -}) { +}: Options) { await setUserContext(fabricClient, peer.adminUserId); const channel = await createChannel({ @@ -27,27 +47,31 @@ module.exports = async function registerChaincodeEventListener({ peers: [peer] }); + const channelPeer = channel.getPeers()[0]; + return registerEventListener({ channel, - peer: channel.getPeers()[0], + peer: channelPeer.getPeer(), type: 'Chaincode', args: [chaincode, eventId], - onEvent: (event) => { + onEvent: ({event}) => { if (event.event_name === eventId) { logger.info(`Event received for ${eventId}`); logger.debug(event); // filtered block events don't give the payload let {payload} = event; if (typeof payload !== 'undefined' && Buffer.isBuffer(payload)) { + let parsedPayload: Payload | string = null; try { - payload = JSON.parse(payload.toString('utf8')); + parsedPayload = JSON.parse(payload.toString('utf8')); } catch (e) { // Not a json object - payload = payload.toString('utf8'); + parsedPayload = payload.toString('utf8') as string; } logger.info(`Event payload ${JSON.stringify(payload)}`); + return onEvent(eventId, parsedPayload); } - onEvent(eventId, payload); + onEvent(eventId); } }, onDisconnect: (error) => { diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts new file mode 100644 index 0000000..a712607 --- /dev/null +++ b/src/typings/index.d.ts @@ -0,0 +1,23 @@ +interface CertOptions { + 'ssl-target-name-override'?: string; +} + +interface Peer { + url: string; + mspid: string; + certPath: string; + certOptions: CertOptions; + adminUserId: string; +} + +interface Orderer { + url: string; + certPath: string; + certOptions: CertOptions; +} + +interface Chaincode { + args: string[]; + fcn: string; + id: string; +} diff --git a/src/utils/createChannel.ts b/src/utils/createChannel.ts index 6146ee3..23f2774 100644 --- a/src/utils/createChannel.ts +++ b/src/utils/createChannel.ts @@ -1,15 +1,24 @@ + +import FabricClient from 'fabric-client'; import loadCert from '../utils/loadCert'; -import getLogger from './logger'; +import getLogger from './getLogger'; import isGrpcs from './isGrpcs'; const logger = getLogger('utils/createChannel'); +interface CreateChannelOptions { + fabricClient: FabricClient; + channelId: string; + peers?: Peer[]; + orderer?: Orderer; +} + export default function createChannel({ fabricClient, channelId, peers = [], orderer = undefined -}) { +}: CreateChannelOptions): Promise { const ordererUrl = orderer ? orderer.url : undefined; const channel = fabricClient.newChannel(channelId); @@ -17,13 +26,13 @@ export default function createChannel({ const registerPeersCertOnChannel = () => Promise.all(peers.map((peer) => { return new Promise((resolve, reject) => { if (!isGrpcs(peer.url)) { - channel.addPeer(fabricClient.newPeer(peer.url)); + channel.addPeer(fabricClient.newPeer(peer.url), peer.mspid); resolve(); return; } loadCert(peer.certPath, peer.certOptions) .then((certOptions) => { - channel.addPeer(fabricClient.newPeer(peer.url, certOptions)); + channel.addPeer(fabricClient.newPeer(peer.url, certOptions), peer.mspid); resolve(); }) .catch(reject); diff --git a/src/utils/createPeers.ts b/src/utils/createPeers.ts index e2ac44a..3284f1a 100644 --- a/src/utils/createPeers.ts +++ b/src/utils/createPeers.ts @@ -1,14 +1,15 @@ import loadCert from './loadCert'; import isGrpcs from './isGrpcs'; +import FabricClient from 'fabric-client'; -export default function createPeers(fabricClient, peers) { - const createPeerPromises = []; +export default function createPeers(fabricClient: FabricClient, peers: Peer[]) { + const createPeerPromises: Promise[] = []; if (Array.isArray(peers)) { peers.forEach((peer) => { const createPeerPromise = Promise.resolve() .then(() => { if (!isGrpcs(peer.url)) { - return Promise.resolve(); + return Promise.resolve(null); } return loadCert(peer.certPath, peer.certOptions); }) diff --git a/src/utils/logger.ts b/src/utils/getLogger.ts similarity index 95% rename from src/utils/logger.ts rename to src/utils/getLogger.ts index 088df6a..ab3c25e 100644 --- a/src/utils/logger.ts +++ b/src/utils/getLogger.ts @@ -1,4 +1,4 @@ -import log4js from 'log4js'; +import * as log4js from 'log4js'; export default function getLogger(name: string) { const logger = log4js.getLogger(name); diff --git a/src/utils/loadCert.ts b/src/utils/loadCert.ts index c4c396f..ffe58af 100644 --- a/src/utils/loadCert.ts +++ b/src/utils/loadCert.ts @@ -1,23 +1,20 @@ import fs from 'fs'; -import getLogger from './logger'; +import getLogger from './getLogger'; const logger = getLogger('fabric/loadCert'); -interface CertOptions { - -} - -export default function loadCert(certPath: string, certOptions: CertOptions = {}) { +// TODO: Why pass cert options? furnction serves only as a proxy... +export default function loadCert(certPath: string, certOptions: CertOptions = {}): Promise { return new Promise((resolve, reject) => { logger.info(`Loading certificate for path: ${certPath}`); - fs.readFile(certPath, 'utf8', (err, ordererCert) => { + fs.readFile(certPath, 'utf8', (err, certContent) => { if (err) { reject(err); return; } resolve({ ...certOptions, - pem: ordererCert + pem: certContent, }); }); }); diff --git a/src/utils/parseErrorMessage.spec.js b/src/utils/parseErrorMessage.spec.js index 9d8ddb5..015b865 100644 --- a/src/utils/parseErrorMessage.spec.js +++ b/src/utils/parseErrorMessage.spec.js @@ -1,4 +1,4 @@ -const parseErrorMessage = require('./parseErrorMessage'); +const parseErrorMessage = require('../../dist/utils/parseErrorMessage').default; test('Parses an error string with a custom error object correctly', () => { const message = diff --git a/src/utils/parseErrorMessage.ts b/src/utils/parseErrorMessage.ts index 297e7e1..e678fce 100644 --- a/src/utils/parseErrorMessage.ts +++ b/src/utils/parseErrorMessage.ts @@ -1,4 +1,4 @@ -import getLogger from './logger'; +import getLogger from './getLogger'; const logger = getLogger('fabric/parseErrorMessage'); @@ -24,7 +24,7 @@ export default function parseErrorMessage(message: string): Error { try { const errorResponse = JSON.parse(errorMessageMatch); const errorObject = Array.isArray(errorResponse) ? errorResponse[0] : errorResponse; - const error = new Error(errorObject.message || 'Unknown error'); + const error = new Error(errorObject.message || 'Unknown error') as Error & {[key: string]: any}; Object.keys(errorObject).forEach((key) => { error[key] = errorObject[key]; }); diff --git a/src/utils/registerEventListener.ts b/src/utils/registerEventListener.ts index 83d5242..85d1330 100644 --- a/src/utils/registerEventListener.ts +++ b/src/utils/registerEventListener.ts @@ -1,7 +1,32 @@ -import getLogger from './logger'; +import getLogger from './getLogger'; +import FabricClient from 'fabric-client'; const logger = getLogger('utils/registerEventListener'); +type EventData = { + event?: FabricClient.ChaincodeEvent; + blockNumber?: number; + txId?: string; + txStatus?: string; + code?: string; +} + +interface Options { + channel: FabricClient.Channel; + peer: FabricClient.Peer; + type: 'Chaincode' | 'Tx'; + args: string[]; + onEvent: (data: EventData) => void; + onDisconnect: (error: Error, willReconnect: boolean) => void; + timeoutForReconnect?: number; + maxReconnects?: number; + fullBlock?: boolean; + startBlock?: number; + endBlock?: number; + unregister?: boolean; + disconnect?: boolean; +} + export default function registerEventListener({ channel, peer, @@ -16,8 +41,8 @@ export default function registerEventListener({ endBlock, unregister, disconnect -}) { - let regId = null; +}: Options) { + let regId: string = null; // Listening for requests and keep requests in sync logger.info(`Setting up event hub for ${type} with arguments ${JSON.stringify(args)}`); @@ -26,45 +51,59 @@ export default function registerEventListener({ let reconnects = 0; const startListening = () => { - eventHub.connect({ - full_block: fullBlock - }); - regId = eventHub[`register${type}Event`].apply(eventHub, [ - ...args, - ...[ - onEvent, - async (error) => { - logger.warn(`Private Eventhub disconnected, trying to reconnect ${error}`); + eventHub.connect(fullBlock); + + const onError = async (error: Error) => { + logger.warn(`Private Eventhub disconnected, trying to reconnect ${error}`); + + const willReconnect = (typeof maxReconnects === 'undefined' || reconnects <= maxReconnects); - const willReconnect = (typeof maxReconnects === 'undefined' || reconnects <= maxReconnects); + if (typeof onDisconnect === 'function') { + await onDisconnect(error, willReconnect); + } - if (typeof onDisconnect === 'function') { - await onDisconnect(error, willReconnect); - } + // this is the callback if something goes wrong with the event registration or processing + if (willReconnect) { + logger.info(`The event hub was disconnected, retrying (attempt: ${reconnects})`); + setTimeout(startListening, timeoutForReconnect); + } - // this is the callback if something goes wrong with the event registration or processing - if (willReconnect) { - logger.info(`The event hub was disconnected, retrying (attempt: ${reconnects})`); - setTimeout(startListening, timeoutForReconnect); - } + reconnects += 1; + }; + const options = { + startBlock, endBlock, unregister, disconnect + }; - reconnects += 1; - }, - { - startBlock, endBlock, unregister, disconnect - } - ] - ]); + switch (type) { + case 'Chaincode': + eventHub.registerChaincodeEvent( + args[0], args[1], + (event, blockNumber, txId, txStatus) => onEvent({ + event, + blockNumber, + txId, + txStatus, + }), + onError, options + ); + break; + case 'Tx': + regId = eventHub.registerTxEvent(args[0], (txId, code) => onEvent({ + txId, + code, + }), onError, options); + } logger.info(`Start listening for ${type} with arguments ${JSON.stringify(args)}, regId = ${regId}`); }; startListening(); + const disconnectEventHub = eventHub.disconnect.bind(eventHub) as typeof eventHub.disconnect; return { - disconnect: eventHub.disconnect.bind(eventHub), + disconnect: disconnectEventHub, // @deprecated, renamed to disconnect to be consistent with HFL API - stopListening: eventHub.disconnect.bind(eventHub) + stopListening: disconnectEventHub }; } catch (err) { logger.error(err); diff --git a/src/utils/setUserContext.ts b/src/utils/setUserContext.ts index d41a5b9..463b689 100644 --- a/src/utils/setUserContext.ts +++ b/src/utils/setUserContext.ts @@ -1,8 +1,9 @@ -import getLogger from './logger'; +import getLogger from './getLogger'; +import FabricClient from 'fabric-client'; const logger = getLogger('fabric/setUserContext'); -export default function setUserContext(fabricClient, userId) { +export default function setUserContext(fabricClient: FabricClient, userId: string) { return Promise.resolve() .then(() => { // get the enrolled user from persistence, this user will sign all requests diff --git a/test/testSetup.js b/test/testSetup.js index d6425a5..6a10dd1 100644 --- a/test/testSetup.js +++ b/test/testSetup.js @@ -2,7 +2,7 @@ const { keyStorePath, channelId, peer, orderer, adminUserId, chaincodeId } = require('./config'); -const {invoke, createFabricClient} = require('../src/index'); +const {invoke, createFabricClient} = require('../dist/index').default; async function initLedger() { try { diff --git a/tsconfig.json b/tsconfig.json index 4191d0c..f6c6ace 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,15 @@ { "compilerOptions": { - "target": "es2017", + "target": "es5", "module": "commonjs", "declaration": true, "outDir": "./dist", - "strict": true + "strict": true, + "lib": ["es2017"], + "allowSyntheticDefaultImports": true, + "strictNullChecks": false, + "sourceMap": true, + "sourceRoot": "./src", + "moduleResolution": "node", } }