INIT: move uptime migration helper to own repository
This commit is contained in:
commit
4c567e247e
|
@ -0,0 +1,8 @@
|
||||||
|
# sample configuration for uptimeRobot to kuma migration
|
||||||
|
|
||||||
|
# get from UptimeRobotApi
|
||||||
|
UPTIME_ROBOT_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
|
||||||
|
KUMA_URL="http://localhost:3001"
|
||||||
|
KUMA_USERNAME="admin"
|
||||||
|
KUMA_PASSWORD="password2"
|
|
@ -0,0 +1,3 @@
|
||||||
|
dist/
|
||||||
|
node_modules/
|
||||||
|
.env
|
|
@ -0,0 +1,53 @@
|
||||||
|
# UptimeRobot to Kuma migration
|
||||||
|
|
||||||
|
We migrated from UptimeRobot to UptimeKuma, but there was no fast way to achieve this, so
|
||||||
|
we wrote our own small migration helper.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
Copy the `.env.sample` as `.env` and enter your UptimeRobot API key.
|
||||||
|
|
||||||
|
For testing, you can simply start UptimeKuma via Docker:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run --rm -p 3001:3001 --name uptime-kuma louislam/uptime-kuma:1
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensure you finished the initial setup (simply open [localhost:3001](localhost:3001) in your browser) and
|
||||||
|
updated the credentials in the `.env` file.
|
||||||
|
|
||||||
|
To start the migration run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# copy all your UptimeRobot monitors to your Kuma installation
|
||||||
|
yarn copy-monitors
|
||||||
|
|
||||||
|
# disable all UptimeRobot monitors
|
||||||
|
yarn disable-uptime-robot
|
||||||
|
|
||||||
|
# delete all your monitors from UptimeRobot
|
||||||
|
# DANGER!!! This is can not be undone
|
||||||
|
yarn delete-uptime-robot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Migration
|
||||||
|
|
||||||
|
**Important Node:** This migration helper was writen specially for our use-case. So not all UptimeRobot
|
||||||
|
scenarios and features are implemented. So no garantie this will work 100% for you.
|
||||||
|
|
||||||
|
**Pro Tipp:** Before migrating, create a default notification that will get used as default.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Fetching from UptimeRobot
|
||||||
|
|
||||||
|
This part was quite easy, because UptimeRobot got a good REST-API to fetch all monitors from
|
||||||
|
|
||||||
|
### Creating the monitors in Kuma
|
||||||
|
|
||||||
|
This was the hard part. Currently, Kuma does not provide any form of API. In the first version of this migration
|
||||||
|
helper, I tried to hook into the websocket connection of the UI and create monitors that way. This was really instabile
|
||||||
|
and resulted in many non-deterministic errors.
|
||||||
|
|
||||||
|
For this reason I switched to Playwright. This allows us the remote-control a browser, which will create
|
||||||
|
the monitors via the Kuma-UI.
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "kuma-migration",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"copy-monitors": "yarn build && node dist/index.js copy-monitors",
|
||||||
|
"disable-uptime-robot": "yarn build && node dist/index.js disable-uptime-robot",
|
||||||
|
"delete-uptime-robot": "yarn build && node dist/index.js delete-uptime-robot",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^18.11.18",
|
||||||
|
"playwright": "^1.29.2",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
|
"typescript": "^4.9.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "18.13.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.2.3",
|
||||||
|
"dotenv": "^16.0.3"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
import dotenv from "dotenv"
|
||||||
|
|
||||||
|
import {
|
||||||
|
UptimeRobotMonitor,
|
||||||
|
UptimeRobotGetMonitorResponse,
|
||||||
|
UptimeRobotEditMonitorResponse,
|
||||||
|
UptimeRobotDeleteMonitorResponse
|
||||||
|
} from "./types";
|
||||||
|
import {chromium, Page} from 'playwright';
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
dotenv.config()
|
||||||
|
|
||||||
|
const UPTIME_ROBOT_API_KEY = process.env.UPTIME_ROBOT_API_KEY
|
||||||
|
|
||||||
|
const KUMA_URL = process.env.KUMA_URL
|
||||||
|
const KUMA_USERNAME = process.env.KUMA_USERNAME
|
||||||
|
const KUMA_PASSWORD = process.env.KUMA_PASSWORD
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
!UPTIME_ROBOT_API_KEY ||
|
||||||
|
!KUMA_URL ||
|
||||||
|
!KUMA_USERNAME ||
|
||||||
|
!KUMA_PASSWORD
|
||||||
|
) {
|
||||||
|
console.warn('Required env variables are missing!')
|
||||||
|
console.warn('Copy ".env.sample" as ".env"')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const UPTIME_ROBOT_GET_MONITOR_API_PATH = "https://api.uptimerobot.com/v2/getMonitors?api_key="
|
||||||
|
|
||||||
|
const loadMonitorsFromUptimeRobot = async () => {
|
||||||
|
const monitors: UptimeRobotMonitor[] = []
|
||||||
|
|
||||||
|
let monitorCount = 0
|
||||||
|
let currentOffset = 0
|
||||||
|
let totalMonitors = 9999999
|
||||||
|
|
||||||
|
while (monitorCount < totalMonitors) {
|
||||||
|
const response = await axios.post(
|
||||||
|
UPTIME_ROBOT_GET_MONITOR_API_PATH + UPTIME_ROBOT_API_KEY,
|
||||||
|
`offset=${currentOffset}`
|
||||||
|
)
|
||||||
|
|
||||||
|
const jsonResponse = response.data as UptimeRobotGetMonitorResponse
|
||||||
|
|
||||||
|
totalMonitors = jsonResponse.pagination.total
|
||||||
|
currentOffset += 50
|
||||||
|
monitorCount += jsonResponse.monitors.length
|
||||||
|
monitors.push(...jsonResponse.monitors)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return monitors
|
||||||
|
}
|
||||||
|
|
||||||
|
const UPTIME_ROBOT_DISABLE_MONITOR_API_PATH = "https://api.uptimerobot.com/v2/editMonitor"
|
||||||
|
|
||||||
|
const disableUptimeRobotMonitor = async (monitor: UptimeRobotMonitor) => {
|
||||||
|
const response = await axios.post(
|
||||||
|
UPTIME_ROBOT_DISABLE_MONITOR_API_PATH,
|
||||||
|
new URLSearchParams({
|
||||||
|
'api_key': UPTIME_ROBOT_API_KEY,
|
||||||
|
'format': 'json',
|
||||||
|
'id': `${monitor.id}`,
|
||||||
|
'status': '0'
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Cache-Control': 'no-cache'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const responseJson = response.data as UptimeRobotEditMonitorResponse
|
||||||
|
if (responseJson?.stat === "fail") {
|
||||||
|
console.error(`Failed to edit monitor '${monitor.friendly_name}' due to '${responseJson.error?.type}'`)
|
||||||
|
process.exit(1)
|
||||||
|
} else {
|
||||||
|
console.log(`Disabled monitor "${monitor.friendly_name}"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UPTIME_ROBOT_DELETE_MONITOR_API_PATH = "https://api.uptimerobot.com/v2/deleteMonitor"
|
||||||
|
const deleteUptimeRobotMonitor = async (monitor: UptimeRobotMonitor) => {
|
||||||
|
const response = await axios.post(
|
||||||
|
UPTIME_ROBOT_DELETE_MONITOR_API_PATH,
|
||||||
|
new URLSearchParams({
|
||||||
|
'api_key': UPTIME_ROBOT_API_KEY,
|
||||||
|
'format': 'json',
|
||||||
|
'id': `${monitor.id}`,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Cache-Control': 'no-cache'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const responseJson = response.data as UptimeRobotDeleteMonitorResponse
|
||||||
|
if (responseJson?.stat === "fail") {
|
||||||
|
console.error(`Failed to delete monitor '${monitor.friendly_name}' due to '${responseJson.error?.type}'`)
|
||||||
|
process.exit(1)
|
||||||
|
} else {
|
||||||
|
console.log(`Deleted monitor "${monitor.friendly_name}"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPlaywright = async () => chromium.launch({headless: false})
|
||||||
|
|
||||||
|
const ensureLoggedIn = async (page: Page) => {
|
||||||
|
const loginButton = await page.getByText("Login")
|
||||||
|
|
||||||
|
if (loginButton == null) {
|
||||||
|
console.log('already logged in ...')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.getByPlaceholder('Username').type(KUMA_USERNAME)
|
||||||
|
await page.getByPlaceholder('Password').type(KUMA_PASSWORD)
|
||||||
|
|
||||||
|
await loginButton.click()
|
||||||
|
await page.waitForLoadState("domcontentloaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
const createMonitor = async (page: Page, monitor: UptimeRobotMonitor) => {
|
||||||
|
await page.waitForLoadState('domcontentloaded')
|
||||||
|
await page.waitForLoadState('networkidle')
|
||||||
|
|
||||||
|
await page.getByText('Add New Monitor').first().click()
|
||||||
|
|
||||||
|
const createButton = await page.$('a:text(" Add New Monitor")')
|
||||||
|
await createButton?.click()
|
||||||
|
|
||||||
|
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.getByLabel('Friendly Name').first().fill(monitor.friendly_name)
|
||||||
|
|
||||||
|
switch (monitor.type) {
|
||||||
|
case 1:
|
||||||
|
await createMonitorHTTP(page, monitor)
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
await createMonitorKeyword(page, monitor)
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
await createMonitorPort(page, monitor)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
console.log(`Monitor type ${monitor.type} of ${monitor.friendly_name} is not supported`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.getByLabel('Heartbeat Interval (Check every').fill(String(monitor.interval))
|
||||||
|
|
||||||
|
const saveButton = await page.$('button#monitor-submit-btn')
|
||||||
|
await saveButton?.click()
|
||||||
|
|
||||||
|
await page.waitForLoadState("domcontentloaded")
|
||||||
|
await page.waitForLoadState("networkidle")
|
||||||
|
|
||||||
|
await page.waitForTimeout(400)
|
||||||
|
|
||||||
|
console.log('Created Monitor ', monitor.friendly_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
const createMonitorHTTP = async (page: Page, monitor: UptimeRobotMonitor) => {
|
||||||
|
await page.getByLabel("Monitor Type").selectOption("HTTP(s)")
|
||||||
|
await page.getByLabel('URL').fill(monitor.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
const createMonitorKeyword = async (page: Page, monitor: UptimeRobotMonitor) => {
|
||||||
|
await page.getByLabel("Monitor Type").selectOption("HTTP(s) - Keyword")
|
||||||
|
await page.getByLabel('URL').fill(monitor.url)
|
||||||
|
await page.getByLabel('Keyword').fill(monitor.keyword_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const createMonitorPort = async (page: Page, monitor: UptimeRobotMonitor) => {
|
||||||
|
await page.getByLabel("Monitor Type").selectOption("TCP Port")
|
||||||
|
await page.getByLabel('Hostname').fill(monitor.url)
|
||||||
|
await page.getByLabel('Port').fill(String(monitor.port))
|
||||||
|
}
|
||||||
|
|
||||||
|
const copyMonitors = async () => {
|
||||||
|
const monitors = await loadMonitorsFromUptimeRobot()
|
||||||
|
console.log(`Found ${monitors.length} monitors`)
|
||||||
|
|
||||||
|
const browser = await startPlaywright()
|
||||||
|
const page = await browser.newPage()
|
||||||
|
await page.goto(KUMA_URL)
|
||||||
|
|
||||||
|
await ensureLoggedIn(page)
|
||||||
|
|
||||||
|
for (let monitor of monitors) {
|
||||||
|
await createMonitor(page, monitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
await browser.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
const disableUptimeRobot = async () => {
|
||||||
|
const monitors = await loadMonitorsFromUptimeRobot()
|
||||||
|
console.log(`Found ${monitors.length} monitors`)
|
||||||
|
|
||||||
|
for (let monitor of monitors) {
|
||||||
|
await disableUptimeRobotMonitor(monitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteUptimeRobotMonitors = async () => {
|
||||||
|
const monitors = await loadMonitorsFromUptimeRobot()
|
||||||
|
console.log(`Found ${monitors.length} monitors`)
|
||||||
|
|
||||||
|
for (let monitor of monitors) {
|
||||||
|
await deleteUptimeRobotMonitor(monitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const run = async () => {
|
||||||
|
const task = process.argv[2]
|
||||||
|
|
||||||
|
switch (task) {
|
||||||
|
case 'copy-monitors':
|
||||||
|
await copyMonitors()
|
||||||
|
break
|
||||||
|
case 'disable-uptime-robot':
|
||||||
|
await disableUptimeRobot()
|
||||||
|
break
|
||||||
|
case 'delete-uptime-robot':
|
||||||
|
await deleteUptimeRobotMonitors()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
console.error(`Task '${task} is not supported ...'`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
|
@ -0,0 +1,43 @@
|
||||||
|
export interface UptimeRobotMonitor {
|
||||||
|
id: number;
|
||||||
|
friendly_name: string;
|
||||||
|
url: string;
|
||||||
|
type: number;
|
||||||
|
sub_type: string;
|
||||||
|
keyword_type: null;
|
||||||
|
keyword_case_type: number;
|
||||||
|
keyword_value: string;
|
||||||
|
port: string;
|
||||||
|
interval: number;
|
||||||
|
timeout: number;
|
||||||
|
status: number;
|
||||||
|
create_datetime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UptimeRobotPagination {
|
||||||
|
offset: number;
|
||||||
|
limit: number;
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UptimeRobotGetMonitorResponse {
|
||||||
|
stat: 'OK' | 'fail';
|
||||||
|
pagination: UptimeRobotPagination;
|
||||||
|
monitors: UptimeRobotMonitor[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UptimeRobotEditMonitorResponse {
|
||||||
|
stat: 'OK' | 'fail';
|
||||||
|
error?: {
|
||||||
|
type: 'not_authorized',
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UptimeRobotDeleteMonitorResponse {
|
||||||
|
stat: 'OK' | 'fail';
|
||||||
|
error?: {
|
||||||
|
type: 'not_authorized',
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "NodeNext",
|
||||||
|
"target": "ESNext",
|
||||||
|
"lib": ["ESNext", "DOM"],
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"sourceMap": false,
|
||||||
|
"outDir": "dist",
|
||||||
|
},
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@cspotcode/source-map-support@^0.8.0":
|
||||||
|
version "0.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
|
||||||
|
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/trace-mapping" "0.3.9"
|
||||||
|
|
||||||
|
"@jridgewell/resolve-uri@^3.0.3":
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
|
||||||
|
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec@^1.4.10":
|
||||||
|
version "1.4.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
|
||||||
|
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
|
||||||
|
|
||||||
|
"@jridgewell/trace-mapping@0.3.9":
|
||||||
|
version "0.3.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
|
||||||
|
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/resolve-uri" "^3.0.3"
|
||||||
|
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||||
|
|
||||||
|
"@tsconfig/node10@^1.0.7":
|
||||||
|
version "1.0.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
|
||||||
|
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
|
||||||
|
|
||||||
|
"@tsconfig/node12@^1.0.7":
|
||||||
|
version "1.0.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
|
||||||
|
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
|
||||||
|
|
||||||
|
"@tsconfig/node14@^1.0.0":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
|
||||||
|
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
|
||||||
|
|
||||||
|
"@tsconfig/node16@^1.0.2":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
|
||||||
|
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
|
||||||
|
|
||||||
|
"@types/node@^18.11.18":
|
||||||
|
version "18.11.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
|
||||||
|
integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
|
||||||
|
|
||||||
|
acorn-walk@^8.1.1:
|
||||||
|
version "8.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||||
|
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||||
|
|
||||||
|
acorn@^8.4.1:
|
||||||
|
version "8.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
|
||||||
|
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
|
||||||
|
|
||||||
|
arg@^4.1.0:
|
||||||
|
version "4.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||||
|
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||||
|
|
||||||
|
asynckit@^0.4.0:
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
|
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||||
|
|
||||||
|
axios@^1.2.3:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.3.tgz#31a3d824c0ebf754a004b585e5f04a5f87e6c4ff"
|
||||||
|
integrity sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==
|
||||||
|
dependencies:
|
||||||
|
follow-redirects "^1.15.0"
|
||||||
|
form-data "^4.0.0"
|
||||||
|
proxy-from-env "^1.1.0"
|
||||||
|
|
||||||
|
combined-stream@^1.0.8:
|
||||||
|
version "1.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||||
|
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||||
|
dependencies:
|
||||||
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
|
create-require@^1.1.0:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||||
|
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||||
|
|
||||||
|
delayed-stream@~1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||||
|
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||||
|
|
||||||
|
diff@^4.0.1:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||||
|
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||||
|
|
||||||
|
dotenv@^16.0.3:
|
||||||
|
version "16.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
|
||||||
|
integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==
|
||||||
|
|
||||||
|
follow-redirects@^1.15.0:
|
||||||
|
version "1.15.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
|
||||||
|
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
|
||||||
|
|
||||||
|
form-data@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||||
|
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||||
|
dependencies:
|
||||||
|
asynckit "^0.4.0"
|
||||||
|
combined-stream "^1.0.8"
|
||||||
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
|
make-error@^1.1.1:
|
||||||
|
version "1.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||||
|
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||||
|
|
||||||
|
mime-db@1.52.0:
|
||||||
|
version "1.52.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||||
|
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||||
|
|
||||||
|
mime-types@^2.1.12:
|
||||||
|
version "2.1.35"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||||
|
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||||
|
dependencies:
|
||||||
|
mime-db "1.52.0"
|
||||||
|
|
||||||
|
playwright-core@1.29.2:
|
||||||
|
version "1.29.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.29.2.tgz#2e8347e7e8522409f22b244e600e703b64022406"
|
||||||
|
integrity sha512-94QXm4PMgFoHAhlCuoWyaBYKb92yOcGVHdQLoxQ7Wjlc7Flg4aC/jbFW7xMR52OfXMVkWicue4WXE7QEegbIRA==
|
||||||
|
|
||||||
|
playwright@^1.29.2:
|
||||||
|
version "1.29.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.29.2.tgz#d6a0a3e8e44f023f7956ed19ffa8af915a042769"
|
||||||
|
integrity sha512-hKBYJUtdmYzcjdhYDkP9WGtORwwZBBKAW8+Lz7sr0ZMxtJr04ASXVzH5eBWtDkdb0c3LLFsehfPBTRfvlfKJOA==
|
||||||
|
dependencies:
|
||||||
|
playwright-core "1.29.2"
|
||||||
|
|
||||||
|
proxy-from-env@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||||
|
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||||
|
|
||||||
|
ts-node@^10.9.1:
|
||||||
|
version "10.9.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
|
||||||
|
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
|
||||||
|
dependencies:
|
||||||
|
"@cspotcode/source-map-support" "^0.8.0"
|
||||||
|
"@tsconfig/node10" "^1.0.7"
|
||||||
|
"@tsconfig/node12" "^1.0.7"
|
||||||
|
"@tsconfig/node14" "^1.0.0"
|
||||||
|
"@tsconfig/node16" "^1.0.2"
|
||||||
|
acorn "^8.4.1"
|
||||||
|
acorn-walk "^8.1.1"
|
||||||
|
arg "^4.1.0"
|
||||||
|
create-require "^1.1.0"
|
||||||
|
diff "^4.0.1"
|
||||||
|
make-error "^1.1.1"
|
||||||
|
v8-compile-cache-lib "^3.0.1"
|
||||||
|
yn "3.1.1"
|
||||||
|
|
||||||
|
typescript@^4.9.4:
|
||||||
|
version "4.9.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
|
||||||
|
integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
|
||||||
|
|
||||||
|
v8-compile-cache-lib@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||||
|
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
|
||||||
|
|
||||||
|
yn@3.1.1:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||||
|
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
Loading…
Reference in New Issue