Adding logger; moving lambdas to separate dirs and including rollup to create distributables; finished up some unit tests
This commit is contained in:
parent
19798aad3d
commit
0cf9aac94c
14 changed files with 486 additions and 101 deletions
239
package-lock.json
generated
239
package-lock.json
generated
|
|
@ -5,7 +5,6 @@
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "autobaan",
|
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -17,6 +16,9 @@
|
||||||
"@babel/preset-env": "^7.16.4",
|
"@babel/preset-env": "^7.16.4",
|
||||||
"@babel/preset-typescript": "^7.16.0",
|
"@babel/preset-typescript": "^7.16.0",
|
||||||
"@rollup/plugin-babel": "^5.3.0",
|
"@rollup/plugin-babel": "^5.3.0",
|
||||||
|
"@rollup/plugin-commonjs": "^21.0.1",
|
||||||
|
"@rollup/plugin-node-resolve": "^13.0.6",
|
||||||
|
"@rollup/plugin-typescript": "^8.3.0",
|
||||||
"@types/aws-lambda": "^8.10.85",
|
"@types/aws-lambda": "^8.10.85",
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/puppeteer": "^5.4.4",
|
"@types/puppeteer": "^5.4.4",
|
||||||
|
|
@ -26,6 +28,7 @@
|
||||||
"eslint": "^8.2.0",
|
"eslint": "^8.2.0",
|
||||||
"jest": "^27.3.1",
|
"jest": "^27.3.1",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.4.1",
|
||||||
|
"rollup": "^2.60.1",
|
||||||
"typescript": "^4.4.4"
|
"typescript": "^4.4.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -2445,6 +2448,71 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@rollup/plugin-commonjs": {
|
||||||
|
"version": "21.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz",
|
||||||
|
"integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"commondir": "^1.0.1",
|
||||||
|
"estree-walker": "^2.0.1",
|
||||||
|
"glob": "^7.1.6",
|
||||||
|
"is-reference": "^1.2.1",
|
||||||
|
"magic-string": "^0.25.7",
|
||||||
|
"resolve": "^1.17.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^2.38.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/plugin-node-resolve": {
|
||||||
|
"version": "13.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.6.tgz",
|
||||||
|
"integrity": "sha512-sFsPDMPd4gMqnh2gS0uIxELnoRUp5kBl5knxD2EO0778G1oOJv4G1vyT2cpWz75OU2jDVcXhjVUuTAczGyFNKA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"@types/resolve": "1.17.1",
|
||||||
|
"builtin-modules": "^3.1.0",
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"is-module": "^1.0.0",
|
||||||
|
"resolve": "^1.19.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^2.42.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/plugin-typescript": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"resolve": "^1.17.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^2.14.0",
|
||||||
|
"tslib": "*",
|
||||||
|
"typescript": ">=3.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||||
|
|
@ -2612,6 +2680,15 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/resolve": {
|
||||||
|
"version": "1.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
|
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/stack-utils": {
|
"node_modules/@types/stack-utils": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
||||||
|
|
@ -3361,6 +3438,18 @@
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/builtin-modules": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
|
|
@ -3496,6 +3585,12 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/commondir": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/concat-map": {
|
"node_modules/concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
|
@ -4879,6 +4974,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-module": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/is-number": {
|
"node_modules/is-number": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
|
@ -4894,6 +4995,15 @@
|
||||||
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
|
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/is-reference": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/estree": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-stream": {
|
"node_modules/is-stream": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
|
@ -6936,6 +7046,15 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/magic-string": {
|
||||||
|
"version": "0.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
||||||
|
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"sourcemap-codec": "^1.4.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/make-dir": {
|
"node_modules/make-dir": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
|
|
@ -7649,11 +7768,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "2.60.0",
|
"version": "2.60.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.1.tgz",
|
||||||
"integrity": "sha512-cHdv9GWd58v58rdseC8e8XIaPUo8a9cgZpnCMMDGZFDZKEODOiPPEQFXLriWr/TjXzhPPmG5bkAztPsOARIcGQ==",
|
"integrity": "sha512-akwfnpjY0rXEDSn1UTVfKXJhPsEBu+imi1gqBA1ZkHGydUnkV/fWCC90P7rDaLEW8KTwBcS1G3N4893Ndz+jwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
},
|
},
|
||||||
|
|
@ -7803,6 +7921,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sourcemap-codec": {
|
||||||
|
"version": "1.4.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||||
|
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/sprintf-js": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
|
@ -10211,6 +10335,53 @@
|
||||||
"@rollup/pluginutils": "^3.1.0"
|
"@rollup/pluginutils": "^3.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@rollup/plugin-commonjs": {
|
||||||
|
"version": "21.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz",
|
||||||
|
"integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"commondir": "^1.0.1",
|
||||||
|
"estree-walker": "^2.0.1",
|
||||||
|
"glob": "^7.1.6",
|
||||||
|
"is-reference": "^1.2.1",
|
||||||
|
"magic-string": "^0.25.7",
|
||||||
|
"resolve": "^1.17.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"estree-walker": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@rollup/plugin-node-resolve": {
|
||||||
|
"version": "13.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.6.tgz",
|
||||||
|
"integrity": "sha512-sFsPDMPd4gMqnh2gS0uIxELnoRUp5kBl5knxD2EO0778G1oOJv4G1vyT2cpWz75OU2jDVcXhjVUuTAczGyFNKA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"@types/resolve": "1.17.1",
|
||||||
|
"builtin-modules": "^3.1.0",
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"is-module": "^1.0.0",
|
||||||
|
"resolve": "^1.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@rollup/plugin-typescript": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"resolve": "^1.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@rollup/pluginutils": {
|
"@rollup/pluginutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||||
|
|
@ -10369,6 +10540,15 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/resolve": {
|
||||||
|
"version": "1.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
|
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/stack-utils": {
|
"@types/stack-utils": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
||||||
|
|
@ -10895,6 +11075,12 @@
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"builtin-modules": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"call-bind": {
|
"call-bind": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
|
|
@ -11004,6 +11190,12 @@
|
||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"commondir": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
|
@ -12038,6 +12230,12 @@
|
||||||
"is-extglob": "^2.1.1"
|
"is-extglob": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-module": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-number": {
|
"is-number": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
|
@ -12050,6 +12248,15 @@
|
||||||
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
|
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-reference": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/estree": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-stream": {
|
"is-stream": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
|
@ -13574,6 +13781,15 @@
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"magic-string": {
|
||||||
|
"version": "0.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
||||||
|
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"sourcemap-codec": "^1.4.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"make-dir": {
|
"make-dir": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
|
|
@ -14108,11 +14324,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rollup": {
|
"rollup": {
|
||||||
"version": "2.60.0",
|
"version": "2.60.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.1.tgz",
|
||||||
"integrity": "sha512-cHdv9GWd58v58rdseC8e8XIaPUo8a9cgZpnCMMDGZFDZKEODOiPPEQFXLriWr/TjXzhPPmG5bkAztPsOARIcGQ==",
|
"integrity": "sha512-akwfnpjY0rXEDSn1UTVfKXJhPsEBu+imi1gqBA1ZkHGydUnkV/fWCC90P7rDaLEW8KTwBcS1G3N4893Ndz+jwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
|
|
@ -14209,6 +14424,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"sourcemap-codec": {
|
||||||
|
"version": "1.4.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||||
|
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"sprintf-js": {
|
"sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
|
|
||||||
12
package.json
12
package.json
|
|
@ -2,15 +2,19 @@
|
||||||
"name": "autobaan",
|
"name": "autobaan",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "14.x"
|
"node": "14.x"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build": "rm -r ./dist/* && rollup -c",
|
||||||
|
"build:reservationScheduler": "rm -r ./dist/reservationScheduler/ || : && rollup -c ./src/lambdas/reservationScheduler/rollup.config.js",
|
||||||
|
"package:reservationScheduler": "rm ./deploy/reservationScheduler.zip || : && mkdir ./deploy || : && zip deploy/reservationScheduler.zip -j dist/reservationScheduler/*",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
|
"test:clear-cache": "jest --clearCache",
|
||||||
|
"test:clean": "npm run test:clear-cache && npm run test",
|
||||||
"lint": "eslint src/ --ext ts",
|
"lint": "eslint src/ --ext ts",
|
||||||
"prettier": "prettier src -w",
|
"prettier": "prettier src -w",
|
||||||
"build": "tsc",
|
|
||||||
"local": "npx ts-node src/local.ts",
|
"local": "npx ts-node src/local.ts",
|
||||||
"zip": "mkdir deploy && zip deploy/reservation-lambda.zip -r dist"
|
"zip": "mkdir deploy && zip deploy/reservation-lambda.zip -r dist"
|
||||||
},
|
},
|
||||||
|
|
@ -25,6 +29,9 @@
|
||||||
"@babel/preset-env": "^7.16.4",
|
"@babel/preset-env": "^7.16.4",
|
||||||
"@babel/preset-typescript": "^7.16.0",
|
"@babel/preset-typescript": "^7.16.0",
|
||||||
"@rollup/plugin-babel": "^5.3.0",
|
"@rollup/plugin-babel": "^5.3.0",
|
||||||
|
"@rollup/plugin-commonjs": "^21.0.1",
|
||||||
|
"@rollup/plugin-node-resolve": "^13.0.6",
|
||||||
|
"@rollup/plugin-typescript": "^8.3.0",
|
||||||
"@types/aws-lambda": "^8.10.85",
|
"@types/aws-lambda": "^8.10.85",
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/puppeteer": "^5.4.4",
|
"@types/puppeteer": "^5.4.4",
|
||||||
|
|
@ -34,6 +41,7 @@
|
||||||
"eslint": "^8.2.0",
|
"eslint": "^8.2.0",
|
||||||
"jest": "^27.3.1",
|
"jest": "^27.3.1",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.4.1",
|
||||||
|
"rollup": "^2.60.1",
|
||||||
"typescript": "^4.4.4"
|
"typescript": "^4.4.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,38 @@ export enum LogLevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Logger {
|
export class Logger {
|
||||||
|
private static instance: LoggerInstance
|
||||||
|
|
||||||
|
public static instantiate(
|
||||||
|
correlationId: string,
|
||||||
|
level = LogLevel.ERROR
|
||||||
|
): LoggerInstance {
|
||||||
|
Logger.instance = new LoggerInstance(correlationId, level)
|
||||||
|
return Logger.instance
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getInstance(): LoggerInstance {
|
||||||
|
return Logger.instance
|
||||||
|
}
|
||||||
|
|
||||||
|
public static debug(message: string, details?: unknown): void {
|
||||||
|
Logger.getInstance().debug(message, details)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static info(message: string, details?: unknown): void {
|
||||||
|
Logger.getInstance().info(message, details)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static error(message: string, details?: unknown): void {
|
||||||
|
Logger.getInstance().error(message, details)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LoggerInstance {
|
||||||
private readonly correlationId: string
|
private readonly correlationId: string
|
||||||
private readonly level: LogLevel
|
private readonly level: LogLevel
|
||||||
|
|
||||||
constructor(correlationId: string, level = LogLevel.ERROR) {
|
public constructor(correlationId: string, level = LogLevel.ERROR) {
|
||||||
this.correlationId = correlationId
|
this.correlationId = correlationId
|
||||||
this.level = level
|
this.level = level
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ dayjs.extend(isSameOrBefore)
|
||||||
|
|
||||||
import { DateRange, Opponent } from './reservation'
|
import { DateRange, Opponent } from './reservation'
|
||||||
|
|
||||||
export interface ReservationRequest {
|
export interface ReservationRequest extends Record<string, unknown> {
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
dateRange: DateRange
|
dateRange: DateRange
|
||||||
|
|
@ -28,20 +28,30 @@ export class ValidationError extends Error {
|
||||||
this.code = code
|
this.code = code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates an incoming request body and converts to ReservationRequest
|
* Validates an incoming request body and converts to ReservationRequest
|
||||||
* @param body String of request body
|
* @param body String of request body
|
||||||
* @returns ReservationRequest
|
* @returns ReservationRequest
|
||||||
*/
|
*/
|
||||||
export const validateRequest = (body: string): ReservationRequest => {
|
export const validateStringRequest = (body: string): ReservationRequest => {
|
||||||
const request = validateRequestBody(body)
|
const request = validateRequestBody(body)
|
||||||
validateRequestDateRange(request.dateRange)
|
validateRequestDateRange(request.dateRange)
|
||||||
validateRequestOpponent(request.opponent)
|
validateRequestOpponent(request.opponent)
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateRequestBody = (body?: string): ReservationRequest => {
|
export const validateJSONRequest = (
|
||||||
|
body: Record<string, unknown>
|
||||||
|
): ReservationRequest => {
|
||||||
|
const request = validateRequestBody(body)
|
||||||
|
validateRequestDateRange(request.dateRange)
|
||||||
|
validateRequestOpponent(request.opponent)
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateRequestBody = (
|
||||||
|
body?: string | Record<string, unknown>
|
||||||
|
): ReservationRequest => {
|
||||||
if (body === undefined) {
|
if (body === undefined) {
|
||||||
throw new ValidationError(
|
throw new ValidationError(
|
||||||
'Invalid request',
|
'Invalid request',
|
||||||
|
|
@ -49,7 +59,21 @@ const validateRequestBody = (body?: string): ReservationRequest => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const jsonBody = transformRequestBody(body)
|
let jsonBody: ReservationRequest
|
||||||
|
if (typeof body === 'string') {
|
||||||
|
jsonBody = transformRequestBody(body)
|
||||||
|
} else {
|
||||||
|
const { username, password, dateRange, opponent } = body
|
||||||
|
jsonBody = {
|
||||||
|
username: username as string,
|
||||||
|
password: password as string,
|
||||||
|
dateRange: convertDateRangeStringToObject(
|
||||||
|
dateRange as { start: string; end: string }
|
||||||
|
),
|
||||||
|
opponent: opponent as Opponent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const { username, password, opponent, dateRange } = jsonBody
|
const { username, password, opponent, dateRange } = jsonBody
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -77,14 +101,15 @@ const transformRequestBody = (body: string): ReservationRequest => {
|
||||||
try {
|
try {
|
||||||
json = JSON.parse(body)
|
json = JSON.parse(body)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
throw new ValidationError(
|
throw new ValidationError(
|
||||||
'Invalid request',
|
'Invalid request',
|
||||||
ValidationErrorCode.INVALID_JSON
|
ValidationErrorCode.INVALID_JSON
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const startTime = json.dateRange?.start ?? 'invalid'
|
const start = json.dateRange?.start ?? 'invalid'
|
||||||
const endTime = json.dateRange?.end ?? 'invalid'
|
const end = json.dateRange?.end ?? 'invalid'
|
||||||
const dateRange: DateRange = { start: dayjs(startTime), end: dayjs(endTime) }
|
const dateRange: DateRange = convertDateRangeStringToObject({ start, end })
|
||||||
return {
|
return {
|
||||||
username: json.username,
|
username: json.username,
|
||||||
password: json.password,
|
password: json.password,
|
||||||
|
|
@ -93,6 +118,14 @@ const transformRequestBody = (body: string): ReservationRequest => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const convertDateRangeStringToObject = ({
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
}: {
|
||||||
|
start: string
|
||||||
|
end: string
|
||||||
|
}): DateRange => ({ start: dayjs(start), end: dayjs(end) })
|
||||||
|
|
||||||
const validateRequestDateRange = (dateRange: DateRange): void => {
|
const validateRequestDateRange = (dateRange: DateRange): void => {
|
||||||
// checking that both dates are valid
|
// checking that both dates are valid
|
||||||
const { start, end } = dateRange
|
const { start, end } = dateRange
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export class Runner {
|
||||||
BrowserConnectOptions
|
BrowserConnectOptions
|
||||||
): Promise<Reservation[]> {
|
): Promise<Reservation[]> {
|
||||||
this.browser = await puppeteer.launch(options)
|
this.browser = await puppeteer.launch(options)
|
||||||
this.page = await this.browser.newPage()
|
this.page = await this.browser?.newPage()
|
||||||
await this.login()
|
await this.login()
|
||||||
return await this.makeReservations()
|
return await this.makeReservations()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
src/lambdas/reservationHandler/rollup.config.js
Normal file
20
src/lambdas/reservationHandler/rollup.config.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// rollup.config.js
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
import typescript from '@rollup/plugin-typescript'
|
||||||
|
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||||
|
import commonjs from '@rollup/plugin-commonjs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
input: path.join(__dirname, 'index.ts'),
|
||||||
|
output: {
|
||||||
|
file: './dist/reservationHandler/index.js',
|
||||||
|
format: 'cjs',
|
||||||
|
sourcemap: true,
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
typescript(),
|
||||||
|
nodeResolve(),
|
||||||
|
commonjs(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
import { Context, Handler } from 'aws-lambda'
|
import { Context, Handler } from 'aws-lambda'
|
||||||
import { Dayjs } from 'dayjs'
|
import { Dayjs } from 'dayjs'
|
||||||
|
|
||||||
import { Logger, LogLevel } from '../common/logger'
|
import { Logger, LogLevel } from '../../common/logger'
|
||||||
import { Reservation } from '../common/reservation'
|
import { Reservation } from '../../common/reservation'
|
||||||
import {
|
import { ReservationRequest, validateJSONRequest } from '../../common/request'
|
||||||
validateRequest,
|
import { scheduleDateToRequestReservation } from '../../common/schedule'
|
||||||
ReservationRequest,
|
|
||||||
} from '../common/request'
|
|
||||||
import { scheduleDateToRequestReservation } from '../common/schedule'
|
|
||||||
|
|
||||||
export interface ScheduledReservationRequest {
|
export interface ScheduledReservationRequest {
|
||||||
reservationRequest: ReservationRequest
|
reservationRequest: ReservationRequest
|
||||||
|
|
@ -18,21 +15,29 @@ export interface ReservationSchedulerResult {
|
||||||
scheduledReservationRequest?: ScheduledReservationRequest
|
scheduledReservationRequest?: ScheduledReservationRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler: Handler<string, ReservationSchedulerResult> = async (
|
export interface ReservationSchedulerInput
|
||||||
payload: string,
|
extends Omit<ReservationRequest, 'dateRange'> {
|
||||||
context: Context,
|
dateRange: { start: string; end: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const handler: Handler<
|
||||||
|
ReservationSchedulerInput,
|
||||||
|
ReservationSchedulerResult
|
||||||
|
> = async (
|
||||||
|
payload: ReservationSchedulerInput,
|
||||||
|
context: Context
|
||||||
): Promise<ReservationSchedulerResult> => {
|
): Promise<ReservationSchedulerResult> => {
|
||||||
const logger = new Logger(context.awsRequestId, LogLevel.DEBUG)
|
Logger.instantiate(context.awsRequestId, LogLevel.DEBUG)
|
||||||
logger.debug('Handling event', { payload })
|
Logger.debug('Handling event', { payload })
|
||||||
let reservationRequest: ReservationRequest
|
let reservationRequest: ReservationRequest
|
||||||
try {
|
try {
|
||||||
reservationRequest = validateRequest(payload)
|
reservationRequest = validateJSONRequest(payload)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Failed to validate request', { err })
|
Logger.error('Failed to validate request', { err })
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug('Successfully validated request', { reservationRequest })
|
Logger.debug('Successfully validated request', { reservationRequest })
|
||||||
|
|
||||||
const res = new Reservation(
|
const res = new Reservation(
|
||||||
reservationRequest.dateRange,
|
reservationRequest.dateRange,
|
||||||
|
|
@ -40,11 +45,11 @@ const handler: Handler<string, ReservationSchedulerResult> = async (
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!res.isAvailableForReservation()) {
|
if (!res.isAvailableForReservation()) {
|
||||||
logger.debug('Reservation date is more than 7 days away')
|
Logger.debug('Reservation date is more than 7 days away')
|
||||||
const scheduledDay = scheduleDateToRequestReservation(
|
const scheduledDay = scheduleDateToRequestReservation(
|
||||||
reservationRequest.dateRange.start
|
reservationRequest.dateRange.start
|
||||||
)
|
)
|
||||||
logger.info(
|
Logger.info(
|
||||||
`Scheduling reservation request for ${scheduledDay.format('YYYY-MM-DD')}`
|
`Scheduling reservation request for ${scheduledDay.format('YYYY-MM-DD')}`
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
|
|
@ -55,10 +60,8 @@ const handler: Handler<string, ReservationSchedulerResult> = async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info('Reservation request can be performed now')
|
Logger.info('Reservation request can be performed now')
|
||||||
return {
|
return {
|
||||||
scheduledReservationRequest: { reservationRequest },
|
scheduledReservationRequest: { reservationRequest },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default handler
|
|
||||||
20
src/lambdas/reservationScheduler/rollup.config.js
Normal file
20
src/lambdas/reservationScheduler/rollup.config.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// rollup.config.js
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
import typescript from '@rollup/plugin-typescript'
|
||||||
|
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||||
|
import commonjs from '@rollup/plugin-commonjs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
input: path.join(__dirname, 'index.ts'),
|
||||||
|
output: {
|
||||||
|
file: './dist/reservationScheduler/index.js',
|
||||||
|
format: 'cjs',
|
||||||
|
sourcemap: true,
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
typescript(),
|
||||||
|
nodeResolve(),
|
||||||
|
commonjs(),
|
||||||
|
]
|
||||||
|
}
|
||||||
34
src/local.ts
34
src/local.ts
|
|
@ -1,12 +1,13 @@
|
||||||
import { IncomingRequest } from './common/request'
|
import dayjs from 'dayjs'
|
||||||
|
import { ReservationRequest } from './common/request'
|
||||||
import { Reservation } from './common/reservation'
|
import { Reservation } from './common/reservation'
|
||||||
import { Runner } from './common/runner'
|
import { Runner } from './common/runner'
|
||||||
|
|
||||||
const run = async (request: IncomingRequest) => {
|
const run = async (request: ReservationRequest) => {
|
||||||
const { username, password, dateTimes, opponent } = request
|
const { username, password, dateRange, opponent } = request
|
||||||
const reservations = dateTimes.map((dt) => new Reservation(dt, opponent))
|
const reservation = new Reservation(dateRange, opponent)
|
||||||
|
|
||||||
const runner = new Runner(username, password, reservations)
|
const runner = new Runner(username, password, [reservation])
|
||||||
await runner.run({ headless: false })
|
await runner.run({ headless: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,26 +39,13 @@ const [endHour, endMinute] = endTime.split(':').map((t) => Number.parseInt(t))
|
||||||
run({
|
run({
|
||||||
username: username,
|
username: username,
|
||||||
password: password,
|
password: password,
|
||||||
dateTimes: [
|
dateRange: {
|
||||||
{
|
start: dayjs(`${year}-${month}-${day}T${startHour}:${startMinute}`),
|
||||||
year: Number.parseInt(year),
|
end: dayjs(`${year}-${month}-${day}T${endHour}:${endMinute}`),
|
||||||
month: Number.parseInt(month),
|
},
|
||||||
day: Number.parseInt(day),
|
|
||||||
timeRange: {
|
|
||||||
start: {
|
|
||||||
hour: startHour,
|
|
||||||
minute: startMinute,
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
hour: endHour,
|
|
||||||
minute: endMinute,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
opponent: {
|
opponent: {
|
||||||
id: opponentId,
|
|
||||||
name: opponentName,
|
name: opponentName,
|
||||||
|
id: opponentId,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => console.log('Success'))
|
.then(() => console.log('Success'))
|
||||||
|
|
|
||||||
44
tests/common/logger.test.ts
Normal file
44
tests/common/logger.test.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Logger, LogLevel } from '../../src/common/logger'
|
||||||
|
|
||||||
|
describe('Logger', () => {
|
||||||
|
test('should create a single instance of LoggerInstance', () => {
|
||||||
|
const a = Logger.instantiate('abc', LogLevel.DEBUG)
|
||||||
|
const b = Logger.getInstance()
|
||||||
|
|
||||||
|
expect(a).toStrictEqual(b)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should log messages', () => {
|
||||||
|
const consoleLogSpy = jest.fn()
|
||||||
|
const consoleErrorSpy = jest.fn()
|
||||||
|
jest.spyOn(console, 'log').mockImplementation(consoleLogSpy)
|
||||||
|
jest.spyOn(console, 'error').mockImplementation(consoleErrorSpy)
|
||||||
|
|
||||||
|
Logger.instantiate('abc', LogLevel.DEBUG)
|
||||||
|
Logger.debug('first')
|
||||||
|
Logger.info('second')
|
||||||
|
Logger.error('third', { errorMessage: 'test' })
|
||||||
|
|
||||||
|
expect(consoleLogSpy).toHaveBeenCalledTimes(2)
|
||||||
|
expect(consoleLogSpy).toHaveBeenNthCalledWith(
|
||||||
|
1, '[%s] %s: %s', 'abc', 'DEBUG', 'first'
|
||||||
|
)
|
||||||
|
expect(consoleLogSpy).toHaveBeenNthCalledWith(
|
||||||
|
2, '[%s] %s: %s', 'abc', 'INFO', 'second'
|
||||||
|
)
|
||||||
|
expect(consoleErrorSpy).toHaveBeenCalledTimes(1)
|
||||||
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
||||||
|
'[%s] %s: %s - %O', 'abc', 'ERROR', 'third', { "errorMessage": "test" }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should log only when level is >= LogLevel of LoggerInstance', () => {
|
||||||
|
const consoleLogSpy = jest.fn()
|
||||||
|
jest.spyOn(console, 'log').mockImplementationOnce(consoleLogSpy)
|
||||||
|
|
||||||
|
Logger.instantiate('abc', LogLevel.INFO)
|
||||||
|
Logger.debug('should\'t appear')
|
||||||
|
|
||||||
|
expect(consoleLogSpy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
validateRequest,
|
validateJSONRequest,
|
||||||
|
validateStringRequest,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
ValidationErrorCode,
|
ValidationErrorCode,
|
||||||
} from '../../src/common/request'
|
} from '../../src/common/request'
|
||||||
|
|
||||||
describe('request', () => {
|
describe('request', () => {
|
||||||
describe('validateRequest', () => {
|
describe('validateStringRequest', () => {
|
||||||
test('should return ReservationRequest', () => {
|
test('should return ReservationRequest', () => {
|
||||||
const body = JSON.stringify({
|
const body = JSON.stringify({
|
||||||
username: 'collin',
|
username: 'collin',
|
||||||
|
|
@ -22,11 +23,11 @@ describe('request', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(() => validateRequest(body)).not.toThrow()
|
expect(() => validateStringRequest(body)).not.toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should fail for undefined body', () => {
|
test('should fail for undefined body', () => {
|
||||||
expect(() => validateRequest(undefined)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.UNDEFINED_REQUEST_BODY))
|
expect(() => validateStringRequest(undefined)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.UNDEFINED_REQUEST_BODY))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should fail for invalid json', () => {
|
test('should fail for invalid json', () => {
|
||||||
|
|
@ -43,7 +44,7 @@ describe('request', () => {
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
expect(() => validateRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_JSON))
|
expect(() => validateStringRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_JSON))
|
||||||
})
|
})
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
|
|
@ -60,7 +61,7 @@ describe('request', () => {
|
||||||
{ username: 'collin', password: '1qaz2wsx', dateRange: { start: '1', end: '1' }, opponent: { id: '123', name: '' } },
|
{ username: 'collin', password: '1qaz2wsx', dateRange: { start: '1', end: '1' }, opponent: { id: '123', name: '' } },
|
||||||
{ username: 'collin', password: '1qaz2wsx', dateRange: { start: '1', end: '1' }, opponent: { id: '123' } },
|
{ username: 'collin', password: '1qaz2wsx', dateRange: { start: '1', end: '1' }, opponent: { id: '123' } },
|
||||||
])('should fail for body missing required values', (body) => {
|
])('should fail for body missing required values', (body) => {
|
||||||
expect(() => validateRequest(JSON.stringify(body))).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_REQUEST_BODY))
|
expect(() => validateStringRequest(JSON.stringify(body))).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_REQUEST_BODY))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should fail for invalid date range', () => {
|
test('should fail for invalid date range', () => {
|
||||||
|
|
@ -77,7 +78,7 @@ describe('request', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(() => validateRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_DATE_RANGE))
|
expect(() => validateStringRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_DATE_RANGE))
|
||||||
})
|
})
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
|
|
@ -97,7 +98,7 @@ describe('request', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(() => validateRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_START_OR_END_DATE))
|
expect(() => validateStringRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_START_OR_END_DATE))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not fail if no opponent is provided', () => {
|
test('should not fail if no opponent is provided', () => {
|
||||||
|
|
@ -110,7 +111,7 @@ describe('request', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(() => validateRequest(body)).not.toThrow()
|
expect(() => validateStringRequest(body)).not.toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
|
|
@ -129,7 +130,26 @@ describe('request', () => {
|
||||||
opponent,
|
opponent,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(() => validateRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_OPPONENT))
|
expect(() => validateStringRequest(body)).toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_OPPONENT))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('validateJSONRequest', () => {
|
||||||
|
test('should return ReservationRequest', () => {
|
||||||
|
const body = {
|
||||||
|
username: 'collin',
|
||||||
|
password: '123abc',
|
||||||
|
dateRange: {
|
||||||
|
start: '2021-12-25T12:34:56Z',
|
||||||
|
end: '2021-12-25T12:45:56Z'
|
||||||
|
},
|
||||||
|
opponent: {
|
||||||
|
id: '123',
|
||||||
|
name: 'collin',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => validateJSONRequest(body)).not.toThrow()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { ValidationError, ValidationErrorCode } from '../../src/common/request'
|
import { ValidationError, ValidationErrorCode } from '../../src/common/request'
|
||||||
import handler, { ReservationSchedulerResult } from '../../src/lambdas/reservationScheduler'
|
import { handler, ReservationSchedulerInput, ReservationSchedulerResult } from '../../src/lambdas/reservationScheduler'
|
||||||
|
|
||||||
jest.mock('../../src/common/logger')
|
jest.mock('../../src/common/logger')
|
||||||
|
|
||||||
|
|
@ -9,12 +9,12 @@ describe('reservationScheduler', () => {
|
||||||
const start = dayjs().add(15, 'minutes')
|
const start = dayjs().add(15, 'minutes')
|
||||||
const end = start.add(15, 'minutes')
|
const end = start.add(15, 'minutes')
|
||||||
|
|
||||||
const payload = '{' +
|
const payload: ReservationSchedulerInput = {
|
||||||
'"username": "collin",' +
|
username: "collin",
|
||||||
'"password": "password",' +
|
password: "password",
|
||||||
`"dateRange": { "start": "${start.toISOString()}", "end": "${end.toISOString()}" },` +
|
dateRange: { start: start.toISOString(), end: end.toISOString() },
|
||||||
'"opponent": { "id": "123", "name": "collin" }' +
|
opponent: { id: "123", name: "collin" }
|
||||||
'}'
|
}
|
||||||
|
|
||||||
// @ts-expect-error - Stubbing AWS context
|
// @ts-expect-error - Stubbing AWS context
|
||||||
await expect(handler(payload, { awsRequestId: '1234' }, undefined)).resolves
|
await expect(handler(payload, { awsRequestId: '1234' }, undefined)).resolves
|
||||||
|
|
@ -32,12 +32,12 @@ describe('reservationScheduler', () => {
|
||||||
test('should handle valid requests outside of reservation window', async () => {
|
test('should handle valid requests outside of reservation window', async () => {
|
||||||
const start = dayjs().add(15, 'days')
|
const start = dayjs().add(15, 'days')
|
||||||
const end = start.add(15, 'minutes')
|
const end = start.add(15, 'minutes')
|
||||||
const payload = '{' +
|
const payload: ReservationSchedulerInput = {
|
||||||
'"username": "collin",' +
|
username: "collin",
|
||||||
'"password": "password",' +
|
password: "password",
|
||||||
`"dateRange": { "start": "${start.toISOString()}", "end": "${end.toISOString()}" },` +
|
dateRange: { start: start.toISOString(), end: end.toISOString() },
|
||||||
'"opponent": { "id": "123", "name": "collin" }' +
|
opponent: { id: "123", name: "collin" }
|
||||||
'}'
|
}
|
||||||
|
|
||||||
// @ts-expect-error - Stubbing AWS context
|
// @ts-expect-error - Stubbing AWS context
|
||||||
await expect(handler(payload, { awsRequestId: '1234' }, undefined)).resolves.toMatchObject<ReservationSchedulerResult>({
|
await expect(handler(payload, { awsRequestId: '1234' }, undefined)).resolves.toMatchObject<ReservationSchedulerResult>({
|
||||||
|
|
@ -56,16 +56,16 @@ describe('reservationScheduler', () => {
|
||||||
test('should throw error for invalid requests', async () => {
|
test('should throw error for invalid requests', async () => {
|
||||||
const start = dayjs().add(15, 'days')
|
const start = dayjs().add(15, 'days')
|
||||||
const end = start.add(15, 'minutes')
|
const end = start.add(15, 'minutes')
|
||||||
const payload = '{invalidJson' +
|
|
||||||
'"username": "collin",' +
|
const payload: ReservationSchedulerInput = {
|
||||||
'"password": "password",' +
|
password: "password",
|
||||||
`"dateRange": { "start": "${start.format()}", "end": "${end.format()}" },` +
|
dateRange: { start: start.toISOString(), end: end.toISOString() },
|
||||||
'"opponent": { "id": "123", "name": "collin" }' +
|
opponent: { id: "123", name: "collin" }
|
||||||
'}'
|
}
|
||||||
|
|
||||||
// @ts-expect-error - Stubbing AWS context
|
// @ts-expect-error - Stubbing AWS context
|
||||||
await expect(handler(payload, { awsRequestId: '1234' }, undefined))
|
await expect(handler(payload, { awsRequestId: '1234' }, undefined))
|
||||||
.rejects
|
.rejects
|
||||||
.toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_JSON))
|
.toThrowError(new ValidationError('Invalid request', ValidationErrorCode.INVALID_REQUEST_BODY))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": ["es2021"],
|
"lib": ["esnext"],
|
||||||
"module": "commonjs",
|
"module": "esnext",
|
||||||
"target": "es2021",
|
"moduleResolution": "node",
|
||||||
|
"target": "es6",
|
||||||
|
"sourceMap": true,
|
||||||
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"outDir": "dist/"
|
"outDir": "./dist/"
|
||||||
},
|
},
|
||||||
|
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"./src/**/*.ts"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue