diff --git a/providers/workflow-es-mysql/package-lock.json b/providers/workflow-es-mysql/package-lock.json new file mode 100644 index 0000000..c7a5dcb --- /dev/null +++ b/providers/workflow-es-mysql/package-lock.json @@ -0,0 +1,448 @@ +{ + "name": "workflow-es-mysql", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/bluebird": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.26.tgz", + "integrity": "sha512-aj2mrBLn5ky0GmAg6IPXrQjnN0iB/ulozuJ+oZdrHRAzRbXjGmu4UXsNCjFvPbSaaPZmniocdOzsM392qLOlmQ==" + }, + "@types/continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha1-oz4N+dzptCTRyY/E/evYV43O7H4=", + "requires": { + "@types/node": "*" + } + }, + "@types/jasmine": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.12.tgz", + "integrity": "sha512-lXvr2xFQEVQLkIhuGaR3GC1L9lMU1IxeWnAF/wNY5ZWpC4p9dgxkKkzMp7pntpAdv9pZSnYqgsBkCg32MXSZMg==", + "dev": true + }, + "@types/lodash": { + "version": "4.14.129", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.129.tgz", + "integrity": "sha512-oYaV0eSlnOacOr7i4X1FFdH8ttSlb57gu3I9MuStIv2CYkISEY84dNHYsC3bF6sNH7qYcu1BtVrCtQ8Q4KPTfQ==" + }, + "@types/node": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", + "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==" + }, + "@types/sequelize": { + "version": "4.27.47", + "resolved": "https://registry.npmjs.org/@types/sequelize/-/sequelize-4.27.47.tgz", + "integrity": "sha512-gbvb0R0Ndf6unWkheqEqsn8cj/gy1NqjIO5pEkB/Ov9VEYw2T/owhNoL4hOVCMgHNL+YQCnSzRcaWj4izFC0Mw==", + "requires": { + "@types/bluebird": "*", + "@types/continuation-local-storage": "*", + "@types/lodash": "*", + "@types/validator": "*" + } + }, + "@types/validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-i1aY7RKb6HmQIEnK0cBmUZUp1URx0riIHw/GYNoZ46Su0GWfLiDmMI8zMRmaauMnOTg2bQag0qfwcyUFC9Tn+A==" + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bluebird": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "cls-bluebird": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", + "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "requires": { + "is-bluebird": "^1.0.2", + "shimmer": "^1.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "denque": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", + "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + }, + "dottie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", + "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==" + }, + "es6-shim": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.3.tgz", + "integrity": "sha1-m/tzY/7//4emzbbNk+QF7DxLbyY=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "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" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "inversify": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-4.13.0.tgz", + "integrity": "sha512-O5d8y7gKtyRwrvTLZzYET3kdFjqUy58sGpBYMARF13mzqDobpfBXVOPLH7HmnD2VR6Q+1HzZtslGvsdQfeb0SA==" + }, + "is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "jasmine": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.4.0.tgz", + "integrity": "sha512-sR9b4n+fnBFDEd7VS2el2DeHgKcPiMVn44rtKFumq9q7P/t8WrxsVIZPob4UDdgcDNCwyDqwxCt4k9TDRmjPoQ==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "jasmine-core": "~3.4.0" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "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" + } + } + } + }, + "jasmine-core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.4.0.tgz", + "integrity": "sha512-HU/YxV4i6GcmiH4duATwAbJQMlE0MsDIR5XmSVxURxKHn3aGAdbY1/ZJFmVRbKtnLwIxxMJD7gYaPsypcbYimg==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "~0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.25", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz", + "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "mysql2": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.5.tgz", + "integrity": "sha512-zedaOOyb3msuuZcJJnxIX/EGOpmljDG7B+UevRH5lqcv+yhy9eCwkArBz8/AO+/rlY3/oCsOdG8R5oD6k0hNfg==", + "requires": { + "denque": "^1.4.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.4.24", + "long": "^4.0.0", + "lru-cache": "^4.1.3", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.1" + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "retry-as-promised": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", + "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", + "requires": { + "any-promise": "^1.3.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" + }, + "sequelize": { + "version": "5.8.6", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.8.6.tgz", + "integrity": "sha512-u6KJuMBNLAE44PkGUTlevBseb6BV/n5r8CDGmYe1VxcGxdlWXYUiNXlEFEW0OL6ie+yXYV7dnPHa/fDi1M7gMw==", + "requires": { + "bluebird": "^3.5.0", + "cls-bluebird": "^2.1.0", + "debug": "^4.1.1", + "dottie": "^2.0.0", + "inflection": "1.12.0", + "lodash": "^4.17.11", + "moment": "^2.24.0", + "moment-timezone": "^0.5.21", + "retry-as-promised": "^3.1.0", + "semver": "^5.6.0", + "sequelize-pool": "^1.0.2", + "toposort-class": "^1.0.1", + "uuid": "^3.2.1", + "validator": "^10.11.0", + "wkx": "^0.4.6" + } + }, + "sequelize-pool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-1.0.2.tgz", + "integrity": "sha512-VMKl/gCCdIvB1gFZ7p+oqLFEyZEz3oMMYjkKvfEC7GoO9bBcxmfOOU9RdkoltfXGgBZFigSChihRly2gKtsh2w==", + "requires": { + "bluebird": "^3.5.3" + } + }, + "sequelize-typescript": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-0.6.10.tgz", + "integrity": "sha512-4RUC3A+sLJgoLDevEVMzM+LkAWRgQ3aUm30vxi2pbCxDYzKHfc1RmwVzmSUsr3+qR2ZAl+tWsrSYGnYhAcgkqQ==", + "requires": { + "@types/bluebird": "3.5.26", + "@types/node": "11.12.2", + "@types/sequelize": "4.27.47", + "es6-shim": "0.35.3", + "glob": "7.1.2" + }, + "dependencies": { + "@types/node": { + "version": "11.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.12.2.tgz", + "integrity": "sha512-c82MtnqWB/CqqK7/zit74Ob8H1dBdV7bK+BcErwtXbe0+nUGkgzq5NTDmRW/pAv2lFtmeNmW95b0zK2hxpeklg==" + } + } + }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" + }, + "typescript": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", + "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + }, + "wkx": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.6.tgz", + "integrity": "sha512-LHxXlzRCYQXA9ZHgs8r7Gafh0gVOE8o3QmudM1PIkOdkXXjW7Thcl+gb2P2dRuKgW8cqkitCRZkkjtmWzpHi7A==", + "requires": { + "@types/node": "*" + } + }, + "workflow-es": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/workflow-es/-/workflow-es-2.3.5.tgz", + "integrity": "sha512-lflsvS2BfmIhXDxTpI5Q/tWVYoTN5F5RvBGF8U5lzlSK1o2uKLGulDpScf6gEiVqmTQSVNA3FSV2aSaTK7y8jA==", + "requires": { + "inversify": "^4.1.0", + "reflect-metadata": "^0.1.10" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/providers/workflow-es-mysql/package.json b/providers/workflow-es-mysql/package.json index aa9192a..5eac918 100644 --- a/providers/workflow-es-mysql/package.json +++ b/providers/workflow-es-mysql/package.json @@ -20,18 +20,19 @@ }, "license": "MIT", "devDependencies": { - "@types/jasmine": "^3.3.1", - "@types/node": "^10.12.12", - "jasmine": "^3.3.1", - "jasmine-core": "^3.3.0", - "typescript": "^3.2.1" + "@types/jasmine": "^3.3.12", + "@types/node": "^12.0.2", + "jasmine": "^3.4.0", + "jasmine-core": "^3.4.0", + "typescript": "^3.4.5" }, "dependencies": { - "mysql2": "^1.6.4", - "reflect-metadata": "^0.1.12", - "sequelize": "^4.41.2", - "sequelize-typescript": "^0.6.6", - "workflow-es": "^2.3.2" + "json-stable-stringify": "^1.0.1", + "mysql2": "1.6.5", + "reflect-metadata": "0.1.13", + "sequelize": "5.8.6", + "sequelize-typescript": "0.6.10", + "workflow-es": "2.3.5" }, "repository": { "type": "git", diff --git a/providers/workflow-es-mysql/spec/helpers/config.ts b/providers/workflow-es-mysql/spec/helpers/config.ts new file mode 100644 index 0000000..c3534cb --- /dev/null +++ b/providers/workflow-es-mysql/spec/helpers/config.ts @@ -0,0 +1,11 @@ +import { Sequelize } from 'sequelize'; + +export function getConnectionString() { + return "mysql://root:test-password@127.0.0.1:3308/tests"; +} + +export async function createTestSchema() { + var sequelize = new Sequelize('mysql://root:test-password@127.0.0.1:3308'); + await sequelize.query(`CREATE DATABASE IF NOT EXISTS \`tests\``); + await sequelize.close(); +} \ No newline at end of file diff --git a/providers/workflow-es-mysql/spec/helpers/imports.ts b/providers/workflow-es-mysql/spec/helpers/imports.ts new file mode 100644 index 0000000..48d5e07 --- /dev/null +++ b/providers/workflow-es-mysql/spec/helpers/imports.ts @@ -0,0 +1 @@ +import "reflect-metadata"; \ No newline at end of file diff --git a/providers/workflow-es-mysql/spec/helpers/spin-wait.ts b/providers/workflow-es-mysql/spec/helpers/spin-wait.ts new file mode 100644 index 0000000..287054f --- /dev/null +++ b/providers/workflow-es-mysql/spec/helpers/spin-wait.ts @@ -0,0 +1,45 @@ + +export async function spinWaitCallback(until: () => Promise, done: DoneFn) { + let counter = 0; + let callback = async () => { + + try { + let result = await until(); + + if ((!result) && (counter < 60)) { + counter++; + setTimeout(callback, 500); + } + else { + done(); + } + } + catch (err) { + done.fail(err); + } + }; + setTimeout(callback, 500); +} + +export function spinWait(until: () => Promise): Promise { + return new Promise((resolve, reject) => { + let counter = 0; + let callback = async () => { + try { + let result = await until(); + + if ((!result) && (counter < 60)) { + counter++; + setTimeout(callback, 500); + } + else { + resolve(); + } + } + catch (err) { + reject(err); + } + }; + setTimeout(callback, 500); + }); +} \ No newline at end of file diff --git a/providers/workflow-es-mysql/spec/mysql-persistence-provider.spec.ts b/providers/workflow-es-mysql/spec/mysql-persistence-provider.spec.ts index 8266da9..d4756f7 100644 --- a/providers/workflow-es-mysql/spec/mysql-persistence-provider.spec.ts +++ b/providers/workflow-es-mysql/spec/mysql-persistence-provider.spec.ts @@ -1,11 +1,9 @@ import { IPersistenceProvider, WorkflowInstance, ExecutionPointer, Event } from "workflow-es"; -import { Sequelize } from 'sequelize-typescript'; import { MySqlPersistence } from "../src/mysql-provider"; +import { getConnectionString, createTestSchema } from "./helpers/config"; var stringify = require('json-stable-stringify'); -const MY_SQL_DATABASE = "tests"; - -describe("mysql-provider", () => { +describe("mysql-provider", async () => { var persistence: IPersistenceProvider; var wf1: WorkflowInstance; @@ -13,11 +11,9 @@ describe("mysql-provider", () => { var ev2: Event; beforeAll(async (done) => { + await createTestSchema(); - var sequelize = new Sequelize(`mysql://root:test-password@127.0.0.1:3308/`); - await sequelize.createSchema(MY_SQL_DATABASE, {logging: false}); - - var mySqlProvider = new MySqlPersistence(`mysql://root:test-password@127.0.0.1:3308/${MY_SQL_DATABASE}`); + var mySqlProvider = new MySqlPersistence(getConnectionString()); mySqlProvider.connect.then(() => { persistence = mySqlProvider; @@ -39,12 +35,14 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should return a generated id", function() { + it("should return a generated id", function(done) { expect(returnedId).toBeDefined(); + done(); }); - it("should return update original object with id", function() { + it("should return update original object with id", function(done) { expect(wf1.id).toBeDefined(); + done(); }); }); @@ -60,8 +58,9 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should match the original", function() { - expect(stringify(wf2)).toBe(stringify(wf1)); + it("should match the original", function(done) { + expect(stringify(wf2.id)).toBe(stringify(wf1.id)); + done(); }); }); @@ -69,7 +68,7 @@ describe("mysql-provider", () => { var modified: WorkflowInstance; beforeEach((done) => { - modified = JSON.parse(JSON.stringify(wf1)); + modified = wf1; modified.nextExecution = 44; modified.executionPointers.push(new ExecutionPointer()); persistence.persistWorkflow(modified) @@ -80,8 +79,9 @@ describe("mysql-provider", () => { it("should match the original", (done) => { persistence.getWorkflowInstance(modified.id) .then((data) => { - delete data["id"]; - expect(stringify(data)).toBe(stringify(modified)); + delete data.id; + expect(stringify(data.nextExecution)).toBe(stringify(modified.nextExecution)); + expect(stringify(data.executionPointers)).toBe(stringify(modified.executionPointers)); done(); }) .catch(done.fail); @@ -106,12 +106,14 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should return a generated id", function() { + it("should return a generated id", function(done) { expect(returnedId).toBeDefined(); + done(); }); - it("should return update original object with id", function() { + it("should return update original object with id", function(done) { expect(ev1.id).toBeDefined(); + done(); }); }); @@ -133,12 +135,14 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should return a generated id", function() { + it("should return a generated id", function(done) { expect(returnedId).toBeDefined(); + done(); }); - it("should return update original object with id", function() { + it("should return update original object with id", function(done) { expect(ev2.id).toBeDefined(); + done(); }); }); @@ -154,14 +158,19 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should contain previous event id", function() { + it("should contain previous event id", function(done) { expect(returnedEvents).toContain(ev1.id); + done(); }); }); describe("markEventProcessed", () => { var eventResult1: Event; beforeEach((done) => { + persistence.createEvent(ev1) + .then(eventId => { + ev1.id = eventId; + }); return persistence.markEventProcessed(ev1.id) .then(() => { persistence.getEvent(ev1.id) @@ -173,8 +182,9 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should be 'true'", () => { + it("should be 'true'", (done) => { expect(eventResult1.isProcessed).toEqual(true); + done(); }); }); @@ -192,8 +202,9 @@ describe("mysql-provider", () => { .catch(done.fail); }); - it("should be 'false'", () => { + it("should be 'false'", (done) => { expect(eventResult2.isProcessed).toEqual(false); + done(); }); }); }); \ No newline at end of file diff --git a/providers/workflow-es-mysql/spec/scenarios/basic-workflow.spec.ts b/providers/workflow-es-mysql/spec/scenarios/basic-workflow.spec.ts new file mode 100644 index 0000000..df84fff --- /dev/null +++ b/providers/workflow-es-mysql/spec/scenarios/basic-workflow.spec.ts @@ -0,0 +1,87 @@ +import { configureWorkflow, WorkflowHost, WorkflowBuilder, WorkflowStatus, WorkflowBase, StepBody, StepExecutionContext, ExecutionResult, WorkflowInstance, ConsoleLogger } from "workflow-es"; +import { MySqlPersistence } from "../../src/mysql-provider"; +import { getConnectionString, createTestSchema } from "../helpers/config"; +import { spinWaitCallback } from "../helpers/spin-wait"; + +let basicWorkflowScope = { + step1Ticker: 0, + step2Ticker: 0 + } + + describe("basic workflow", async () => { + + class Step1 extends StepBody { + public run(context: StepExecutionContext): Promise { + basicWorkflowScope.step1Ticker++; + return ExecutionResult.next(); + } + } + + class Step2 extends StepBody { + public run(context: StepExecutionContext): Promise { + basicWorkflowScope.step2Ticker++; + return ExecutionResult.next(); + } + } + + class Basic_Workflow implements WorkflowBase { + public id: string = "basic-workflow"; + public version: number = 1; + + public build(builder: WorkflowBuilder) { + builder + .startWith(Step1) + .then(Step2); + } + } + + let workflowId = null; + let instance = null; + let persistence = null; + let config = null; + let host = null; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; + + async function initializeWorkflow() { + persistence = new MySqlPersistence(getConnectionString()); + config = configureWorkflow(); + config.useLogger(new ConsoleLogger()); + config.usePersistence(persistence); + host = config.getHost(); + } + + beforeAll(async (done) => { + await createTestSchema(); + await initializeWorkflow(); + + host.registerWorkflow(Basic_Workflow); + await host.start(); + workflowId = await host.startWorkflow("basic-workflow", 1, null); + spinWaitCallback(async () => { + instance = await persistence.getWorkflowInstance(workflowId); + return (instance.status != WorkflowStatus.Runnable); + }, done); + }); + + afterAll(() => { + // host.stop(); + }); + + it("should have an id", function() { + expect(workflowId).toBeDefined(); + }); + + it("should be marked as complete", function() { + expect(instance.status).toBe(WorkflowStatus.Complete); + }); + + it("should have executed step 1 once", function() { + expect(basicWorkflowScope.step1Ticker).toBe(1); + }); + + it("should have executed step 2 once", function() { + expect(basicWorkflowScope.step2Ticker).toBe(1); + }); + + + }); diff --git a/providers/workflow-es-mysql/spec/scenarios/data-io.spec.ts b/providers/workflow-es-mysql/spec/scenarios/data-io.spec.ts new file mode 100644 index 0000000..902bdca --- /dev/null +++ b/providers/workflow-es-mysql/spec/scenarios/data-io.spec.ts @@ -0,0 +1,78 @@ +import { WorkflowHost, WorkflowBuilder, WorkflowStatus, WorkflowBase, StepBody, StepExecutionContext, ExecutionResult, WorkflowInstance, configureWorkflow, ConsoleLogger } from "workflow-es"; +import { MySqlPersistence } from "../../src/mysql-provider"; +import { getConnectionString, createTestSchema } from "../helpers/config"; +import { spinWaitCallback } from "../helpers/spin-wait"; + + describe("data io", () => { + + class AddNumbers extends StepBody { + public number1: number; + public number2: number; + public result: number; + + public run(context: StepExecutionContext): Promise { + this.result = this.number1 + this.number2; + return ExecutionResult.next(); + } + } + + class MyDataClass { + public value1: number; + public value2: number; + public value3: number; + } + + class Data_Workflow implements WorkflowBase { + public id: string = "data-workflow"; + public version: number = 1; + + public build(builder: WorkflowBuilder) { + builder + .startWith(AddNumbers) + .input((step, data) => step.number1 = data.value1) + .input((step, data) => step.number2 = data.value2) + .output((step, data) => data.value3 = step.result) + } + } + + let workflowId = null; + let instance = null; + let persistence = null; + let config = null; + let host = null; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; + + async function initializeWorkflow() { + persistence = new MySqlPersistence(getConnectionString()); + config = configureWorkflow(); + config.useLogger(new ConsoleLogger()); + config.usePersistence(persistence); + host = config.getHost(); + } + + beforeAll(async (done) => { + await createTestSchema(); + await initializeWorkflow(); + + host.registerWorkflow(Data_Workflow); + await host.start(); + workflowId = await host.startWorkflow("data-workflow", 1, { value1: 2, value2: 3 }); + spinWaitCallback(async () => { + instance = await persistence.getWorkflowInstance(workflowId); + return (instance.status != WorkflowStatus.Runnable); + }, done); + }); + + afterAll(() => { + host.stop(); + }); + + it("should be marked as complete", function() { + expect(instance.status).toBe(WorkflowStatus.Complete); + }); + + it("should have return value of 5", function() { + expect(instance.data.value3).toBe(5); + }); + + }); diff --git a/providers/workflow-es-mysql/spec/scenarios/external-events.spec.ts b/providers/workflow-es-mysql/spec/scenarios/external-events.spec.ts new file mode 100644 index 0000000..0edf97a --- /dev/null +++ b/providers/workflow-es-mysql/spec/scenarios/external-events.spec.ts @@ -0,0 +1,74 @@ +import { WorkflowHost, WorkflowBuilder, WorkflowStatus, WorkflowBase, StepBody, StepExecutionContext, ExecutionResult, WorkflowInstance, configureWorkflow, ConsoleLogger } from "workflow-es"; +import { MySqlPersistence } from "../../src/mysql-provider"; +import { getConnectionString, createTestSchema } from "../helpers/config"; +import { spinWaitCallback, spinWait } from "../helpers/spin-wait"; + + describe("external events", async () => { + await createTestSchema(); + + class Step1 extends StepBody { + public run(context: StepExecutionContext): Promise { + return ExecutionResult.next(); + } + } + + class MyDataClass { + public myValue: string; + } + + class Event_Workflow implements WorkflowBase { + public id: string = "event-workflow"; + public version: number = 1; + + public build(builder: WorkflowBuilder) { + builder + .startWith(Step1) + .waitFor("my-event", data => "0") + .output((step, data) => data.myValue = step.eventData); + } + } + + let workflowId = null; + let instance = null; + let persistence = new MySqlPersistence(getConnectionString()); + let config = configureWorkflow(); + config.useLogger(new ConsoleLogger()); + config.usePersistence(persistence); + let host = config.getHost(); + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; + + beforeAll(async (done) => { + + host.registerWorkflow(Event_Workflow); + await host.start(); + + workflowId = await host.startWorkflow("event-workflow", 1, { value1: 2, value2: 3 }); + + await spinWait(async () => { + let subs = await persistence.getSubscriptions("my-event", "0", new Date()); + return (subs.length > 0); + }); + + await host.publishEvent("my-event", "0", "Pass", new Date()); + + spinWaitCallback(async () => { + instance = await persistence.getWorkflowInstance(workflowId); + return (instance.status != WorkflowStatus.Runnable); + }, done); + }); + + afterAll(() => { + host.stop(); + }); + + it("should be marked as complete", function(done) { + expect(instance.status).toBe(WorkflowStatus.Complete); + done(); + }); + + it("should have return value of 'Pass'", function(done) { + expect(instance.data.myValue).toBe("Pass"); + done(); + }); + + }); diff --git a/providers/workflow-es-mysql/spec/scenarios/if.spec.ts b/providers/workflow-es-mysql/spec/scenarios/if.spec.ts new file mode 100644 index 0000000..269548f --- /dev/null +++ b/providers/workflow-es-mysql/spec/scenarios/if.spec.ts @@ -0,0 +1,103 @@ +import { WorkflowHost, WorkflowBuilder, WorkflowStatus, WorkflowBase, StepBody, StepExecutionContext, ExecutionResult, WorkflowInstance, configureWorkflow, ConsoleLogger } from "workflow-es"; +import { MySqlPersistence } from "../../src/mysql-provider"; +import { getConnectionString, createTestSchema } from "../helpers/config"; +import { spinWaitCallback } from "../helpers/spin-wait"; + + describe("if scenario", () => { + + let workflowScope = { + step1Ticker: 0, + step2Ticker: 0, + step3Ticker: 0, + step4Ticker: 0 + } + + class Step1 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step1Ticker++; + return ExecutionResult.next(); + } + } + + class Step2 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step2Ticker++; + return ExecutionResult.next(); + } + } + + class Step3 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step3Ticker++; + return ExecutionResult.next(); + } + } + + class Step4 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step4Ticker++; + return ExecutionResult.next(); + } + } + + class MyDataClass { + public value: number; + } + + class Data_Workflow implements WorkflowBase { + public id: string = "if-workflow"; + public version: number = 1; + + public build(builder: WorkflowBuilder) { + builder + .startWith(Step1) + .if(data => data.value > 5).do(then => then.startWith(Step2)) + .if(data => data.value > 10).do(then => then.startWith(Step3)) + .then(Step4); + } + } + + let workflowId = null; + let instance = null; + let persistence = null; + let config = null; + let host = null; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; + + async function initializeWorkflow() { + persistence = new MySqlPersistence(getConnectionString()); + config = configureWorkflow(); + config.useLogger(new ConsoleLogger()); + config.usePersistence(persistence); + host = config.getHost(); + } + + beforeAll(async (done) => { + await createTestSchema(); + await initializeWorkflow(); + + host.registerWorkflow(Data_Workflow); + await host.start(); + workflowId = await host.startWorkflow("if-workflow", 1, { value: 7 }); + spinWaitCallback(async () => { + instance = await persistence.getWorkflowInstance(workflowId); + return (instance.status != WorkflowStatus.Runnable); + }, done); + }); + + afterAll(() => { + host.stop(); + }); + + it("should be marked as complete", function() { + expect(instance.status).toBe(WorkflowStatus.Complete); + }); + + it("should have taken correct execution path", function() { + expect(workflowScope.step1Ticker).toBe(1); + expect(workflowScope.step2Ticker).toBe(1); + expect(workflowScope.step3Ticker).toBe(0); + expect(workflowScope.step4Ticker).toBe(1); + }); + +}); \ No newline at end of file diff --git a/providers/workflow-es-mysql/spec/scenarios/while.spec.ts b/providers/workflow-es-mysql/spec/scenarios/while.spec.ts new file mode 100644 index 0000000..9914b74 --- /dev/null +++ b/providers/workflow-es-mysql/spec/scenarios/while.spec.ts @@ -0,0 +1,109 @@ +import { WorkflowHost, WorkflowBuilder, WorkflowStatus, WorkflowBase, StepBody, StepExecutionContext, ExecutionResult, WorkflowInstance, configureWorkflow, ConsoleLogger } from "workflow-es"; +import { MySqlPersistence } from "../../src/mysql-provider"; +import { getConnectionString, createTestSchema } from "../helpers/config"; +import { spinWaitCallback } from "../helpers/spin-wait"; + + describe("while scenario", () => { + + let workflowScope = { + step1Ticker: 0, + step2Ticker: 0, + step3Ticker: 0 + } + + class Step1 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step1Ticker++; + return ExecutionResult.next(); + } + } + + class Step2 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step2Ticker++; + return ExecutionResult.next(); + } + } + + class Step3 extends StepBody { + public run(context: StepExecutionContext): Promise { + workflowScope.step3Ticker++; + return ExecutionResult.next(); + } + } + + class Increment extends StepBody { + + public base: number; + public result: number; + + public run(context: StepExecutionContext): Promise { + this.result = this.base + 1; + return ExecutionResult.next(); + } + } + + class MyDataClass { + public value: number; + } + + class Data_Workflow implements WorkflowBase { + public id: string = "while-workflow"; + public version: number = 1; + + public build(builder: WorkflowBuilder) { + builder + .startWith(Step1) + .while(data => data.value < 3).do(then => then + .startWith(Step2) + .then(Increment) + .input((step, data) => step.base = data.value) + .output((step, data) => data.value = step.result) + ) + .then(Step3); + } + } + + let workflowId = null; + let instance = null; + let persistence = null; + let config = null; + let host = null; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; + + async function initializeWorkflow() { + persistence = new MySqlPersistence(getConnectionString()); + config = configureWorkflow(); + config.useLogger(new ConsoleLogger()); + config.usePersistence(persistence); + host = config.getHost(); + } + + beforeAll(async (done) => { + await createTestSchema(); + await initializeWorkflow(); + + host.registerWorkflow(Data_Workflow); + await host.start(); + workflowId = await host.startWorkflow("while-workflow", 1, { value: 0 }); + spinWaitCallback(async () => { + instance = await persistence.getWorkflowInstance(workflowId); + return (instance.status != WorkflowStatus.Runnable); + }, done); + }); + + afterAll(() => { + host.stop(); + }); + + it("should be marked as complete", function() { + expect(instance.status).toBe(WorkflowStatus.Complete); + }); + + it("should have taken correct execution path", function() { + expect(workflowScope.step1Ticker).toBe(1); + expect(workflowScope.step2Ticker).toBe(3); + expect(workflowScope.step3Ticker).toBe(1); + }); + +}); \ No newline at end of file diff --git a/providers/workflow-es-mysql/src/models/event.ts b/providers/workflow-es-mysql/src/models/event.ts index 3825ee7..d3a5c9e 100644 --- a/providers/workflow-es-mysql/src/models/event.ts +++ b/providers/workflow-es-mysql/src/models/event.ts @@ -1,14 +1,13 @@ import { Table, Model, Column, Default, PrimaryKey, DataType } from 'sequelize-typescript' -@Table({ - timestamps: false, - freezeTableName: true -}) +@Table export class Event extends Model { - @Default(DataType.UUIDV1) - @Column(DataType.UUID) - @PrimaryKey + @Column({ + type: DataType.UUID, + defaultValue: DataType.UUIDV1, + primaryKey: true + }) id: string; @Column @@ -21,13 +20,17 @@ export class Event extends Model { get eventData(): any { return JSON.parse(this.getDataValue('eventData')); }; - set eventData(data: any) { - this.setDataValue('eventData', data); + set eventData(eventData: any) { + if (eventData) { + this.setDataValue('eventData', JSON.stringify(eventData)); + } } @Column eventTime: Date; - @Column + @Column({ + defaultValue: false + }) isProcessed: boolean; } \ No newline at end of file diff --git a/providers/workflow-es-mysql/src/models/executionPointer.ts b/providers/workflow-es-mysql/src/models/executionPointer.ts deleted file mode 100644 index f90abac..0000000 --- a/providers/workflow-es-mysql/src/models/executionPointer.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Table, Column, Model, Default, PrimaryKey, DataType } from 'sequelize-typescript'; - -@Table({ - timestamps: false, - freezeTableName: true -}) -export class ExecutionPointer extends Model { - - @Default(DataType.UUIDV1) - @Column(DataType.UUID) - @PrimaryKey - id: string; - - @Column - stepId : number; - - @Column - active : boolean; - - @Column - sleepUntil: number; - - @Column(DataType.TEXT) - get persistenceData(): any { - return JSON.parse(this.getDataValue('persistenceData')); - }; - set persistenceData(data: any) { - this.setDataValue('persistenceData', data); - } - - @Column - startTime: Date; - - @Column - endTime: Date; - - @Column - eventName: string; - - @Column(DataType.TEXT) - get eventKey(): any { - return JSON.parse(this.getDataValue('eventKey')); - }; - set eventKey(data: any) { - this.setDataValue('eventKey', data); - } - - @Column - eventPublished: boolean; - - @Column(DataType.TEXT) - get eventData(): any { - return JSON.parse(this.getDataValue('eventData')); - }; - set eventData(data: any) { - this.setDataValue('eventData', data); - } - - @Column(DataType.TEXT) - get outcome(): any { - return JSON.parse(this.getDataValue('outcome')); - }; - set outcome(data: any) { - this.setDataValue('outcome', data); - } - - @Column - stepName: string; - - @Column - @Default(0) - retryCount: number; - - @Column(DataType.TEXT) - get children(): string[] { - return JSON.parse(this.getDataValue('children')); - }; - set children(data: string[]) { - this.setDataValue('children', data); - } - - @Column(DataType.TEXT) - get contextItem(): any { - return JSON.parse(this.getDataValue('contextItem')); - }; - set contextItem(data: any) { - this.setDataValue('contextItem', data); - } - - @Column - predecessorId: string; - - @Column(DataType.TEXT) - get scope(): string[] { - return JSON.parse(this.getDataValue('scope')); - }; - set scope(data: string[]) { - this.setDataValue('scope', data); - } - - @Column - @Default(0) - status: number; - -} \ No newline at end of file diff --git a/providers/workflow-es-mysql/src/models/subscription.ts b/providers/workflow-es-mysql/src/models/subscription.ts index 7845458..92ada3c 100644 --- a/providers/workflow-es-mysql/src/models/subscription.ts +++ b/providers/workflow-es-mysql/src/models/subscription.ts @@ -1,19 +1,18 @@ import { Table, Model, Column, Default, PrimaryKey, BelongsTo, DataType} from 'sequelize-typescript' import { Workflow } from './workflow' -@Table({ - timestamps: false, - freezeTableName: true -}) +@Table export class Subscription extends Model { - @Default(DataType.UUIDV1) - @Column(DataType.UUID) - @PrimaryKey + @Column({ + type: DataType.UUID, + defaultValue: DataType.UUIDV1, + primaryKey: true + }) id: string; - @BelongsTo(() => Workflow) - workflowId: Workflow; + @Column + workflowId: string; @Column stepId: number; @@ -26,7 +25,7 @@ export class Subscription extends Model { return JSON.parse(this.getDataValue('eventKey')); }; set eventKey(data: any) { - this.setDataValue('eventKey', data); + this.setDataValue('eventKey', JSON.stringify(data)); } @Column diff --git a/providers/workflow-es-mysql/src/models/workflow.ts b/providers/workflow-es-mysql/src/models/workflow.ts index 688bb12..efce157 100644 --- a/providers/workflow-es-mysql/src/models/workflow.ts +++ b/providers/workflow-es-mysql/src/models/workflow.ts @@ -1,15 +1,13 @@ import { Table, Column, Default, Model, HasMany, PrimaryKey, DataType } from 'sequelize-typescript'; -import { ExecutionPointer } from './executionPointer' -@Table({ - timestamps: false, - freezeTableName: true -}) +@Table export class Workflow extends Model { - @Default(DataType.UUIDV1) - @Column(DataType.UUID) - @PrimaryKey + @Column({ + type: DataType.UUID, + defaultValue: DataType.UUIDV1, + primaryKey: true + }) id : string; @Column @@ -32,7 +30,7 @@ export class Workflow extends Model { return JSON.parse(this.getDataValue('data')); }; set data(data: any) { - this.setDataValue('data', data); + this.setDataValue('data', JSON.stringify(data)); } @Column @@ -41,9 +39,11 @@ export class Workflow extends Model { @Column completeTime : Date; - @HasMany(() => ExecutionPointer) - executionPointers : ExecutionPointer[]; - - - + @Column(DataType.TEXT) + get executionPointers(): any { + return JSON.parse(this.getDataValue('executionPointers')); + }; + set executionPointers(data: any) { + this.setDataValue('executionPointers', JSON.stringify(data)); + } } \ No newline at end of file diff --git a/providers/workflow-es-mysql/src/mysql-provider.ts b/providers/workflow-es-mysql/src/mysql-provider.ts index 6422585..d681bbf 100644 --- a/providers/workflow-es-mysql/src/mysql-provider.ts +++ b/providers/workflow-es-mysql/src/mysql-provider.ts @@ -2,20 +2,16 @@ import { IPersistenceProvider, WorkflowInstance, EventSubscription, Event, Workf import { Workflow as workflowCollection, Workflow } from "./models/workflow"; import { Subscription as subscriptionCollection } from "./models/subscription"; import { Event as eventCollection } from "./models/event"; -import { Sequelize } from "sequelize-typescript"; -import { ExecutionPointer } from "./models/executionPointer"; +import { initializeSequelize } from "./sequelize"; export class MySqlPersistence implements IPersistenceProvider { - public sequelize: any; public connect: Promise; constructor(connectionString: string) { - this.sequelize = new Sequelize(connectionString); this.connect = new Promise(async (resolve, reject) => { try { - await this.sequelize.authenticate(); - await this.sequelize.sync(); + await initializeSequelize(connectionString) resolve(); } catch(err) { @@ -29,8 +25,8 @@ export class MySqlPersistence implements IPersistenceProvider { let deferred = new Promise( async (resolve, reject) => { try { - let workflow = await workflowCollection.create(instance, { include: [ExecutionPointer] }); - instance.id = workflow["id"].toString(); + let workflow = await workflowCollection.create(instance); + instance.id = workflow.id; resolve(instance.id); } catch(err) { @@ -42,11 +38,23 @@ export class MySqlPersistence implements IPersistenceProvider { public async persistWorkflow(instance: WorkflowInstance): Promise { let deferred = new Promise(async (resolve, reject) => { var id = instance.id; - delete instance["id"]; + // delete instance.id; This line is deleting the id from the original instance + + var newInstance = { + workflowDefinitionId: instance.workflowDefinitionId, + version: instance.version, + description: instance.description, + nextExecution: instance.nextExecution, + status: instance.status, + data: instance.data, + createTime: instance.createTime, + completeTime: instance.completeTime, + executionPointers: instance.executionPointers + } try { - var workflow = await workflowCollection.findOne({ where: { id: id }, include: [ExecutionPointer] }); - await workflow.updateAttributes(instance); + var workflow = await workflowCollection.findOne({ where: { id: id }}); + await workflow.update(newInstance); resolve(); } catch (err) { reject(err); @@ -57,8 +65,8 @@ export class MySqlPersistence implements IPersistenceProvider { public async getWorkflowInstance(workflowId: string): Promise { let deferred = new Promise(async (resolve, reject) => { try { - let workflow = await workflowCollection.findById(workflowId, { include: [ExecutionPointer] }); - resolve(workflow); + let workflow = await workflowCollection.findOne({where: { id: workflowId }}); + resolve(workflow.get({ plain: true })); } catch (err) { reject(err); } @@ -73,12 +81,12 @@ export class MySqlPersistence implements IPersistenceProvider { where: { status: WorkflowStatus.Runnable, nextExecution: { $lt: Date.now() } - }, - include: [ExecutionPointer] + }, + attributes: ['id'] }); var result = []; for (let item of instances) { - result.push(item["id"].toString()); + result.push(item.id); } resolve(result); } catch (err) { @@ -93,7 +101,7 @@ export class MySqlPersistence implements IPersistenceProvider { try { let sub = await subscriptionCollection.create(subscription); - subscription.id = sub["id"].toString(); + subscription.id = sub.id; resolve(); } catch(err) { @@ -120,7 +128,7 @@ export class MySqlPersistence implements IPersistenceProvider { let event = new EventSubscription(); event.id = instance.id; - event.workflowId = instance.workflowId.id; + event.workflowId = instance.workflowId; event.stepId = instance.stepId; event.eventName = instance.eventName; event.eventKey = instance.eventKey; @@ -154,7 +162,7 @@ export class MySqlPersistence implements IPersistenceProvider { var deferred = new Promise(async (resolve, reject) => { try { let evnt = await eventCollection.create(event); - event.id = evnt["id"].toString(); + event.id = evnt.id; resolve(event.id); } catch(err) { @@ -167,7 +175,7 @@ export class MySqlPersistence implements IPersistenceProvider { var deferred = new Promise(async (resolve, reject) => { try { let event = await eventCollection.findById(id); - resolve(event); + resolve(event.get({plain: true})); } catch(err) { reject(err); @@ -182,11 +190,12 @@ export class MySqlPersistence implements IPersistenceProvider { where: { isProcessed: false, eventTime: { $lt: new Date() } - } + }, + attributes: ['id'] }); var result = []; for (let event of events) { - result.push(event["id"].toString()); + result.push(event.id); } resolve(result); } @@ -198,9 +207,10 @@ export class MySqlPersistence implements IPersistenceProvider { } public async markEventProcessed(id: string): Promise { + console.log(`markEventProcessed(id:${id})`); var deferred = new Promise(async (resolve, reject) => { try { - var event = await eventCollection.findOne({ where: { id: id } }); + var event = await eventCollection.findByPrimary(id); await event.update({ isProcessed: true }) resolve(); } @@ -213,7 +223,7 @@ export class MySqlPersistence implements IPersistenceProvider { public async markEventUnprocessed(id: string): Promise { var deferred = new Promise(async (resolve, reject) => { try { - var event = await eventCollection.findOne({ where: { id: id } }); + var event = await eventCollection.findById(id); await event.update({ isProcessed: false }) resolve(); } @@ -232,11 +242,12 @@ export class MySqlPersistence implements IPersistenceProvider { eventName: eventName, eventKey: eventKey, eventTime: { $gt: asOf } - } + }, + attributes: ['id'] }); var result = []; for (let event of events) { - result.push(event["id"].toString); + result.push(event.id); } resolve(result); } diff --git a/providers/workflow-es-mysql/src/sequelize.ts b/providers/workflow-es-mysql/src/sequelize.ts index af470e2..62d194d 100644 --- a/providers/workflow-es-mysql/src/sequelize.ts +++ b/providers/workflow-es-mysql/src/sequelize.ts @@ -1,15 +1,12 @@ import { Sequelize } from 'sequelize-typescript'; +import { Event } from './models/event'; +import { Subscription } from './models/subscription'; +import { Workflow } from './models/workflow'; -export const sequelize = new Sequelize({ - dialect: 'mysql', - operatorsAliases: Sequelize.Op as any, - database: 'workflow', - username: 'root', - password: '', - modelPaths: [__dirname + '/models'], - pool: { - max: 10, - min: 1, - idle: 10000 - } -}); \ No newline at end of file +export async function initializeSequelize(connectionString) { + const sequelize = new Sequelize(connectionString); + + await sequelize.addModels([Event, Subscription, Workflow]); + + return sequelize; +} \ No newline at end of file diff --git a/providers/workflow-es-mysql/tsconfig.json b/providers/workflow-es-mysql/tsconfig.json index 07e6237..fe6d6d5 100644 --- a/providers/workflow-es-mysql/tsconfig.json +++ b/providers/workflow-es-mysql/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "commonjs", - "target": "es6", + "target": "ES2016", "outDir": "./build", "declaration": true, "noImplicitAny": false, @@ -11,7 +11,9 @@ "es2017" ], "experimentalDecorators": true, - "emitDecoratorMetadata": true + "emitDecoratorMetadata": true, + "esModuleInterop": false, + "skipLibCheck": true }, "exclude": [ "node_modules"