mirror of
https://github.com/opelly27/streetmerchant.git
synced 2026-05-20 07:37:39 +00:00
feat: enhanced lookup behaviour (#270)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
This commit is contained in:
@@ -20,6 +20,8 @@ PUSHBULLET=""
|
|||||||
PUSHOVER_TOKEN=""
|
PUSHOVER_TOKEN=""
|
||||||
PUSHOVER_USER=""
|
PUSHOVER_USER=""
|
||||||
PUSHOVER_PRIORITY=""
|
PUSHOVER_PRIORITY=""
|
||||||
|
PAGE_BACKOFF_MIN=""
|
||||||
|
PAGE_BACKOFF_MAX=""
|
||||||
PAGE_SLEEP_MIN=""
|
PAGE_SLEEP_MIN=""
|
||||||
PAGE_SLEEP_MAX=""
|
PAGE_SLEEP_MAX=""
|
||||||
SHOW_ONLY_BRANDS=""
|
SHOW_ONLY_BRANDS=""
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ At any point you want the program to stop, use <kbd>Ctrl</kbd> + <kbd>C</kbd>.
|
|||||||
|
|
||||||
> :point_right: Please visit the [wiki](https://github.com/jef/nvidia-snatcher/wiki) if you need more help with installation.
|
> :point_right: Please visit the [wiki](https://github.com/jef/nvidia-snatcher/wiki) if you need more help with installation.
|
||||||
|
|
||||||
|
### Developer notes
|
||||||
|
|
||||||
|
The command `npm run dev` can be used instead of `npm run start` to automatically restart the project when filesystem changes are detected in the `src/` folder or `.env` file.
|
||||||
|
|
||||||
### Customization
|
### Customization
|
||||||
|
|
||||||
To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make any changes to your liking. _All environment variables are **optional**._
|
To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make any changes to your liking. _All environment variables are **optional**._
|
||||||
@@ -83,6 +87,8 @@ Here is a list of variables that you can use to customize your newly copied `.en
|
|||||||
| `PUSHOVER_TOKEN` | Pushover access token | Generate at https://pushover.net/apps/build | |
|
| `PUSHOVER_TOKEN` | Pushover access token | Generate at https://pushover.net/apps/build | |
|
||||||
| `PUSHOVER_USER` | Pushover username | |
|
| `PUSHOVER_USER` | Pushover username | |
|
||||||
| `PUSHOVER_PRIORITY` | Pushover message priority |
|
| `PUSHOVER_PRIORITY` | Pushover message priority |
|
||||||
|
| `PAGE_BACKOFF_MIN` | Minimum backoff time between retrying requests for the same store when a forbidden response is received | Default: `10000` |
|
||||||
|
| `PAGE_BACKOFF_MAX` | Maximum backoff time between retrying requests for the same store when a forbidden response is received | Default: `3600000` |
|
||||||
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same store | In milliseconds, default: `5000` |
|
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same store | In milliseconds, default: `5000` |
|
||||||
| `PAGE_SLEEP_MAX` | Maximum sleep time between queries of the same store | In milliseconds, default: `10000` |
|
| `PAGE_SLEEP_MAX` | Maximum sleep time between queries of the same store | In milliseconds, default: `10000` |
|
||||||
| `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` |
|
| `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` |
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"exec": "ts-node --files ./src/index",
|
||||||
|
"ext": "ts",
|
||||||
|
"watch": [
|
||||||
|
"src/",
|
||||||
|
".env"
|
||||||
|
]
|
||||||
|
}
|
||||||
Generated
+387
-24
@@ -313,7 +313,6 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@slack/logger/-/logger-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@slack/logger/-/logger-2.0.0.tgz",
|
||||||
"integrity": "sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw==",
|
"integrity": "sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": ">=8.9.0"
|
"@types/node": ">=8.9.0"
|
||||||
}
|
}
|
||||||
@@ -321,14 +320,12 @@
|
|||||||
"@slack/types": {
|
"@slack/types": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@slack/types/-/types-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@slack/types/-/types-1.9.0.tgz",
|
||||||
"integrity": "sha512-RmwgMWqOtzd2JPXdiaD/tyrDD0vtjjRDFdxN1I3tAxwBbg4aryzDUVqFc8na16A+3Xik/UN8X1hvVTw8J4EB9w==",
|
"integrity": "sha512-RmwgMWqOtzd2JPXdiaD/tyrDD0vtjjRDFdxN1I3tAxwBbg4aryzDUVqFc8na16A+3Xik/UN8X1hvVTw8J4EB9w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@slack/web-api": {
|
"@slack/web-api": {
|
||||||
"version": "5.12.0",
|
"version": "5.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.12.0.tgz",
|
||||||
"integrity": "sha512-ygSnNHVid7PltGo7W36f2SNVHyliemkzxn9uSwgnWNF7CHmWBKWAylU/eoDml9l5K7akMOxbousiurOw4XqOFg==",
|
"integrity": "sha512-ygSnNHVid7PltGo7W36f2SNVHyliemkzxn9uSwgnWNF7CHmWBKWAylU/eoDml9l5K7akMOxbousiurOw4XqOFg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@slack/logger": ">=1.0.0 <3.0.0",
|
"@slack/logger": ">=1.0.0 <3.0.0",
|
||||||
"@slack/types": "^1.7.0",
|
"@slack/types": "^1.7.0",
|
||||||
@@ -346,8 +343,7 @@
|
|||||||
"is-stream": {
|
"is-stream": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
|
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -372,6 +368,15 @@
|
|||||||
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
|
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/cheerio": {
|
||||||
|
"version": "0.22.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.22.tgz",
|
||||||
|
"integrity": "sha512-05DYX4zU96IBfZFY+t3Mh88nlwSMtmmzSYaQkKN48T495VV1dkHSah6qYyDTN5ngaS0i0VonH37m+RuzSM0YiA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/chrome": {
|
"@types/chrome": {
|
||||||
"version": "0.0.91",
|
"version": "0.0.91",
|
||||||
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.91.tgz",
|
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.91.tgz",
|
||||||
@@ -433,7 +438,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/is-stream/-/is-stream-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/is-stream/-/is-stream-1.1.0.tgz",
|
||||||
"integrity": "sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==",
|
"integrity": "sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
@@ -499,8 +503,7 @@
|
|||||||
"@types/p-queue": {
|
"@types/p-queue": {
|
||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz",
|
||||||
"integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ==",
|
"integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@types/parse-json": {
|
"@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@@ -531,8 +534,7 @@
|
|||||||
"@types/retry": {
|
"@types/retry": {
|
||||||
"version": "0.12.0",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@types/tough-cookie": {
|
"@types/tough-cookie": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@@ -674,6 +676,12 @@
|
|||||||
"eslint-visitor-keys": "^1.1.0"
|
"eslint-visitor-keys": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"abbrev": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.4.0",
|
"version": "7.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
|
||||||
@@ -749,6 +757,22 @@
|
|||||||
"color-convert": "^1.9.0"
|
"color-convert": "^1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"anymatch": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"arg": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"argparse": {
|
"argparse": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
@@ -1042,6 +1066,12 @@
|
|||||||
"tweetnacl": "^0.14.3"
|
"tweetnacl": "^0.14.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"binary-extensions": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"bl": {
|
"bl": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
|
||||||
@@ -1058,6 +1088,11 @@
|
|||||||
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
|
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"boolbase": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||||
|
},
|
||||||
"boxen": {
|
"boxen": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
|
||||||
@@ -1294,6 +1329,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
|
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
|
||||||
},
|
},
|
||||||
|
"buffer-from": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"buffer-xor": {
|
"buffer-xor": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
|
||||||
@@ -1422,6 +1463,70 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cheerio": {
|
||||||
|
"version": "1.0.0-rc.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
|
||||||
|
"integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
|
||||||
|
"requires": {
|
||||||
|
"css-select": "~1.2.0",
|
||||||
|
"dom-serializer": "~0.1.1",
|
||||||
|
"entities": "~1.1.1",
|
||||||
|
"htmlparser2": "^3.9.1",
|
||||||
|
"lodash": "^4.15.0",
|
||||||
|
"parse5": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chokidar": {
|
||||||
|
"version": "3.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
|
||||||
|
"integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"anymatch": "~3.1.1",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"fsevents": "~2.1.2",
|
||||||
|
"glob-parent": "~5.1.0",
|
||||||
|
"is-binary-path": "~2.1.0",
|
||||||
|
"is-glob": "~4.0.1",
|
||||||
|
"normalize-path": "~3.0.0",
|
||||||
|
"readdirp": "~3.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"braces": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fill-range": "^7.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fill-range": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"chownr": {
|
"chownr": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||||
@@ -1756,6 +1861,22 @@
|
|||||||
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
|
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"css-select": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
|
||||||
|
"requires": {
|
||||||
|
"boolbase": "~1.0.0",
|
||||||
|
"css-what": "2.1",
|
||||||
|
"domutils": "1.5.1",
|
||||||
|
"nth-check": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"css-what": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
|
||||||
|
},
|
||||||
"dashdash": {
|
"dashdash": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||||
@@ -1913,6 +2034,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.799653.tgz",
|
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.799653.tgz",
|
||||||
"integrity": "sha512-t1CcaZbvm8pOlikqrsIM9GOa7Ipp07+4h/q9u0JXBWjPCjHdBl9KkddX87Vv9vBHoBGtwV79sYQNGnQM6iS5gg=="
|
"integrity": "sha512-t1CcaZbvm8pOlikqrsIM9GOa7Ipp07+4h/q9u0JXBWjPCjHdBl9KkddX87Vv9vBHoBGtwV79sYQNGnQM6iS5gg=="
|
||||||
},
|
},
|
||||||
|
"diff": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"diffie-hellman": {
|
"diffie-hellman": {
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
|
||||||
@@ -1962,7 +2089,6 @@
|
|||||||
"version": "1.1.8",
|
"version": "1.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/discord-webhook-node/-/discord-webhook-node-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/discord-webhook-node/-/discord-webhook-node-1.1.8.tgz",
|
||||||
"integrity": "sha512-3u0rrwywwYGc6HrgYirN/9gkBYqmdpvReyQjapoXARAHi0P0fIyf3W5tS5i3U3cc7e44E+e7dIHYUeec7yWaug==",
|
"integrity": "sha512-3u0rrwywwYGc6HrgYirN/9gkBYqmdpvReyQjapoXARAHi0P0fIyf3W5tS5i3U3cc7e44E+e7dIHYUeec7yWaug==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"form-data": "^3.0.0",
|
"form-data": "^3.0.0",
|
||||||
"node-fetch": "^2.6.0"
|
"node-fetch": "^2.6.0"
|
||||||
@@ -1972,7 +2098,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
|
||||||
"integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
|
"integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.8",
|
"combined-stream": "^1.0.8",
|
||||||
@@ -1990,12 +2115,43 @@
|
|||||||
"esutils": "^2.0.2"
|
"esutils": "^2.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dom-serializer": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "^1.3.0",
|
||||||
|
"entities": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain-browser": {
|
"domain-browser": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
|
||||||
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
|
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"domelementtype": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||||
|
},
|
||||||
|
"domhandler": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domutils": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||||
|
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
||||||
|
"requires": {
|
||||||
|
"dom-serializer": "0",
|
||||||
|
"domelementtype": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dot-case": {
|
"dot-case": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz",
|
||||||
@@ -2105,6 +2261,11 @@
|
|||||||
"ansi-colors": "^4.1.1"
|
"ansi-colors": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entities": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||||
|
},
|
||||||
"env-editor": {
|
"env-editor": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.1.tgz",
|
||||||
@@ -2853,8 +3014,7 @@
|
|||||||
"eventemitter3": {
|
"eventemitter3": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
||||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
|
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"events": {
|
"events": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
@@ -3182,8 +3342,7 @@
|
|||||||
"find-exec": {
|
"find-exec": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/find-exec/-/find-exec-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/find-exec/-/find-exec-1.0.1.tgz",
|
||||||
"integrity": "sha512-4o6QkGkpg3xK5s/47rdK9LDZRsE4JR1mrXnaAOXBngG6UKeIDJXfwtNCAkljgyy6VRh75D3FFaB0tii9vDEtIA==",
|
"integrity": "sha512-4o6QkGkpg3xK5s/47rdK9LDZRsE4JR1mrXnaAOXBngG6UKeIDJXfwtNCAkljgyy6VRh75D3FFaB0tii9vDEtIA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"find-root": {
|
"find-root": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
@@ -3272,7 +3431,6 @@
|
|||||||
"version": "2.5.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||||
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.6",
|
"combined-stream": "^1.0.6",
|
||||||
@@ -3310,6 +3468,13 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
},
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@@ -3597,6 +3762,19 @@
|
|||||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"htmlparser2": {
|
||||||
|
"version": "3.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||||
|
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "^1.3.1",
|
||||||
|
"domhandler": "^2.3.0",
|
||||||
|
"domutils": "^1.5.1",
|
||||||
|
"entities": "^1.1.1",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
|
"readable-stream": "^3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"http-cache-semantics": {
|
"http-cache-semantics": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
|
||||||
@@ -3718,6 +3896,12 @@
|
|||||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ignore-by-default": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"import-fresh": {
|
"import-fresh": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
|
||||||
@@ -3827,6 +4011,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||||
},
|
},
|
||||||
|
"is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-buffer": {
|
"is-buffer": {
|
||||||
"version": "1.1.6",
|
"version": "1.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
|
||||||
@@ -4457,6 +4650,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"make-error": {
|
||||||
|
"version": "1.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||||
|
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"map-cache": {
|
"map-cache": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
|
||||||
@@ -4984,6 +5183,71 @@
|
|||||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.11.tgz",
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.11.tgz",
|
||||||
"integrity": "sha512-BVZBDi+aJV4O38rxsUh164Dk1NCqgh6Cm0rQSb9SK/DHGll/DrCMnycVDD7msJgZCnmVa8ASo8EZzR7jsgTukQ=="
|
"integrity": "sha512-BVZBDi+aJV4O38rxsUh164Dk1NCqgh6Cm0rQSb9SK/DHGll/DrCMnycVDD7msJgZCnmVa8ASo8EZzR7jsgTukQ=="
|
||||||
},
|
},
|
||||||
|
"nodemon": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chokidar": "^3.2.2",
|
||||||
|
"debug": "^3.2.6",
|
||||||
|
"ignore-by-default": "^1.0.1",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"pstree.remy": "^1.1.7",
|
||||||
|
"semver": "^5.7.1",
|
||||||
|
"supports-color": "^5.5.0",
|
||||||
|
"touch": "^3.1.0",
|
||||||
|
"undefsafe": "^2.0.2",
|
||||||
|
"update-notifier": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||||
|
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nopt": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
|
||||||
|
"integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"abbrev": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"normalize-package-data": {
|
"normalize-package-data": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||||
@@ -5004,12 +5268,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"normalize-url": {
|
"normalize-url": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
||||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nth-check": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
|
||||||
|
"requires": {
|
||||||
|
"boolbase": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"oauth-sign": {
|
"oauth-sign": {
|
||||||
"version": "0.9.0",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||||
@@ -5238,8 +5516,7 @@
|
|||||||
"p-queue": {
|
"p-queue": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz",
|
||||||
"integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==",
|
"integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"p-reduce": {
|
"p-reduce": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@@ -5251,7 +5528,6 @@
|
|||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz",
|
||||||
"integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==",
|
"integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/retry": "^0.12.0",
|
"@types/retry": "^0.12.0",
|
||||||
"retry": "^0.12.0"
|
"retry": "^0.12.0"
|
||||||
@@ -5322,6 +5598,14 @@
|
|||||||
"lines-and-columns": "^1.1.6"
|
"lines-and-columns": "^1.1.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"parse5": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"pascal-case": {
|
"pascal-case": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz",
|
||||||
@@ -5424,7 +5708,6 @@
|
|||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/play-sound/-/play-sound-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/play-sound/-/play-sound-1.1.3.tgz",
|
||||||
"integrity": "sha512-lqEzgtNAdfg2VUXItOtu5bTyWcqeFmnJmgvc8iHEeEOBEJdurqiGYfmCOzIpSBcwrs7XeSpvHv+Rw9dzRPc4aw==",
|
"integrity": "sha512-lqEzgtNAdfg2VUXItOtu5bTyWcqeFmnJmgvc8iHEeEOBEJdurqiGYfmCOzIpSBcwrs7XeSpvHv+Rw9dzRPc4aw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"find-exec": "1.0.1"
|
"find-exec": "1.0.1"
|
||||||
}
|
}
|
||||||
@@ -5518,6 +5801,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||||
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
||||||
},
|
},
|
||||||
|
"pstree.remy": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"public-encrypt": {
|
"public-encrypt": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
|
||||||
@@ -5881,6 +6170,15 @@
|
|||||||
"util-deprecate": "^1.0.1"
|
"util-deprecate": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"readdirp": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"redent": {
|
"redent": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
|
||||||
@@ -6070,8 +6368,7 @@
|
|||||||
"retry": {
|
"retry": {
|
||||||
"version": "0.12.0",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
|
||||||
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
|
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
@@ -6404,6 +6701,24 @@
|
|||||||
"urix": "^0.1.0"
|
"urix": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"source-map-support": {
|
||||||
|
"version": "0.5.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
||||||
|
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"source-map": "^0.6.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"source-map-url": {
|
"source-map-url": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
|
||||||
@@ -6872,6 +7187,15 @@
|
|||||||
"repeat-string": "^1.6.1"
|
"repeat-string": "^1.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"touch": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"nopt": "~1.0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||||
@@ -6900,6 +7224,19 @@
|
|||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ts-node": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"arg": "^4.1.0",
|
||||||
|
"diff": "^4.0.1",
|
||||||
|
"make-error": "^1.1.1",
|
||||||
|
"source-map-support": "^0.5.17",
|
||||||
|
"yn": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tsconfig-paths": {
|
"tsconfig-paths": {
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
||||||
@@ -7016,6 +7353,26 @@
|
|||||||
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
|
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"undefsafe": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"debug": "^2.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"union-value": {
|
"union-value": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||||
@@ -7518,6 +7875,12 @@
|
|||||||
"buffer-crc32": "~0.2.3",
|
"buffer-crc32": "~0.2.3",
|
||||||
"fd-slicer": "~1.1.0"
|
"fd-slicer": "~1.1.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"yn": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -5,6 +5,7 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf ./build && tsc",
|
"build": "rimraf ./build && tsc",
|
||||||
|
"dev": "nodemon --config nodemon.json",
|
||||||
"lint": "xo",
|
"lint": "xo",
|
||||||
"lint:fix": "xo --fix",
|
"lint:fix": "xo --fix",
|
||||||
"start": "npm run build && node build/index.js",
|
"start": "npm run build && node build/index.js",
|
||||||
@@ -22,12 +23,16 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/jef/nvidia-snatcher#readme",
|
"homepage": "https://github.com/jef/nvidia-snatcher#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@slack/web-api": "^5.12.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
|
"cheerio": "^1.0.0-rc.3",
|
||||||
|
"discord-webhook-node": "^1.1.8",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"messaging-api-telegram": "^1.0.1",
|
"messaging-api-telegram": "^1.0.1",
|
||||||
"node-notifier": "^8.0.0",
|
"node-notifier": "^8.0.0",
|
||||||
"nodemailer": "^6.4.11",
|
"nodemailer": "^6.4.11",
|
||||||
"open": "^7.2.1",
|
"open": "^7.2.1",
|
||||||
|
"play-sound": "^1.1.3",
|
||||||
"puppeteer": "^5.3.1",
|
"puppeteer": "^5.3.1",
|
||||||
"puppeteer-extra": "^3.1.15",
|
"puppeteer-extra": "^3.1.15",
|
||||||
"puppeteer-extra-plugin-adblocker": "^2.11.6",
|
"puppeteer-extra-plugin-adblocker": "^2.11.6",
|
||||||
@@ -38,17 +43,17 @@
|
|||||||
"winston": "^3.3.3"
|
"winston": "^3.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@slack/web-api": "^5.12.0",
|
|
||||||
"@types/async": "^3.2.3",
|
"@types/async": "^3.2.3",
|
||||||
|
"@types/cheerio": "^0.22.22",
|
||||||
"@types/node": "^14.11.2",
|
"@types/node": "^14.11.2",
|
||||||
"@types/node-notifier": "^8.0.0",
|
"@types/node-notifier": "^8.0.0",
|
||||||
"@types/nodemailer": "^6.4.0",
|
"@types/nodemailer": "^6.4.0",
|
||||||
"@types/puppeteer": "^3.0.2",
|
"@types/puppeteer": "^3.0.2",
|
||||||
"@types/twitter": "^1.7.0",
|
"@types/twitter": "^1.7.0",
|
||||||
"discord-webhook-node": "^1.1.8",
|
|
||||||
"husky": "^4.3.0",
|
"husky": "^4.3.0",
|
||||||
"play-sound": "^1.1.3",
|
"nodemon": "^2.0.4",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
|
"ts-node": "^9.0.0",
|
||||||
"typescript": "^4.0.2",
|
"typescript": "^4.0.2",
|
||||||
"xo": "^0.33.1"
|
"xo": "^0.33.1"
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-1
@@ -7,5 +7,7 @@ export const adBlocker = new PuppeteerExtraPluginAdblocker({
|
|||||||
|
|
||||||
export async function disableBlockerInPage(page: Page) {
|
export async function disableBlockerInPage(page: Page) {
|
||||||
const blockerObject = await adBlocker.getBlocker();
|
const blockerObject = await adBlocker.getBlocker();
|
||||||
await blockerObject.disableBlockingInPage(page);
|
if (blockerObject.isBlockingEnabled(page)) {
|
||||||
|
await blockerObject.disableBlockingInPage(page);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ function envOrNumber(environment: string | undefined, number?: number): number {
|
|||||||
const browser = {
|
const browser = {
|
||||||
isHeadless: envOrBoolean(process.env.HEADLESS),
|
isHeadless: envOrBoolean(process.env.HEADLESS),
|
||||||
isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false),
|
isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false),
|
||||||
|
maxBackoff: envOrNumber(process.env.PAGE_BACKOFF_MAX, 3600000),
|
||||||
maxSleep: envOrNumber(process.env.PAGE_SLEEP_MAX, 10000),
|
maxSleep: envOrNumber(process.env.PAGE_SLEEP_MAX, 10000),
|
||||||
|
minBackoff: envOrNumber(process.env.PAGE_BACKOFF_MIN, 10000),
|
||||||
minSleep: envOrNumber(process.env.PAGE_SLEEP_MIN, 5000),
|
minSleep: envOrNumber(process.env.PAGE_SLEEP_MIN, 5000),
|
||||||
open: envOrBoolean(process.env.OPEN_BROWSER)
|
open: envOrBoolean(process.env.OPEN_BROWSER)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {Config} from './config';
|
|||||||
import {Logger} from './logger';
|
import {Logger} from './logger';
|
||||||
import {Stores} from './store/model';
|
import {Stores} from './store/model';
|
||||||
import {adBlocker} from './adblocker';
|
import {adBlocker} from './adblocker';
|
||||||
|
import {fetchLinks} from './store/fetch-links';
|
||||||
import {getSleepTime} from './util';
|
import {getSleepTime} from './util';
|
||||||
import puppeteer from 'puppeteer-extra';
|
import puppeteer from 'puppeteer-extra';
|
||||||
import stealthPlugin from 'puppeteer-extra-plugin-stealth';
|
import stealthPlugin from 'puppeteer-extra-plugin-stealth';
|
||||||
@@ -37,14 +38,21 @@ async function main() {
|
|||||||
headless: Config.browser.isHeadless
|
headless: Config.browser.isHeadless
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
for (const store of Stores) {
|
for (const store of Stores) {
|
||||||
Logger.debug(store.links);
|
Logger.debug(store.links);
|
||||||
if (store.setupAction !== undefined) {
|
if (store.setupAction !== undefined) {
|
||||||
store.setupAction(browser);
|
store.setupAction(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (store.linksBuilder) {
|
||||||
|
promises.push(fetchLinks(store, browser));
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(tryLookupAndLoop, getSleepTime(), browser, store);
|
setTimeout(tryLookupAndLoop, getSleepTime(), browser, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -26,6 +26,27 @@ export const Logger = winston.createLogger({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const Print = {
|
export const Print = {
|
||||||
|
backoff(link: Link, store: Store, delay: number, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow(`REQUEST FORBIDDEN - BACKOFF DELAY ${delay}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: REQUEST FORBIDDEN - BACKOFF DELAY ${delay}`;
|
||||||
|
},
|
||||||
|
badStatusCode(link: Link, store: Store, statusCode: number, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow(`STATUS CODE ERROR ${statusCode}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: STATUS CODE ERROR ${statusCode}`;
|
||||||
|
},
|
||||||
|
bannedSeller(link: Link, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('BANNED SELLER');
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: BANNED SELLER`;
|
||||||
|
},
|
||||||
captcha(link: Link, store: Store, color?: boolean): string {
|
captcha(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('CAPTCHA');
|
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('CAPTCHA');
|
||||||
@@ -47,6 +68,20 @@ export const Print = {
|
|||||||
|
|
||||||
return `ℹ ${buildProductString(link, store)} :: IN STOCK, WAITING`;
|
return `ℹ ${buildProductString(link, store)} :: IN STOCK, WAITING`;
|
||||||
},
|
},
|
||||||
|
message(message: string, topic: string, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return '✖ ' + buildSetupString(topic, store, true) + ' :: ' + chalk.yellow(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildSetupString(topic, store)} :: ${message}`;
|
||||||
|
},
|
||||||
|
noResponse(link: Link, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('NO RESPONSE');
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: NO RESPONSE`;
|
||||||
|
},
|
||||||
outOfStock(link: Link, store: Store, color?: boolean): string {
|
outOfStock(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.red('OUT OF STOCK');
|
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.red('OUT OF STOCK');
|
||||||
@@ -63,6 +98,14 @@ export const Print = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function buildSetupString(topic: string, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [setup (${topic})]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `[${store.name}] [setup (${topic})]`;
|
||||||
|
}
|
||||||
|
|
||||||
function buildProductString(link: Link, store: Store, color?: boolean): string {
|
function buildProductString(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [${link.brand} (${link.series})] ${link.model}`);
|
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [${link.brand} (${link.series})] ${link.model}`);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {Link, Series, Store} from './model';
|
||||||
|
import {Logger, Print} from '../logger';
|
||||||
|
import {Browser} from 'puppeteer';
|
||||||
|
import cheerio from 'cheerio';
|
||||||
|
import {filterSeries} from './filter';
|
||||||
|
import {usingResponse} from '../util';
|
||||||
|
|
||||||
|
function addNewLinks(store: Store, links: Link[], series: Series) {
|
||||||
|
if (links.length === 0) {
|
||||||
|
Logger.error(Print.message('NO STORE LINKS FOUND', series, store, true));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingUrls = new Set(store.links.map(link => link.url));
|
||||||
|
const newLinks = links.filter(link => !existingUrls.has(link.url));
|
||||||
|
|
||||||
|
if (newLinks.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info(Print.message(`FOUND ${newLinks.length} STORE LINKS`, series, store, true));
|
||||||
|
Logger.debug(JSON.stringify(newLinks, null, 2));
|
||||||
|
|
||||||
|
store.links = store.links.concat(newLinks);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchLinks(store: Store, browser: Browser) {
|
||||||
|
if (!store.linksBuilder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
for (const {series, url} of store.linksBuilder.urls) {
|
||||||
|
if (!filterSeries(series)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info(Print.message('DETECTING STORE LINKS', series, store, true));
|
||||||
|
|
||||||
|
promises.push(usingResponse(browser, url, async response => {
|
||||||
|
const text = await response?.text();
|
||||||
|
|
||||||
|
if (!text) {
|
||||||
|
Logger.error(Print.message('NO RESPONSE', series, store, true));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const docElement = cheerio.load(text).root();
|
||||||
|
const links = store.linksBuilder!.builder(docElement, series);
|
||||||
|
|
||||||
|
addNewLinks(store, links, series);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
|
}
|
||||||
+1
-1
@@ -40,7 +40,7 @@ function filterModel(model: Link['model']): boolean {
|
|||||||
*
|
*
|
||||||
* @param series The series of the GPU
|
* @param series The series of the GPU
|
||||||
*/
|
*/
|
||||||
function filterSeries(series: Link['series']): boolean {
|
export function filterSeries(series: Link['series']): boolean {
|
||||||
if (Config.store.showOnlySeries.length === 0) {
|
if (Config.store.showOnlySeries.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,85 @@
|
|||||||
|
import {Element, LabelQuery} from './model';
|
||||||
|
import {Logger} from '../logger';
|
||||||
|
import {Page} from 'puppeteer';
|
||||||
|
|
||||||
|
export type Selector = {
|
||||||
|
requireVisible: boolean;
|
||||||
|
selector: string;
|
||||||
|
type: 'innerHTML' | 'outerHTML' | 'textContent';
|
||||||
|
};
|
||||||
|
|
||||||
|
function isElementArray(query: LabelQuery): query is Element[] {
|
||||||
|
return Array.isArray(query) && query.length > 0 && typeof query[0] === 'object';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryAsElementArray(query: LabelQuery, defaultContainer: string): Array<Required<Element>> {
|
||||||
|
if (isElementArray(query)) {
|
||||||
|
return query.map(x => ({
|
||||||
|
container: x.container ?? defaultContainer,
|
||||||
|
text: x.text
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(query)) {
|
||||||
|
return [{
|
||||||
|
container: defaultContainer,
|
||||||
|
text: query
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [{
|
||||||
|
container: query.container ?? defaultContainer,
|
||||||
|
text: query.text
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function pageIncludesLabels(page: Page, query: LabelQuery, options: Selector) {
|
||||||
|
const elementQueries = getQueryAsElementArray(query, options.selector);
|
||||||
|
|
||||||
|
const resolved = await Promise.all(elementQueries.map(async query => {
|
||||||
|
const selector = {...options, selector: query.container};
|
||||||
|
const contents = await extractPageContents(page, selector) ?? '';
|
||||||
|
|
||||||
|
if (!contents) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.debug(contents);
|
||||||
|
|
||||||
|
return includesLabels(contents, query.text);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return resolved.includes(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function extractPageContents(page: Page, selector: Selector): Promise<string | null> {
|
||||||
|
const content = await page.evaluate((options: Selector) => {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const element: globalThis.HTMLElement | null = document.querySelector(options.selector);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.requireVisible && !(element.offsetWidth > 0 && element.offsetHeight > 0)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (options.type) {
|
||||||
|
case 'innerHTML':
|
||||||
|
return element.innerHTML;
|
||||||
|
case 'outerHTML':
|
||||||
|
return element.outerHTML;
|
||||||
|
case 'textContent':
|
||||||
|
return element.textContent;
|
||||||
|
default:
|
||||||
|
return 'Error: selector.type is unknown';
|
||||||
|
}
|
||||||
|
}, selector);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if DOM has any related text.
|
* Checks if DOM has any related text.
|
||||||
*
|
*
|
||||||
|
|||||||
+85
-35
@@ -1,15 +1,23 @@
|
|||||||
import {Browser, Page, Response} from 'puppeteer';
|
import {Browser, Page, Response} from 'puppeteer';
|
||||||
import {Link, Store} from './model';
|
import {Link, Store} from './model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Logger, Print} from '../logger';
|
||||||
|
import {Selector, pageIncludesLabels} from './includes-labels';
|
||||||
import {closePage, delay, getSleepTime} from '../util';
|
import {closePage, delay, getSleepTime} from '../util';
|
||||||
import {Config} from '../config';
|
import {Config} from '../config';
|
||||||
|
import {disableBlockerInPage} from '../adblocker';
|
||||||
import {filterStoreLink} from './filter';
|
import {filterStoreLink} from './filter';
|
||||||
import {includesLabels} from './includes-labels';
|
|
||||||
import open from 'open';
|
import open from 'open';
|
||||||
import {sendNotification} from '../notification';
|
import {sendNotification} from '../notification';
|
||||||
|
|
||||||
|
type Backoff = {
|
||||||
|
count: number;
|
||||||
|
time: number;
|
||||||
|
};
|
||||||
|
|
||||||
const inStock: Record<string, boolean> = {};
|
const inStock: Record<string, boolean> = {};
|
||||||
|
|
||||||
|
const storeBackoff: Record<string, Backoff> = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for looking up information about a each product within
|
* Responsible for looking up information about a each product within
|
||||||
* a `Store`. It's important that we ignore `no-await-in-loop` here
|
* a `Store`. It's important that we ignore `no-await-in-loop` here
|
||||||
@@ -34,6 +42,14 @@ async function lookup(browser: Browser, store: Store) {
|
|||||||
page.setDefaultNavigationTimeout(Config.page.navigationTimeout);
|
page.setDefaultNavigationTimeout(Config.page.navigationTimeout);
|
||||||
await page.setUserAgent(Config.page.userAgent);
|
await page.setUserAgent(Config.page.userAgent);
|
||||||
|
|
||||||
|
if (store.disableAdBlocker) {
|
||||||
|
try {
|
||||||
|
await disableBlockerInPage(page);
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await lookupCard(browser, store, page, link);
|
await lookupCard(browser, store, page, link);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -49,7 +65,41 @@ async function lookupCard(browser: Browser, store: Store, page: Page, link: Link
|
|||||||
const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0';
|
const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0';
|
||||||
const response: Response | null = await page.goto(link.url, {waitUntil: givenWaitFor});
|
const response: Response | null = await page.goto(link.url, {waitUntil: givenWaitFor});
|
||||||
|
|
||||||
if (await lookupCardInStock(store, page)) {
|
if (!response) {
|
||||||
|
Logger.debug(Print.noResponse(link, store, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
let backoff = storeBackoff[store.name];
|
||||||
|
|
||||||
|
if (!backoff) {
|
||||||
|
backoff = {count: 0, time: Config.browser.minBackoff};
|
||||||
|
storeBackoff[store.name] = backoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response?.status() === 403) {
|
||||||
|
Logger.warn(Print.backoff(link, store, backoff.time, true));
|
||||||
|
await delay(backoff.time);
|
||||||
|
backoff.count++;
|
||||||
|
backoff.time = Math.min(backoff.time * 2, Config.browser.maxBackoff);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response?.status() === 429) {
|
||||||
|
Logger.warn(Print.rateLimit(link, store, true));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((response?.status() || 200) >= 400) {
|
||||||
|
Logger.warn(Print.badStatusCode(link, store, response!.status(), true));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backoff.count > 0) {
|
||||||
|
backoff.count--;
|
||||||
|
backoff.time = Math.max(backoff.time / 2, Config.browser.minBackoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await lookupCardInStock(store, page, link)) {
|
||||||
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
||||||
Logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`);
|
Logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`);
|
||||||
|
|
||||||
@@ -77,48 +127,48 @@ async function lookupCard(browser: Browser, store: Store, page: Page, link: Link
|
|||||||
link.screenshot = `success-${Date.now()}.png`;
|
link.screenshot = `success-${Date.now()}.png`;
|
||||||
await page.screenshot({path: link.screenshot});
|
await page.screenshot({path: link.screenshot});
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await lookupPageHasCaptcha(store, page)) {
|
|
||||||
Logger.warn(Print.captcha(link, store, true));
|
|
||||||
await delay(getSleepTime());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response && response.status() === 429) {
|
|
||||||
Logger.warn(Print.rateLimit(link, store, true));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info(Print.outOfStock(link, store, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function lookupCardInStock(store: Store, page: Page) {
|
async function lookupCardInStock(store: Store, page: Page, link: Link) {
|
||||||
const stockHandle = await page.$(store.labels.inStock.container);
|
const baseOptions: Selector = {
|
||||||
|
requireVisible: false,
|
||||||
|
selector: store.labels.container ?? 'body',
|
||||||
|
type: 'textContent'
|
||||||
|
};
|
||||||
|
|
||||||
const visible = await page.evaluate(element => element && element.offsetWidth > 0 && element.offsetHeight > 0, stockHandle);
|
if (store.labels.inStock) {
|
||||||
if (!visible) {
|
const options = {...baseOptions, requireVisible: true, type: 'outerHTML' as const};
|
||||||
return false;
|
|
||||||
|
if (!await pageIncludesLabels(page, store.labels.inStock, options)) {
|
||||||
|
Logger.info(Print.outOfStock(link, store, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stockContent = await page.evaluate(element => element.outerHTML, stockHandle);
|
if (store.labels.outOfStock) {
|
||||||
|
if (await pageIncludesLabels(page, store.labels.outOfStock, baseOptions)) {
|
||||||
Logger.debug(stockContent);
|
Logger.info(Print.outOfStock(link, store, true));
|
||||||
|
return false;
|
||||||
return includesLabels(stockContent, store.labels.inStock.text);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async function lookupPageHasCaptcha(store: Store, page: Page) {
|
|
||||||
if (!store.labels.captcha) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const captchaHandle = await page.$(store.labels.captcha.container);
|
if (store.labels.bannedSeller) {
|
||||||
const captchaContent = await page.evaluate(element => element.textContent, captchaHandle);
|
if (await pageIncludesLabels(page, store.labels.bannedSeller, baseOptions)) {
|
||||||
|
Logger.warn(Print.bannedSeller(link, store, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return includesLabels(captchaContent, store.labels.captcha.text);
|
if (store.labels.captcha) {
|
||||||
|
if (await pageIncludesLabels(page, store.labels.captcha, baseOptions)) {
|
||||||
|
Logger.warn(Print.captcha(link, store, true));
|
||||||
|
await delay(getSleepTime());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function tryLookupAndLoop(browser: Browser, store: Store) {
|
export async function tryLookupAndLoop(browser: Browser, store: Store) {
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
export interface Card {
|
||||||
|
brand: string;
|
||||||
|
model: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseCard(name: string): Card | null {
|
||||||
|
name = name.replace(/[^\w ]+/g, '').trim();
|
||||||
|
name = name.replace(/\bgraphics card\b/gi, '').trim();
|
||||||
|
name = name.replace(/\b\w+ fan\b/gi, '').trim();
|
||||||
|
name = name.replace(/\s{2,}/g, ' ');
|
||||||
|
|
||||||
|
let model = name.split(' ');
|
||||||
|
const brand = model.shift();
|
||||||
|
|
||||||
|
if (!brand) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some vendors have oc at the beginning of the product name,
|
||||||
|
// store whether the card contains the term "oc" and remove
|
||||||
|
// it during filtering, then add it to the end of the name.
|
||||||
|
let isOC = false;
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/prefer-regexp-exec */
|
||||||
|
model = model.filter(word => {
|
||||||
|
if (word.toLowerCase() === 'oc') {
|
||||||
|
isOC = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !word.match(/^(nvidia|geforce|rtx|amp[ae]re|graphics|card|gpu|pci-?e(xpress)?|ray-?tracing|ray|tracing|core|boost)$/i) &&
|
||||||
|
!word.match(/^(\d+(?:gb?|mhz)?|gb|mhz|g?ddr(\d+x?)?)$/i);
|
||||||
|
});
|
||||||
|
/* eslint-enable @typescript-eslint/prefer-regexp-exec */
|
||||||
|
|
||||||
|
if (isOC) {
|
||||||
|
model.push('OC');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
brand: brand.toLowerCase(),
|
||||||
|
model: model.join(' ').toLowerCase().replace(/ gaming\b/g, '').trim()
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
import {Browser, LoadEvent} from 'puppeteer';
|
import {Browser, LoadEvent} from 'puppeteer';
|
||||||
|
|
||||||
export type Element = {
|
export type Element = {
|
||||||
container: string;
|
container?: string;
|
||||||
text: string[];
|
text: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Series = 'test:series' | '3070' | '3080' | '3090';
|
||||||
|
|
||||||
export type Link = {
|
export type Link = {
|
||||||
brand: 'test:brand' | 'asus' | 'evga' | 'gigabyte' | 'pny' | 'msi' | 'nvidia' | 'zotac';
|
brand: 'test:brand' | 'asus' | 'evga' | 'gigabyte' | 'inno3d' | 'kfa2' | 'palit' | 'pny' | 'msi' | 'nvidia' | 'zotac';
|
||||||
series: 'test:series' | '3070' | '3080' | '3090';
|
series: Series;
|
||||||
model: string;
|
model: string;
|
||||||
url: string;
|
url: string;
|
||||||
cartUrl?: string;
|
cartUrl?: string;
|
||||||
@@ -15,13 +17,23 @@ export type Link = {
|
|||||||
screenshot?: string;
|
screenshot?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type LabelQuery = Element[] | Element | string[];
|
||||||
|
|
||||||
export type Labels = {
|
export type Labels = {
|
||||||
captcha?: Element;
|
bannedSeller?: LabelQuery;
|
||||||
inStock: Element;
|
captcha?: LabelQuery;
|
||||||
|
container?: string;
|
||||||
|
inStock?: LabelQuery;
|
||||||
|
outOfStock?: LabelQuery;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Store = {
|
export type Store = {
|
||||||
|
disableAdBlocker?: boolean;
|
||||||
links: Link[];
|
links: Link[];
|
||||||
|
linksBuilder?: {
|
||||||
|
builder: (docElement: cheerio.Cheerio, series: Series) => Link[];
|
||||||
|
urls: Array<{series: Series; url: string}>;
|
||||||
|
};
|
||||||
labels: Labels;
|
labels: Labels;
|
||||||
name: string;
|
name: string;
|
||||||
setupAction?: (browser: Browser) => void;
|
setupAction?: (browser: Browser) => void;
|
||||||
|
|||||||
+30
-1
@@ -1,5 +1,6 @@
|
|||||||
|
import {Browser, Page, Response} from 'puppeteer';
|
||||||
import {Config} from './config';
|
import {Config} from './config';
|
||||||
import {Page} from 'puppeteer';
|
import {Logger} from './logger';
|
||||||
import {disableBlockerInPage} from './adblocker';
|
import {disableBlockerInPage} from './adblocker';
|
||||||
|
|
||||||
export function getSleepTime() {
|
export function getSleepTime() {
|
||||||
@@ -12,6 +13,34 @@ export async function delay(ms: number) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function usingResponse<T>(
|
||||||
|
browser: Browser,
|
||||||
|
url: string,
|
||||||
|
cb: (response: (Response | null), page: Page, browser: Browser) => Promise<T>
|
||||||
|
): Promise<T> {
|
||||||
|
return usingPage(browser, async (page, browser) => {
|
||||||
|
const response = await page.goto(url, {waitUntil: 'domcontentloaded'});
|
||||||
|
|
||||||
|
return cb(response, page, browser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function usingPage<T>(browser: Browser, cb: (page: Page, browser: Browser) => Promise<T>): Promise<T> {
|
||||||
|
const page = await browser.newPage();
|
||||||
|
page.setDefaultNavigationTimeout(Config.page.navigationTimeout);
|
||||||
|
await page.setUserAgent(Config.page.userAgent);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await cb(page, browser);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
await closePage(page);
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function closePage(page: Page) {
|
export async function closePage(page: Page) {
|
||||||
await disableBlockerInPage(page);
|
await disableBlockerInPage(page);
|
||||||
await page.close();
|
await page.close();
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"lib": ["es6"],
|
"lib": ["es6", "dom"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"outDir": "build",
|
"outDir": "build",
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
|
|||||||
Reference in New Issue
Block a user