Merge pull request #3 from meienberger/feature/install-app
Feature/install app
This commit is contained in:
commit
206b822cac
106 changed files with 2915 additions and 518 deletions
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[![forthebadge](https://svgshare.com/i/g4Y.svg)](https://forthebadge.com)
|
|
@ -5,9 +5,8 @@ packages:
|
||||||
- iptables
|
- iptables
|
||||||
- coreutils
|
- coreutils
|
||||||
- git
|
- git
|
||||||
- base-devel
|
|
||||||
- docker
|
- docker
|
||||||
- avahi
|
- avahi-daemon
|
||||||
- nodejs
|
- nodejs
|
||||||
- npm
|
- npm
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,33 @@
|
||||||
- name: Install docker
|
- name: Install docker
|
||||||
package:
|
package:
|
||||||
name: docker
|
name:
|
||||||
|
- docker
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- gnupg
|
||||||
|
- lsb-release
|
||||||
state: latest
|
state: latest
|
||||||
|
|
||||||
|
- name: Add docker gpg key
|
||||||
|
shell: curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
|
||||||
|
- name: Check lsb_release -cs
|
||||||
|
shell: lsb_release -cs
|
||||||
|
register: lsb_release
|
||||||
|
|
||||||
|
- name: Add deb for bookworm release
|
||||||
|
shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
when: lsb_release.stdout == "bookworm"
|
||||||
|
|
||||||
|
- name: Add deb for non-bookworm
|
||||||
|
shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
when: lsb_release.stdout != "bookworm"
|
||||||
|
|
||||||
|
- name: Update packages
|
||||||
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
upgrade: yes
|
||||||
|
|
||||||
- name: Install essential packages
|
- name: Install essential packages
|
||||||
package:
|
package:
|
||||||
name:
|
name:
|
||||||
|
@ -24,6 +49,20 @@
|
||||||
- name: Make docker-compose executable
|
- name: Make docker-compose executable
|
||||||
shell: chmod +x /usr/local/bin/docker-compose
|
shell: chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# - name: Disable iptables for docker by editing file /etc/default/docker
|
||||||
|
# lineinfile:
|
||||||
|
# path: /etc/default/docker
|
||||||
|
# regexp: "^DOCKER_OPTS="
|
||||||
|
# line: "DOCKER_OPTS=\"--iptables=false\""
|
||||||
|
# state: present
|
||||||
|
|
||||||
|
# - name: Create file /etc/docker/daemon.json with content hello world written inside
|
||||||
|
# lineinfile:
|
||||||
|
# path: /etc/docker/daemon.json
|
||||||
|
# regexp: "^"
|
||||||
|
# line: "{ \"iptables\": false }"
|
||||||
|
# state: present
|
||||||
|
|
||||||
- name: Create group docker
|
- name: Create group docker
|
||||||
group:
|
group:
|
||||||
name: docker
|
name: docker
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
- name: Change machine hostname to tipi.local
|
- name: Change machine hostname to tipi.local
|
||||||
shell: hostnamectl set-hostname tipi.local
|
shell: hostnamectl set-hostname tipi.local
|
||||||
|
|
||||||
- name: Update packages
|
# - name: Update packages
|
||||||
become: yes
|
# apt:
|
||||||
pacman:
|
# update_cache: yes
|
||||||
update_cache: yes
|
# upgrade: yes
|
||||||
upgrade: yes
|
|
||||||
|
|
||||||
- name: Add user to root group
|
|
||||||
user:
|
|
||||||
name: "{{ username }}"
|
|
||||||
group: root
|
|
||||||
|
|
||||||
- name: Install essential packages
|
- name: Install essential packages
|
||||||
package:
|
package:
|
||||||
name: "{{ packages }}"
|
name: "{{ packages }}"
|
||||||
state: latest
|
state: latest
|
||||||
|
|
||||||
|
- name: Add user to root group
|
||||||
|
user:
|
||||||
|
name: "{{ username }}"
|
||||||
|
group: root
|
||||||
|
|
||||||
- name: Disable SSH password auth
|
- name: Disable SSH password auth
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- name: Install "pm2" package globally.
|
- name: Install "pm2" package globally.
|
||||||
community.general.npm:
|
community.general.npm:
|
||||||
name: yarn
|
name: pm2
|
||||||
global: yes
|
global: yes
|
||||||
|
|
||||||
- name: Run pm2 first time
|
- name: Run pm2 first time
|
||||||
|
|
45
apps/anonaddy/config.json
Normal file
45
apps/anonaddy/config.json
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"name": "Anonaddy",
|
||||||
|
"port": 8084,
|
||||||
|
"id": "anonaddy",
|
||||||
|
"description": "",
|
||||||
|
"short_desc": "Anonymous email forwarding",
|
||||||
|
"author": "",
|
||||||
|
"source": "https://github.com/anonaddy/anonaddy",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/51450862?s=200&v=4",
|
||||||
|
"requirements": {
|
||||||
|
"ports": [25]
|
||||||
|
},
|
||||||
|
"form_fields": {
|
||||||
|
"username": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "Username",
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "ANONADDY_USERNAME"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "App key",
|
||||||
|
"hint": "Application key for encrypter service. Generate one with : echo \"base64:$(openssl rand -base64 32)\"",
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "ANONADDY_KEY"
|
||||||
|
},
|
||||||
|
"domain": {
|
||||||
|
"type": "fqdn",
|
||||||
|
"label": "Your email domain (eg. example.com)",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "ANONADDY_DOMAIN"
|
||||||
|
},
|
||||||
|
"secret": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "App secret",
|
||||||
|
"hint": "Long random string used when hashing data for the anonymous replies",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "ANONADDY_SECRET"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,29 +32,32 @@ services:
|
||||||
container_name: anonaddy
|
container_name: anonaddy
|
||||||
ports:
|
ports:
|
||||||
- 25:25
|
- 25:25
|
||||||
- ${APP_ANONADDY_PORT}:8000
|
- ${APP_PORT}:8000
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- redis
|
- redis
|
||||||
volumes:
|
volumes:
|
||||||
- "${APP_DATA_DIR}/data:/data"
|
- "${APP_DATA_DIR}/data:/data"
|
||||||
environment:
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
DB_HOST: db-anonaddy
|
DB_HOST: db-anonaddy
|
||||||
DB_PASSWORD: anonaddy
|
DB_PASSWORD: anonaddy
|
||||||
REDIS_HOST: redis-anonaddy
|
REDIS_HOST: redis-anonaddy
|
||||||
APP_KEY: ${APP_ANONADDY_KEY}
|
APP_KEY: ${ANONADDY_KEY}
|
||||||
ANONADDY_DOMAIN: ${APP_ANONADDY_DOMAIN}
|
ANONADDY_DOMAIN: ${ANONADDY_DOMAIN}
|
||||||
ANONADDY_SECRET: ${APP_ANONADDY_SECRET}
|
ANONADDY_SECRET: ${ANONADDY_SECRET}
|
||||||
|
ANONADDY_ADMIN_USERNAME: ${ANONADDY_USERNAME}
|
||||||
|
POSTFIX_DEBUG: true
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- tipi_main_network
|
- tipi_main_network
|
||||||
labels:
|
# labels:
|
||||||
traefik.enable: true
|
# traefik.enable: true
|
||||||
traefik.http.routers.anonaddy.rule: Host(`anonaddy.tipi.home`)
|
# traefik.http.routers.anonaddy.rule: Host(`anonaddy.tipi.home`)
|
||||||
traefik.http.routers.anonaddy.tls: true
|
# traefik.http.routers.anonaddy.tls: true
|
||||||
traefik.http.routers.anonaddy.entrypoints: websecure
|
# traefik.http.routers.anonaddy.entrypoints: websecure
|
||||||
traefik.http.routers.anonaddy.service: anonaddy
|
# traefik.http.routers.anonaddy.service: anonaddy
|
||||||
traefik.http.services.anonaddy.loadbalancer.server.port: 8000
|
# traefik.http.services.anonaddy.loadbalancer.server.port: 8000
|
||||||
# labels:
|
# labels:
|
||||||
# traefik.enable: true
|
# traefik.enable: true
|
||||||
# traefik.http.routers.anonaddy.rule: PathPrefix(`/anonaddy`)
|
# traefik.http.routers.anonaddy.rule: PathPrefix(`/anonaddy`)
|
||||||
|
|
11
apps/busybox/config.json
Normal file
11
apps/busybox/config.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "BusyBox",
|
||||||
|
"port": 3000,
|
||||||
|
"id": "busybox",
|
||||||
|
"description": "",
|
||||||
|
"short_desc": "",
|
||||||
|
"author": "",
|
||||||
|
"source": "",
|
||||||
|
"image": "https://raw.githubusercontent.com/docker-library/docs/cc5d5e47fd7e0c57c9b8de4c1bfb6258e0dac85d/busybox/logo.png",
|
||||||
|
"form_fields": {}
|
||||||
|
}
|
6
apps/busybox/docker-compose.yml
Normal file
6
apps/busybox/docker-compose.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
version: "3.7"
|
||||||
|
services:
|
||||||
|
test:
|
||||||
|
image: meienberger/ubuntu-test
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
|
@ -2,5 +2,4 @@ version: "3.7"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
tipi_main_network:
|
tipi_main_network:
|
||||||
external:
|
|
||||||
name: runtipi_tipi_main_network
|
name: runtipi_tipi_main_network
|
11
apps/filerun/config.json
Normal file
11
apps/filerun/config.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "FileRun",
|
||||||
|
"port": 8087,
|
||||||
|
"id": "filerun",
|
||||||
|
"description": "Reliable and Performant File Management Desktop Sync and File Sharing",
|
||||||
|
"short_desc": "Access your homeserver files from your browser",
|
||||||
|
"author": "FileRun, LDA - Portugal",
|
||||||
|
"source": "https://www.filerun.com/",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/6422152?v=4",
|
||||||
|
"form_fields": {}
|
||||||
|
}
|
38
apps/filerun/docker-compose.yml
Normal file
38
apps/filerun/docker-compose.yml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
services:
|
||||||
|
filerun-db:
|
||||||
|
container_name: filerun-db
|
||||||
|
image: mariadb:10.1
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: tipi
|
||||||
|
MYSQL_USER: tipi
|
||||||
|
MYSQL_PASSWORD: tipi
|
||||||
|
MYSQL_DATABASE: tipi
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/db:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
||||||
|
|
||||||
|
filerun:
|
||||||
|
container_name: filerun
|
||||||
|
image: filerun/filerun:arm64v8
|
||||||
|
environment:
|
||||||
|
FR_DB_HOST: filerun-db
|
||||||
|
FR_DB_PORT: 3306
|
||||||
|
FR_DB_NAME: tipi
|
||||||
|
FR_DB_USER: tipi
|
||||||
|
FR_DB_PASS: tipi
|
||||||
|
APACHE_RUN_USER: ${PUID}
|
||||||
|
APACHE_RUN_GROUP: ${PGID}
|
||||||
|
APACHE_RUN_USER_ID: 33
|
||||||
|
APACHE_RUN_GROUP_ID: 33
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
links:
|
||||||
|
- db:db
|
||||||
|
ports:
|
||||||
|
- ${APP_PORT}:80
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/html:/var/www/html
|
||||||
|
- ${ROOT_FOLDER}/app-data:/user-files
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
11
apps/freshrss/config.json
Normal file
11
apps/freshrss/config.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "FreshRSS",
|
||||||
|
"port": 8086,
|
||||||
|
"id": "freshrss",
|
||||||
|
"description": "FreshRSS is a self-hosted RSS feed aggregator like Leed or Kriss Feed.\nIt is lightweight, easy to work with, powerful, and customizable.\n\nIt is a multi-user application with an anonymous reading mode. It supports custom tags. There is an API for (mobile) clients, and a Command-Line Interface.\n\nThanks to the WebSub standard (formerly PubSubHubbub), FreshRSS is able to receive instant push notifications from compatible sources, such as Mastodon, Friendica, WordPress, Blogger, FeedBurner, etc.\n\nFreshRSS natively supports basic Web scraping, based on XPath, for Web sites not providing any RSS / Atom feed.\n\nFinally, it supports extensions for further tuning.",
|
||||||
|
"short_desc": "A free, self-hostable aggregator… ",
|
||||||
|
"author": "https://freshrss.org/",
|
||||||
|
"source": "https://github.com/FreshRSS/FreshRSS",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/9414285?s=200&v=4",
|
||||||
|
"form_fields": {}
|
||||||
|
}
|
|
@ -6,19 +6,19 @@ services:
|
||||||
image: freshrss/freshrss:arm
|
image: freshrss/freshrss:arm
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "${APP_FRESHRSS_PORT}:80"
|
- ${APP_PORT}:80
|
||||||
volumes:
|
volumes:
|
||||||
- ${APP_DATA_DIR}/data/:/var/www/FreshRSS/data
|
- ${APP_DATA_DIR}/data/freshrss:/var/www/FreshRSS/data
|
||||||
- ${APP_DATA_DIR}/extensions/:/var/www/FreshRSS/extensions
|
- ${APP_DATA_DIR}/data/extensions/:/var/www/FreshRSS/extensions
|
||||||
environment:
|
environment:
|
||||||
CRON_MIN: '*/20'
|
CRON_MIN: '*/20'
|
||||||
TZ: $TZ
|
TZ: $TZ
|
||||||
networks:
|
networks:
|
||||||
- tipi_main_network
|
- tipi_main_network
|
||||||
labels:
|
# labels:
|
||||||
traefik.enable: true
|
# traefik.enable: true
|
||||||
traefik.http.routers.freshrss.rule: Host(`freshrss.tipi.home`)
|
# traefik.http.routers.freshrss.rule: Host(`freshrss.tipi.home`)
|
||||||
traefik.http.routers.freshrss.service: freshrss
|
# traefik.http.routers.freshrss.service: freshrss
|
||||||
traefik.http.routers.freshrss.tls: true
|
# traefik.http.routers.freshrss.tls: true
|
||||||
traefik.http.routers.freshrss.entrypoints: websecure
|
# traefik.http.routers.freshrss.entrypoints: websecure
|
||||||
traefik.http.services.freshrss.loadbalancer.server.port: 80
|
# traefik.http.services.freshrss.loadbalancer.server.port: 80
|
11
apps/jellyfin/config.json
Normal file
11
apps/jellyfin/config.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "Jellyfin",
|
||||||
|
"port": 8091,
|
||||||
|
"id": "jellyfin",
|
||||||
|
"description": "",
|
||||||
|
"short_desc": "",
|
||||||
|
"author": "",
|
||||||
|
"source": "",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/45698031?s=200&v=4",
|
||||||
|
"form_fields": {}
|
||||||
|
}
|
18
apps/jellyfin/docker-compose.yml
Normal file
18
apps/jellyfin/docker-compose.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
jellyfin:
|
||||||
|
image: lscr.io/linuxserver/jellyfin
|
||||||
|
container_name: jellyfin
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/config:/config
|
||||||
|
- ${APP_DATA_DIR}/data/media:/data/media
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=${TZ}
|
||||||
|
restart: "unless-stopped"
|
||||||
|
ports:
|
||||||
|
- ${APP_PORT}:8096
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
|
@ -1,6 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "Nextcloud",
|
"name": "Nextcloud",
|
||||||
|
"port": 8083,
|
||||||
|
"id": "nextcloud",
|
||||||
"description": "Nextcloud is a self-hosted, open source, and fully-featured cloud storage solution for your personal files, office documents, and photos.",
|
"description": "Nextcloud is a self-hosted, open source, and fully-featured cloud storage solution for your personal files, office documents, and photos.",
|
||||||
|
"short_desc": "Productivity platform that keeps you in control",
|
||||||
|
"author": "Nextcloud GmbH",
|
||||||
|
"source": "https://github.com/nextcloud/server",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/19211038?s=200&v=4",
|
||||||
"form_fields": {
|
"form_fields": {
|
||||||
"username": {
|
"username": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -8,7 +14,7 @@
|
||||||
"max": 50,
|
"max": 50,
|
||||||
"min": 3,
|
"min": 3,
|
||||||
"required": true,
|
"required": true,
|
||||||
"env_variable": "NEXTCLOUD_USERNAME"
|
"env_variable": "NEXTCLOUD_ADMIN_USER"
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "password",
|
"type": "password",
|
||||||
|
@ -16,7 +22,7 @@
|
||||||
"max": 50,
|
"max": 50,
|
||||||
"min": 3,
|
"min": 3,
|
||||||
"required": true,
|
"required": true,
|
||||||
"env_variable": "NEXTCLOUD_PASSWORD"
|
"env_variable": "NEXTCLOUD_ADMIN_PASSWORD"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,24 +3,21 @@ version: "3.7"
|
||||||
services:
|
services:
|
||||||
db-nextcloud:
|
db-nextcloud:
|
||||||
container_name: db-nextcloud
|
container_name: db-nextcloud
|
||||||
# user: '1000:1000'
|
image: postgres:14.2
|
||||||
image: mariadb:10.5.12
|
|
||||||
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
|
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- ${APP_DATA_DIR}/data/db:/var/lib/mysql
|
- ${APP_DATA_DIR}/data/db:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_ROOT_PASSWORD=password
|
- POSTGRES_PASSWORD=tipi
|
||||||
- MYSQL_PASSWORD=password
|
- POSTGRES_USER=tipi
|
||||||
- MYSQL_DATABASE=nextcloud
|
- POSTGRES_DB=nextcloud
|
||||||
- MYSQL_USER=nextcloud
|
|
||||||
networks:
|
networks:
|
||||||
- tipi_main_network
|
- tipi_main_network
|
||||||
|
|
||||||
redis-nextcloud:
|
redis-nextcloud:
|
||||||
container_name: redis-nextcloud
|
container_name: redis-nextcloud
|
||||||
# user: '1000:1000'
|
user: "1000:1000"
|
||||||
image: redis:6.2.2-buster
|
image: redis:6.2.6
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- "${APP_DATA_DIR}/data/redis:/data"
|
- "${APP_DATA_DIR}/data/redis:/data"
|
||||||
|
@ -28,7 +25,7 @@ services:
|
||||||
- tipi_main_network
|
- tipi_main_network
|
||||||
|
|
||||||
cron:
|
cron:
|
||||||
image: nextcloud:22.0.0-apache
|
image: nextcloud:23.0.3-apache
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
|
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
|
||||||
|
@ -40,23 +37,23 @@ services:
|
||||||
- tipi_main_network
|
- tipi_main_network
|
||||||
|
|
||||||
nextcloud:
|
nextcloud:
|
||||||
user: root
|
|
||||||
container_name: nextcloud
|
container_name: nextcloud
|
||||||
image: nextcloud:22.1.1-apache
|
image: nextcloud:23.0.3-apache
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- ${APP_NEXTCLOUD_PORT}:80
|
- ${APP_PORT}:80
|
||||||
volumes:
|
volumes:
|
||||||
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
|
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
|
||||||
|
- /volumes/nfs:/nfs
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_HOST=db-nextcloud
|
- POSTGRES_HOST=db-nextcloud
|
||||||
- REDIS_HOST=redis-nextcloud
|
- REDIS_HOST=redis-nextcloud
|
||||||
- MYSQL_PASSWORD=password
|
- POSTGRES_PASSWORD=tipi
|
||||||
- MYSQL_DATABASE=nextcloud
|
- POSTGRES_USER=tipi
|
||||||
- MYSQL_USER=nextcloud
|
- POSTGRES_DB=nextcloud
|
||||||
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
|
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
|
||||||
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
|
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
|
||||||
- NEXTCLOUD_TRUSTED_DOMAINS=tipi.local
|
- NEXTCLOUD_TRUSTED_DOMAINS=tipi.local ${DEVICE_IP}:${APP_PORT}
|
||||||
depends_on:
|
depends_on:
|
||||||
- db-nextcloud
|
- db-nextcloud
|
||||||
- redis-nextcloud
|
- redis-nextcloud
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
## DNS Over TLS, Simple ENCRYPTED recursive caching DNS, TCP port 853
|
|
||||||
## unbound.conf, original at https://calomel.org/unbound_dns.html
|
|
||||||
# tweaks by bartonbytes.com
|
|
||||||
server:
|
|
||||||
access-control: 127.0.0.0/8 allow
|
|
||||||
cache-max-ttl: 14400
|
|
||||||
cache-min-ttl: 600
|
|
||||||
do-tcp: yes
|
|
||||||
hide-identity: yes
|
|
||||||
hide-version: yes
|
|
||||||
interface: 127.0.0.1
|
|
||||||
minimal-responses: yes
|
|
||||||
prefetch: yes
|
|
||||||
qname-minimisation: yes
|
|
||||||
rrset-roundrobin: yes
|
|
||||||
ssl-upstream: yes
|
|
||||||
use-caps-for-id: yes
|
|
||||||
verbosity: 1
|
|
||||||
port: 5533
|
|
||||||
#
|
|
||||||
forward-zone:
|
|
||||||
name: "."
|
|
||||||
forward-addr: 194.242.2.3@853 # Mullvad primary
|
|
||||||
forward-addr: 193.19.108.3@853 # Mullvad secondary
|
|
|
@ -1,34 +0,0 @@
|
||||||
version: "3.7"
|
|
||||||
|
|
||||||
services:
|
|
||||||
unbound:
|
|
||||||
user: '1000:1000'
|
|
||||||
image: "klutchell/unbound:latest"
|
|
||||||
volumes:
|
|
||||||
- ${APP_DATA_DIR}/data/unbound:/etc/unbound
|
|
||||||
networks:
|
|
||||||
- tipi_main_network
|
|
||||||
|
|
||||||
pihole:
|
|
||||||
image: pihole/pihole
|
|
||||||
restart: on-failure
|
|
||||||
ports:
|
|
||||||
- 53:53
|
|
||||||
- 53:53/udp
|
|
||||||
- ${APP_PI_HOLE_PORT}:80
|
|
||||||
volumes:
|
|
||||||
- ${APP_DATA_DIR}/data/pihole:/etc/pihole/
|
|
||||||
- ${APP_DATA_DIR}/data/dnsmasq:/etc/dnsmasq.d/
|
|
||||||
environment:
|
|
||||||
- VIRTUAL_HOST="pihole.${DOMAIN}"
|
|
||||||
- WEBPASSWORD=${APP_PASSWORD}
|
|
||||||
- PIHOLE_DNS=unbound
|
|
||||||
depends_on:
|
|
||||||
- unbound
|
|
||||||
networks:
|
|
||||||
- tipi_main_network
|
|
||||||
labels:
|
|
||||||
traefik.enable: true
|
|
||||||
traefik.http.routers.traefik.rule: Host(`pihole.${DOMAIN}`)
|
|
||||||
traefik.http.services.traefik.loadbalancer.server.port: $APP_PI_HOLE_PORT
|
|
||||||
|
|
23
apps/pihole/config.json
Normal file
23
apps/pihole/config.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "PiHole",
|
||||||
|
"port": 8081,
|
||||||
|
"requirements": {
|
||||||
|
"ports": [53]
|
||||||
|
},
|
||||||
|
"id": "pihole",
|
||||||
|
"description": "",
|
||||||
|
"short_desc": "",
|
||||||
|
"author": "",
|
||||||
|
"source": "",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/16827203?s=200&v=4",
|
||||||
|
"form_fields": {
|
||||||
|
"password": {
|
||||||
|
"type": "password",
|
||||||
|
"label": "Password",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "APP_PASSWORD"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
apps/pihole/docker-compose.yml
Normal file
24
apps/pihole/docker-compose.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
pihole:
|
||||||
|
container_name: pihole
|
||||||
|
image: cbcrowe/pihole-unbound:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 53:53/tcp
|
||||||
|
- 53:53/udp
|
||||||
|
- ${APP_PORT}:80
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/pihole:/etc/pihole
|
||||||
|
- ${APP_DATA_DIR}/data/dnsmasq:/etc/dnsmasq.d
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
WEBPASSWORD: ${APP_PASSWORD}
|
||||||
|
PIHOLE_DNS_: 127.0.0.1#5335
|
||||||
|
FTLCONF_REPLY_ADDR4: 192.168.2.132
|
||||||
|
PIHOLE_DNS_: 127.0.0.1#5335
|
||||||
|
DNSSEC: "true"
|
||||||
|
DNSMASQ_LISTENING: single
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
20
apps/radarr/config.json
Normal file
20
apps/radarr/config.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "Radarr",
|
||||||
|
"port": 8088,
|
||||||
|
"id": "radarr",
|
||||||
|
"description": "",
|
||||||
|
"short_desc": "",
|
||||||
|
"author": "",
|
||||||
|
"source": "",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/25025331?s=200&v=4",
|
||||||
|
"form_fields": {
|
||||||
|
"torrent-client": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "Torrent Client",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "TORRENT_CLIENT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
apps/radarr/docker-compose.yml
Normal file
35
apps/radarr/docker-compose.yml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
version: "3.7"
|
||||||
|
services:
|
||||||
|
jackett:
|
||||||
|
image: lscr.io/linuxserver/jackett
|
||||||
|
container_name: jackett
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=${TZ}
|
||||||
|
- AUTO_UPDATE=true
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/config:/config
|
||||||
|
- ${APP_DATA_DIR}/data/downloads:/downloads
|
||||||
|
ports:
|
||||||
|
- 9117:9117
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
||||||
|
|
||||||
|
radarr:
|
||||||
|
image: lscr.io/linuxserver/radarr
|
||||||
|
container_name: radarr
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/config:/config
|
||||||
|
- ${APP_DATA_DIR}/data/movies:/movies #optional
|
||||||
|
- ${ROOT_FOLDER}/app-data/${TORRENT_CLIENT}/data/downloads:/downloads #optional
|
||||||
|
ports:
|
||||||
|
- ${APP_PORT}:7878
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
11
apps/simple-torrent/config.json
Normal file
11
apps/simple-torrent/config.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "Simple Torrent",
|
||||||
|
"port": 8085,
|
||||||
|
"id": "simple-torrent",
|
||||||
|
"description": "SimpleTorrent is a a self-hosted remote torrent client, written in Go (golang). Started torrents remotely, download sets of files on the local disk of the server, which are then retrievable or streamable via HTTP.",
|
||||||
|
"short_desc": "A self-hosted remote torrent client",
|
||||||
|
"author": "",
|
||||||
|
"source": "https://github.com/boypt/simple-torrent",
|
||||||
|
"image": "https://getumbrel.github.io/umbrel-apps-gallery/simple-torrent/icon.svg",
|
||||||
|
"form_fields": {}
|
||||||
|
}
|
|
@ -6,9 +6,9 @@ services:
|
||||||
image: boypt/cloud-torrent:1.3.9
|
image: boypt/cloud-torrent:1.3.9
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
ports:
|
ports:
|
||||||
- "${APP_SIMPLETORRENT_PORT}:${APP_SIMPLETORRENT_PORT}"
|
- ${APP_PORT}:${APP_PORT}
|
||||||
command: >
|
command: >
|
||||||
--port=${APP_SIMPLETORRENT_PORT}
|
--port=${APP_PORT}
|
||||||
--config-path /config/simple-torrent.json
|
--config-path /config/simple-torrent.json
|
||||||
volumes:
|
volumes:
|
||||||
- ${APP_DATA_DIR}/data/torrents:/torrents
|
- ${APP_DATA_DIR}/data/torrents:/torrents
|
||||||
|
|
12
apps/syncthing/config.json
Normal file
12
apps/syncthing/config.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "Syncthing",
|
||||||
|
"port": 8090,
|
||||||
|
"id": "syncthing",
|
||||||
|
"description": "Syncthing is a peer-to-peer continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.\n\nInstall the Syncthing app on your Umbrel and pair it with the Syncthing app on your phone or computer for a self hosted peer-to-peer backup solution.",
|
||||||
|
"short_desc": "Peer-to-peer file synchronization between your devices",
|
||||||
|
"author": "The Syncthing Foundation",
|
||||||
|
"source": "https://github.com/syncthing",
|
||||||
|
"website": "https://syncthing.net",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/7628018?s=200&v=4",
|
||||||
|
"form_fields": {}
|
||||||
|
}
|
20
apps/syncthing/docker-compose.yml
Normal file
20
apps/syncthing/docker-compose.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
image: syncthing/syncthing:1.19
|
||||||
|
stop_grace_period: 1m
|
||||||
|
hostname: tipi
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data:/var/syncthing
|
||||||
|
ports:
|
||||||
|
- ${APP_PORT}:8384
|
||||||
|
- 22000:22000/tcp # TCP file transfers
|
||||||
|
- 22000:22000/udp # QUIC file transfers
|
||||||
|
- 21027:21027/udp # Receive local discovery broadcasts
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
|
@ -1,8 +0,0 @@
|
||||||
version: '3.7'
|
|
||||||
services:
|
|
||||||
test:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
networks:
|
|
||||||
- tipi_main_network
|
|
31
apps/transmission/config.json
Normal file
31
apps/transmission/config.json
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "Transmission",
|
||||||
|
"port": 8089,
|
||||||
|
"requirements": {
|
||||||
|
"ports": [51413]
|
||||||
|
},
|
||||||
|
"id": "transmission",
|
||||||
|
"description": "",
|
||||||
|
"short_desc": "",
|
||||||
|
"author": "",
|
||||||
|
"source": "https://transmissionbt.com",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/223312?s=200&v=4",
|
||||||
|
"form_fields": {
|
||||||
|
"username": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "Username",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "TRANSMISSION_USERNAME"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "password",
|
||||||
|
"label": "Password",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "TRANSMISSION_PASSWORD"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
0
apps/transmission/data/config/.gitkeep
Normal file
0
apps/transmission/data/config/.gitkeep
Normal file
0
apps/transmission/data/downloads/.gitkeep
Normal file
0
apps/transmission/data/downloads/.gitkeep
Normal file
0
apps/transmission/data/watch/.gitkeep
Normal file
0
apps/transmission/data/watch/.gitkeep
Normal file
25
apps/transmission/docker-compose.yml
Normal file
25
apps/transmission/docker-compose.yml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
version: "3.7"
|
||||||
|
services:
|
||||||
|
transmission:
|
||||||
|
image: lscr.io/linuxserver/transmission
|
||||||
|
container_name: transmission
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=${TZ}
|
||||||
|
- USER=${TRANSMISSION_USERNAME}
|
||||||
|
- PASS=${TRANSMISSION_PASSWORD}
|
||||||
|
# - WHITELIST=iplist #optional
|
||||||
|
# - PEERPORT=peerport #optional
|
||||||
|
# - HOST_WHITELIST=dnsnane list #optional
|
||||||
|
volumes:
|
||||||
|
- ${APP_DATA_DIR}/data/config:/config
|
||||||
|
- ${APP_DATA_DIR}/data/downloads:/downloads
|
||||||
|
- ${APP_DATA_DIR}/data/watch:/watch
|
||||||
|
ports:
|
||||||
|
- ${APP_PORT}:9091
|
||||||
|
- 51413:51413
|
||||||
|
- 51413:51413/udp
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- tipi_main_network
|
35
apps/wg-easy/config.json
Normal file
35
apps/wg-easy/config.json
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"name": "Wireguard",
|
||||||
|
"port": 8082,
|
||||||
|
"requirements": {
|
||||||
|
"ports": [51820]
|
||||||
|
},
|
||||||
|
"id": "wg-easy",
|
||||||
|
"description": "Access your homeserver from anywhere even on your mobile device. Wireguard-easy is a simple tool to configure and manage Wireguard VPN servers. It is written in Go and uses the official Wireguard client. You have to open and redirect port 51820 to your homeserver in order to connect.",
|
||||||
|
"short_desc": "VPN server for your homeserver",
|
||||||
|
"author": "WeeJeWel",
|
||||||
|
"source": "https://github.com/WeeJeWel/wg-easy/",
|
||||||
|
"image": "https://avatars.githubusercontent.com/u/13991055?s=200&v=4",
|
||||||
|
"form_fields": {
|
||||||
|
"host": {
|
||||||
|
"type": "fqdnip",
|
||||||
|
"label": "Your public IP address or domain name",
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "WIREGUARD_HOST"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "password",
|
||||||
|
"label": "Password",
|
||||||
|
"max": 50,
|
||||||
|
"min": 3,
|
||||||
|
"required": true,
|
||||||
|
"env_variable": "WIREGUARD_PASSWORD"
|
||||||
|
},
|
||||||
|
"dns": {
|
||||||
|
"type": "ip",
|
||||||
|
"label": "Default DNS server",
|
||||||
|
"required": false,
|
||||||
|
"env_variable": "WIREGUARD_DNS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
0
apps/wg-easy/data/.gitkeep
Normal file
0
apps/wg-easy/data/.gitkeep
Normal file
|
@ -1,29 +1,35 @@
|
||||||
version: '3.7'
|
version: "3.7"
|
||||||
services:
|
services:
|
||||||
wg-easy:
|
wg-easy:
|
||||||
container_name: wg-easy
|
container_name: wg-easy
|
||||||
image: 'weejewel/wg-easy:latest'
|
image: "meienberger/wg-easy:latest"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
# network_mode: "host"
|
||||||
- ${APP_DATA_DIR}:/etc/wireguard
|
volumes:
|
||||||
ports:
|
- ${APP_DATA_DIR}/data:/etc/wireguard
|
||||||
- 51820:51820
|
- /lib/modules:/lib/modules
|
||||||
- ${APP_WGEASY_PORT}:51821
|
ports:
|
||||||
environment:
|
- 51822:51820/udp
|
||||||
WG_HOST: '${WIREGUARD_HOST}'
|
- ${APP_PORT}:51821/tcp
|
||||||
PASSWORD: '${WIREGUARD_PASSWORD}'
|
environment:
|
||||||
cap_add:
|
WG_HOST: "${WIREGUARD_HOST}"
|
||||||
- NET_ADMIN
|
PASSWORD: "${WIREGUARD_PASSWORD}"
|
||||||
- SYS_MODULE
|
WG_ALLOWED_IPS: 0.0.0.0/0,::/0
|
||||||
sysctls:
|
WG_PORT: 51822
|
||||||
- net.ipv4.conf.all.src_valid_mark=1
|
WG_DEFAULT_DNS: "${WIREGUARD_DNS:-8.8.8.8}"
|
||||||
- net.ipv4.ip_forward=1
|
# WG_FWMARK: 51820
|
||||||
networks:
|
cap_add:
|
||||||
- tipi_main_network
|
- NET_ADMIN
|
||||||
# labels:
|
- SYS_MODULE
|
||||||
# traefik.enable: true
|
sysctls:
|
||||||
# traefik.http.routers.wireguard.rule: Host(`wireguard.tipi.home`)
|
- net.ipv4.conf.all.src_valid_mark=1
|
||||||
# traefik.http.routers.wireguard.service: wireguard
|
- net.ipv4.ip_forward=1
|
||||||
# traefik.http.routers.wireguard.tls: true
|
networks:
|
||||||
# traefik.http.routers.wireguard.entrypoints: websecure
|
- tipi_main_network
|
||||||
# traefik.http.services.wireguard.loadbalancer.server.port: 51821
|
# labels:
|
||||||
|
# traefik.enable: true
|
||||||
|
# traefik.http.routers.wireguard.rule: Host(`wireguard.tipi.home`)
|
||||||
|
# traefik.http.routers.wireguard.service: wireguard
|
||||||
|
# traefik.http.routers.wireguard.tls: true
|
||||||
|
# traefik.http.routers.wireguard.entrypoints: websecure
|
||||||
|
# traefik.http.services.wireguard.loadbalancer.server.port: 51821
|
||||||
|
|
17
dashboard/.eslintrc.js
Normal file
17
dashboard/.eslintrc.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: ['next/core-web-vitals', 'airbnb-typescript', 'eslint:recommended', 'plugin:import/typescript'],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module',
|
||||||
|
project: './tsconfig.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint', 'import'],
|
||||||
|
rules: {
|
||||||
|
'arrow-body-style': 0,
|
||||||
|
'no-restricted-exports': 0,
|
||||||
|
'max-len': [1, { code: 200 }],
|
||||||
|
'import/extensions': ['error', 'ignorePackages', { js: 'never', jsx: 'never', ts: 'never', tsx: 'never' }],
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "next/core-web-vitals"
|
|
||||||
}
|
|
6
dashboard/.prettierrc.js
Normal file
6
dashboard/.prettierrc.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
singleQuote: true,
|
||||||
|
semi: true,
|
||||||
|
trailingComma: "all",
|
||||||
|
printWidth: 200,
|
||||||
|
};
|
|
@ -9,6 +9,9 @@ RUN yarn
|
||||||
|
|
||||||
COPY ./ ./
|
COPY ./ ./
|
||||||
|
|
||||||
|
ARG INTERNAL_IP_ARG
|
||||||
|
ENV INTERNAL_IP $INTERNAL_IP_ARG
|
||||||
|
|
||||||
RUN yarn build
|
RUN yarn build
|
||||||
|
|
||||||
CMD ["yarn", "start"]
|
CMD ["yarn", "start"]
|
12
dashboard/Dockerfile.dev
Normal file
12
dashboard/Dockerfile.dev
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM node:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ./package.json ./
|
||||||
|
COPY ./yarn.lock ./
|
||||||
|
|
||||||
|
RUN yarn
|
||||||
|
|
||||||
|
COPY ./ ./
|
||||||
|
|
||||||
|
CMD ["yarn", "dev"]
|
|
@ -1,6 +1,11 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
|
console.log(process.env);
|
||||||
|
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
}
|
env: {
|
||||||
|
INTERNAL_IP: process.env.INTERNAL_IP,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig;
|
||||||
|
|
|
@ -12,20 +12,33 @@
|
||||||
"@chakra-ui/react": "^1.8.7",
|
"@chakra-ui/react": "^1.8.7",
|
||||||
"@emotion/react": "^11",
|
"@emotion/react": "^11",
|
||||||
"@emotion/styled": "^11",
|
"@emotion/styled": "^11",
|
||||||
|
"axios": "^0.26.1",
|
||||||
|
"clsx": "^1.1.1",
|
||||||
|
"final-form": "^4.20.6",
|
||||||
"framer-motion": "^6",
|
"framer-motion": "^6",
|
||||||
|
"immer": "^9.0.12",
|
||||||
"next": "12.1.4",
|
"next": "12.1.4",
|
||||||
"react": "18.0.0",
|
"react": "18.0.0",
|
||||||
"react-dom": "18.0.0",
|
"react-dom": "18.0.0",
|
||||||
|
"react-final-form": "^6.5.9",
|
||||||
|
"react-icons": "^4.3.1",
|
||||||
|
"swr": "^1.3.0",
|
||||||
"systeminformation": "^5.11.9",
|
"systeminformation": "^5.11.9",
|
||||||
"validator": "^13.7.0"
|
"validator": "^13.7.0",
|
||||||
|
"zustand": "^3.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "17.0.23",
|
"@types/node": "17.0.23",
|
||||||
"@types/react": "17.0.43",
|
"@types/react": "17.0.43",
|
||||||
"@types/react-dom": "17.0.14",
|
"@types/react-dom": "17.0.14",
|
||||||
"@types/validator": "^13.7.2",
|
"@types/validator": "^13.7.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||||
|
"autoprefixer": "^10.4.4",
|
||||||
"eslint": "8.12.0",
|
"eslint": "8.12.0",
|
||||||
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
"eslint-config-next": "12.1.4",
|
"eslint-config-next": "12.1.4",
|
||||||
|
"postcss": "^8.4.12",
|
||||||
|
"tailwindcss": "^3.0.23",
|
||||||
"typescript": "4.6.3"
|
"typescript": "4.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
dashboard/postcss.config.js
Normal file
6
dashboard/postcss.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
BIN
dashboard/public/logo.png
Normal file
BIN
dashboard/public/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -1,4 +0,0 @@
|
||||||
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
23
dashboard/src/components/AppTile/AppStatus.tsx
Normal file
23
dashboard/src/components/AppTile/AppStatus.tsx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { FiPauseCircle, FiPlayCircle } from 'react-icons/fi';
|
||||||
|
import { AppStatus as TAppStatus } from '../../core/types';
|
||||||
|
|
||||||
|
const AppStatus: React.FC<{ status: TAppStatus }> = ({ status }) => {
|
||||||
|
if (status === 'running') {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FiPlayCircle className="text-green-500 mr-1" size={20} />
|
||||||
|
<span className="text-gray-400 text-sm">Running</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FiPauseCircle className="text-red-500 mr-1" size={20} />
|
||||||
|
<span className="text-gray-400 text-sm">Stopped</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppStatus;
|
30
dashboard/src/components/AppTile/index.tsx
Normal file
30
dashboard/src/components/AppTile/index.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { Box, SlideFade, Image } from '@chakra-ui/react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import React from 'react';
|
||||||
|
import { FiChevronRight } from 'react-icons/fi';
|
||||||
|
import { AppConfig } from '../../core/types';
|
||||||
|
import AppStatus from './AppStatus';
|
||||||
|
|
||||||
|
const AppTile: React.FC<{ app: AppConfig }> = ({ app }) => {
|
||||||
|
return (
|
||||||
|
<Link href={`/apps/${app.id}`} passHref>
|
||||||
|
<SlideFade in className="flex flex-1" offsetY="20px">
|
||||||
|
<Box minWidth={400} className="flex flex-1 bg-white drop-shadow-lg rounded-lg p-3 items-center cursor-pointer group hover:drop-shadow-md hover:bg-gray-100 transition-all">
|
||||||
|
<Image alt={`${app.name} logo`} className="rounded-md drop-shadow mr-3 group-hover:scale-105 transition-all" src={app.image} width={100} height={100} />
|
||||||
|
<div className="mr-3 flex-1">
|
||||||
|
<h3 className="font-bold text-xl">{app.name}</h3>
|
||||||
|
<span>{app.short_desc}</span>
|
||||||
|
{app.installed && (
|
||||||
|
<div className="flex mt-1">
|
||||||
|
<AppStatus status={app.status} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<FiChevronRight className="text-slate-300" size={30} />
|
||||||
|
</Box>
|
||||||
|
</SlideFade>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppTile;
|
24
dashboard/src/components/Form/FormInput.tsx
Normal file
24
dashboard/src/components/Form/FormInput.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Input } from '@chakra-ui/react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
placeholder?: string;
|
||||||
|
error?: string;
|
||||||
|
type?: Parameters<typeof Input>[0]['type'];
|
||||||
|
label: string;
|
||||||
|
className?: string;
|
||||||
|
isInvalid?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormInput: React.FC<IProps> = ({ placeholder, error, type, label, className, isInvalid, ...rest }) => {
|
||||||
|
return (
|
||||||
|
<div className={clsx('transition-all', className)}>
|
||||||
|
<label>{label}</label>
|
||||||
|
<Input type={type} placeholder={placeholder} isInvalid={isInvalid} {...rest} />
|
||||||
|
{isInvalid && <span className="text-red-500 text-sm">{error}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormInput;
|
28
dashboard/src/components/Form/validators.ts
Normal file
28
dashboard/src/components/Form/validators.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import validator from 'validator';
|
||||||
|
import { AppConfig, FieldTypes } from '../../core/types';
|
||||||
|
|
||||||
|
export const validateAppConfig = (values: Record<string, string>, fields: (AppConfig['form_fields'][0] & { id: string })[]) => {
|
||||||
|
const errors: any = {};
|
||||||
|
|
||||||
|
fields.forEach((field) => {
|
||||||
|
if (field.required && !values[field.id]) {
|
||||||
|
errors[field.id] = 'Field required';
|
||||||
|
} else if (values[field.id] && field.min && values[field.id].length < field.min) {
|
||||||
|
errors[field.id] = `Field must be at least ${field.min} characters long`;
|
||||||
|
} else if (values[field.id] && field.max && values[field.id].length > field.max) {
|
||||||
|
errors[field.id] = `Field must be at most ${field.max} characters long`;
|
||||||
|
} else if (values[field.id] && field.type === FieldTypes.number && !validator.isNumeric(values[field.id])) {
|
||||||
|
errors[field.id] = 'Field must be a number';
|
||||||
|
} else if (values[field.id] && field.type === FieldTypes.email && !validator.isEmail(values[field.id])) {
|
||||||
|
errors[field.id] = 'Field must be a valid email';
|
||||||
|
} else if (values[field.id] && field.type === FieldTypes.fqdn && !validator.isFQDN(values[field.id] || '')) {
|
||||||
|
errors[field.id] = 'Field must be a valid domain';
|
||||||
|
} else if (values[field.id] && field.type === FieldTypes.ip && !validator.isIP(values[field.id])) {
|
||||||
|
errors[field.id] = 'Field must be a valid IP address';
|
||||||
|
} else if (values[field.id] && field.type === FieldTypes.fqdnip && !validator.isFQDN(values[field.id] || '') && !validator.isIP(values[field.id])) {
|
||||||
|
errors[field.id] = 'Field must be a valid domain or IP address';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
};
|
|
@ -1,27 +1,22 @@
|
||||||
import React from "react";
|
import React from 'react';
|
||||||
import Img from "next/image";
|
import Link from 'next/link';
|
||||||
import Link from "next/link";
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { Button, Flex, useBreakpointValue } from "@chakra-ui/react";
|
import { FiMenu } from 'react-icons/fi';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
onClickMenu: () => void;
|
onClickMenu: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Header: React.FC<IProps> = ({ onClickMenu }) => {
|
const Header: React.FC<IProps> = ({ onClickMenu }) => {
|
||||||
const buttonVisibility = useBreakpointValue<"visible" | "hidden">({
|
|
||||||
base: "visible",
|
|
||||||
md: "hidden",
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header>
|
<header style={{ width: '100%' }} className="flex">
|
||||||
<Flex alignItems="center" bg="tomato" paddingLeft={5} paddingRight={5}>
|
<Flex className="items-center bg-gray-700 drop-shadow-md px-5 flex-1">
|
||||||
<Flex position="absolute" visibility={buttonVisibility || "visible"}>
|
<div onClick={onClickMenu} className="visible md:invisible absolute cursor-pointer py-2">
|
||||||
<Button onClick={onClickMenu}>O</Button>
|
<FiMenu color="white" />
|
||||||
</Flex>
|
</div>
|
||||||
<Flex justifyContent="center" flex="1">
|
<Flex justifyContent="center" flex="1">
|
||||||
<Link href="/" passHref>
|
<Link href="/" passHref>
|
||||||
<Img src="/logo.svg" alt="Tipi" width={100} height={60} />
|
<img src="/logo.png" alt="Tipi" width={230} height={60} />
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
|
@ -1,30 +1,60 @@
|
||||||
import {
|
import { Flex, useDisclosure, Spinner, Breadcrumb, BreadcrumbItem } from '@chakra-ui/react';
|
||||||
Button,
|
import Link from 'next/link';
|
||||||
Flex,
|
import React from 'react';
|
||||||
useBreakpointValue,
|
import { FiChevronRight } from 'react-icons/fi';
|
||||||
useDisclosure,
|
import Header from './Header';
|
||||||
} from "@chakra-ui/react";
|
import Menu from './Menu';
|
||||||
import React from "react";
|
import MenuDrawer from './MenuDrawer';
|
||||||
import Header from "./Header";
|
|
||||||
import Menu from "./Menu";
|
|
||||||
import MenuDrawer from "./MenuDrawer";
|
|
||||||
|
|
||||||
const Layout: React.FC = ({ children }) => {
|
interface IProps {
|
||||||
const menuWidth = useBreakpointValue({ base: 0, md: 200 });
|
loading?: boolean;
|
||||||
|
breadcrumbs?: { name: string; href: string; current?: boolean }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Layout: React.FC<IProps> = ({ children, loading, breadcrumbs }) => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
|
||||||
|
const renderContent = () => {
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<Flex className="justify-center flex-1">
|
||||||
|
<Spinner />
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderBreadcrumbs = () => {
|
||||||
|
return (
|
||||||
|
<Breadcrumb spacing="8px" separator={<FiChevronRight color="gray.500" />}>
|
||||||
|
{breadcrumbs?.map((breadcrumb, index) => {
|
||||||
|
return (
|
||||||
|
<BreadcrumbItem className="hover:underline" isCurrentPage={breadcrumb.current} key={index}>
|
||||||
|
<Link href={breadcrumb.href}>{breadcrumb.name}</Link>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Breadcrumb>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex height="100vh" bg="green.500" direction="column">
|
<Flex height="100vh" className="drop-shadow-md border-r-8" direction="column">
|
||||||
<MenuDrawer isOpen={isOpen} onClose={onClose}>
|
<MenuDrawer isOpen={isOpen} onClose={onClose}>
|
||||||
<Menu />
|
<Menu />
|
||||||
</MenuDrawer>
|
</MenuDrawer>
|
||||||
<Header onClickMenu={onOpen} />
|
<Header onClickMenu={onOpen} />
|
||||||
<Flex flex="1">
|
<Flex flex="1">
|
||||||
<Flex width={menuWidth} bg="blue.500">
|
<Flex className="invisible md:visible w-0 md:w-56">
|
||||||
<Menu />
|
<Menu />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex flex="1" padding={5} bg="yellow.300">
|
<Flex className="bg-slate-200 flex flex-1 p-5">
|
||||||
{children}
|
<div className="flex-1 flex flex-col">
|
||||||
|
{renderBreadcrumbs()}
|
||||||
|
<div className="flex-1 ">{renderContent()}</div>
|
||||||
|
</div>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
|
@ -1,11 +1,40 @@
|
||||||
import React from "react";
|
import { AiOutlineDashboard, AiOutlineSetting, AiOutlineAppstore } from 'react-icons/ai';
|
||||||
|
import { Divider, List, ListItem } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { IconType } from 'react-icons';
|
||||||
|
|
||||||
|
const SideMenu: React.FC = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const path = router.pathname.split('/')[1];
|
||||||
|
|
||||||
|
const renderMenuItem = (title: string, name: string, Icon: IconType) => {
|
||||||
|
const selected = path === name;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link href={`/${name}`} passHref>
|
||||||
|
<div className={clsx('mx-3 rounded-lg p-3 transition-colors', { 'bg-slate-200 drop-shadow-sm': selected })}>
|
||||||
|
<ListItem className={'flex items-center cursor-pointer hover:font-bold'}>
|
||||||
|
<Icon size={20} className="mr-3" />
|
||||||
|
<p className={clsx({ 'font-bold': selected })}>{title}</p>
|
||||||
|
</ListItem>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Menu: React.FC = () => {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<List spacing={3} className="pt-5 flex-1 bg-white md:border-r-2">
|
||||||
<h1>Menu</h1>
|
{renderMenuItem('Dashboard', '', AiOutlineDashboard)}
|
||||||
</div>
|
<Divider />
|
||||||
|
{renderMenuItem('Apps', 'apps', AiOutlineAppstore)}
|
||||||
|
<Divider />
|
||||||
|
{renderMenuItem('Settings', 'settings', AiOutlineSetting)}
|
||||||
|
</List>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Menu;
|
export default SideMenu;
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
import {
|
import { Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, DrawerHeader, DrawerOverlay } from '@chakra-ui/react';
|
||||||
Drawer,
|
import React from 'react';
|
||||||
DrawerBody,
|
|
||||||
DrawerCloseButton,
|
|
||||||
DrawerContent,
|
|
||||||
DrawerFooter,
|
|
||||||
DrawerHeader,
|
|
||||||
DrawerOverlay,
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
@ -16,11 +8,11 @@ interface IProps {
|
||||||
|
|
||||||
const MenuDrawer: React.FC<IProps> = ({ children, isOpen, onClose }) => {
|
const MenuDrawer: React.FC<IProps> = ({ children, isOpen, onClose }) => {
|
||||||
return (
|
return (
|
||||||
<Drawer isOpen={isOpen} placement="left" onClose={onClose}>
|
<Drawer size="xs" isOpen={isOpen} placement="left" onClose={onClose}>
|
||||||
<DrawerOverlay />
|
<DrawerOverlay />
|
||||||
<DrawerContent>
|
<DrawerContent>
|
||||||
<DrawerCloseButton />
|
<DrawerCloseButton />
|
||||||
<DrawerHeader>Create your account</DrawerHeader>
|
<DrawerHeader>My Tipi</DrawerHeader>
|
||||||
<DrawerBody>{children}</DrawerBody>
|
<DrawerBody>{children}</DrawerBody>
|
||||||
<DrawerFooter>
|
<DrawerFooter>
|
||||||
<div>Github</div>
|
<div>Github</div>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./Layout";
|
export { default } from './Layout';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import validator from "validator";
|
import validator from 'validator';
|
||||||
|
|
||||||
interface IFormField {
|
interface IFormField {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -20,81 +20,79 @@ interface IAppConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
const APP_ANONADDY: IAppConfig = {
|
const APP_ANONADDY: IAppConfig = {
|
||||||
id: "anonaddy",
|
id: 'anonaddy',
|
||||||
name: "Anonaddy",
|
name: 'Anonaddy',
|
||||||
description: "Create Unlimited Email Aliases For Free",
|
description: 'Create Unlimited Email Aliases For Free',
|
||||||
url: "https://anonaddy.com/",
|
url: 'https://anonaddy.com/',
|
||||||
color: "#00a8ff",
|
color: '#00a8ff',
|
||||||
logo: "https://anonaddy.com/favicon.ico",
|
logo: 'https://anonaddy.com/favicon.ico',
|
||||||
install_form: {
|
install_form: {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "API Key",
|
name: 'API Key',
|
||||||
type: "text",
|
type: 'text',
|
||||||
placeholder: "API Key",
|
placeholder: 'API Key',
|
||||||
required: true,
|
required: true,
|
||||||
validate: (value: string) => validator.isBase64(value),
|
validate: (value: string) => validator.isBase64(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Return Path",
|
name: 'Return Path',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description: "The email address that bounces will be sent to",
|
description: 'The email address that bounces will be sent to',
|
||||||
placeholder: "Return Path",
|
placeholder: 'Return Path',
|
||||||
required: false,
|
required: false,
|
||||||
validate: (value: string) => validator.isEmail(value),
|
validate: (value: string) => validator.isEmail(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Admin Username",
|
name: 'Admin Username',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description: "The username of the admin user",
|
description: 'The username of the admin user',
|
||||||
placeholder: "Admin Username",
|
placeholder: 'Admin Username',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Enable Registration",
|
name: 'Enable Registration',
|
||||||
type: "boolean",
|
type: 'boolean',
|
||||||
description: "Allow users to register",
|
description: 'Allow users to register',
|
||||||
placeholder: "Enable Registration",
|
placeholder: 'Enable Registration',
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Domain",
|
name: 'Domain',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description: "The domain that will be used for the email address",
|
description: 'The domain that will be used for the email address',
|
||||||
placeholder: "Domain",
|
placeholder: 'Domain',
|
||||||
required: true,
|
required: true,
|
||||||
validate: (value: string) => validator.isFQDN(value),
|
validate: (value: string) => validator.isFQDN(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Hostname",
|
name: 'Hostname',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description: "The hostname that will be used for the email address",
|
description: 'The hostname that will be used for the email address',
|
||||||
placeholder: "Hostname",
|
placeholder: 'Hostname',
|
||||||
required: true,
|
required: true,
|
||||||
validate: (value: string) => validator.isFQDN(value),
|
validate: (value: string) => validator.isFQDN(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Secret",
|
name: 'Secret',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description: "The secret that will be used for the email address",
|
description: 'The secret that will be used for the email address',
|
||||||
placeholder: "Secret",
|
placeholder: 'Secret',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "From Name",
|
name: 'From Name',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description: "The name that will be used for the email address",
|
description: 'The name that will be used for the email address',
|
||||||
placeholder: "From Name",
|
placeholder: 'From Name',
|
||||||
required: true,
|
required: true,
|
||||||
validate: (value: string) =>
|
validate: (value: string) => validator.isLength(value, { min: 1, max: 64 }),
|
||||||
validator.isLength(value, { min: 1, max: 64 }),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "From Address",
|
name: 'From Address',
|
||||||
type: "text",
|
type: 'text',
|
||||||
description:
|
description: 'The email address that will be used for the email address',
|
||||||
"The email address that will be used for the email address",
|
placeholder: 'From Address',
|
||||||
placeholder: "From Address",
|
|
||||||
required: true,
|
required: true,
|
||||||
validate: (value: string) => validator.isEmail(value),
|
validate: (value: string) => validator.isEmail(value),
|
||||||
},
|
},
|
||||||
|
|
33
dashboard/src/core/api.ts
Normal file
33
dashboard/src/core/api.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import axios, { Method } from 'axios';
|
||||||
|
|
||||||
|
export const BASE_URL = 'http://192.168.2.132:3001';
|
||||||
|
|
||||||
|
console.log(process.env);
|
||||||
|
|
||||||
|
interface IFetchParams {
|
||||||
|
endpoint: string;
|
||||||
|
method?: Method;
|
||||||
|
params?: JSON;
|
||||||
|
data?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const api = async <T = unknown>(fetchParams: IFetchParams): Promise<T> => {
|
||||||
|
const { endpoint, method = 'GET', params, data } = fetchParams;
|
||||||
|
|
||||||
|
const response = await axios.request<T & { error?: string }>({
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
url: `${BASE_URL}${endpoint}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.data.error) {
|
||||||
|
throw new Error(response.data.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.data) return response.data;
|
||||||
|
|
||||||
|
throw new Error(`Network request error. status : ${response.status}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default { fetch: api };
|
9
dashboard/src/core/fetcher.ts
Normal file
9
dashboard/src/core/fetcher.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { BareFetcher } from 'swr';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { BASE_URL } from './api';
|
||||||
|
|
||||||
|
const fetcher: BareFetcher<any> = (url: string) => {
|
||||||
|
return axios.get(url, { baseURL: BASE_URL }).then((res) => res.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fetcher;
|
51
dashboard/src/core/types.ts
Normal file
51
dashboard/src/core/types.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
export enum FieldTypes {
|
||||||
|
text = 'text',
|
||||||
|
password = 'password',
|
||||||
|
email = 'email',
|
||||||
|
number = 'number',
|
||||||
|
fqdn = 'fqdn',
|
||||||
|
ip = 'ip',
|
||||||
|
fqdnip = 'fqdnip',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FormField {
|
||||||
|
type: FieldTypes;
|
||||||
|
label: string;
|
||||||
|
max?: number;
|
||||||
|
min?: number;
|
||||||
|
required?: boolean;
|
||||||
|
env_variable: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppConfig {
|
||||||
|
id: string;
|
||||||
|
port: number;
|
||||||
|
requirements?: {
|
||||||
|
ports?: number[];
|
||||||
|
};
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
version: string;
|
||||||
|
image: string;
|
||||||
|
form_fields: Record<string, FormField>;
|
||||||
|
short_desc: string;
|
||||||
|
author: string;
|
||||||
|
source: string;
|
||||||
|
installed: boolean;
|
||||||
|
status: AppStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RequestStatus {
|
||||||
|
SUCCESS = 'SUCCESS',
|
||||||
|
ERROR = 'ERROR',
|
||||||
|
LOADING = 'LOADING',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum AppStatus {
|
||||||
|
RUNNING = 'running',
|
||||||
|
STOPPED = 'stopped',
|
||||||
|
INSTALLING = 'installing',
|
||||||
|
UNINSTALLING = 'uninstalling',
|
||||||
|
STOPPING = 'stopping',
|
||||||
|
STARTING = 'starting',
|
||||||
|
}
|
70
dashboard/src/modules/Apps/components/AppActions.tsx
Normal file
70
dashboard/src/modules/Apps/components/AppActions.tsx
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import { Button } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { FiExternalLink, FiPause, FiPlay, FiSettings, FiTrash2 } from 'react-icons/fi';
|
||||||
|
import { AppConfig, AppStatus } from '../../../core/types';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
app: AppConfig;
|
||||||
|
onInstall: () => void;
|
||||||
|
onUninstall: () => void;
|
||||||
|
onStart: () => void;
|
||||||
|
onStop: () => void;
|
||||||
|
onOpen: () => void;
|
||||||
|
onUpdate: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppActions: React.FC<IProps> = ({ app, onInstall, onUninstall, onStart, onStop, onOpen, onUpdate }) => {
|
||||||
|
const hasSettings = Object.keys(app.form_fields).length > 0;
|
||||||
|
|
||||||
|
if (app?.installed && app.status === AppStatus.STOPPED) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap justify-center">
|
||||||
|
<Button onClick={onStart} width={160} colorScheme="green" className="mt-3 mr-2">
|
||||||
|
Start
|
||||||
|
<FiPlay className="ml-1" />
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onUninstall} width={160} colorScheme="gray" className="mt-3 mr-2">
|
||||||
|
Remove
|
||||||
|
<FiTrash2 className="ml-1" />
|
||||||
|
</Button>
|
||||||
|
{hasSettings && (
|
||||||
|
<Button onClick={onUpdate} width={160} className="mt-3 mr-2">
|
||||||
|
Settings
|
||||||
|
<FiSettings className="ml-1" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (app?.installed && app.status === AppStatus.RUNNING) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button onClick={onOpen} width={160} colorScheme="gray" className="mt-3 mr-2">
|
||||||
|
Open
|
||||||
|
<FiExternalLink className="ml-1" />
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onStop} width={160} colorScheme="red" className="mt-3">
|
||||||
|
Stop
|
||||||
|
<FiPause className="ml-2" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (app.status === AppStatus.INSTALLING || app.status === AppStatus.UNINSTALLING || app.status === AppStatus.STARTING || app.status === AppStatus.STOPPING) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center flex-col md:flex-row">
|
||||||
|
<Button isLoading onClick={() => null} width={160} colorScheme="green" className="mt-3">
|
||||||
|
Install
|
||||||
|
<FiPlay className="ml-1" />
|
||||||
|
</Button>
|
||||||
|
<span className="text-gray-500 text-sm ml-2 mt-3">{`App is ${app.status} please wait and don't refresh page...`}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button onClick={onInstall} width={160} colorScheme="green" className="mt-3">
|
||||||
|
Install
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppActions;
|
46
dashboard/src/modules/Apps/components/InstallForm.tsx
Normal file
46
dashboard/src/modules/Apps/components/InstallForm.tsx
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import { Button } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { Form, Field } from 'react-final-form';
|
||||||
|
import FormInput from '../../../components/Form/FormInput';
|
||||||
|
import { validateAppConfig } from '../../../components/Form/validators';
|
||||||
|
import { AppConfig } from '../../../core/types';
|
||||||
|
import { objectKeys } from '../../../utils/typescript';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
formFields: AppConfig['form_fields'];
|
||||||
|
onSubmit: (values: Record<string, unknown>) => void;
|
||||||
|
initalValues?: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InstallForm: React.FC<IProps> = ({ formFields, onSubmit, initalValues }) => {
|
||||||
|
const fields = objectKeys(formFields).map((key) => ({ ...formFields[key], id: key }));
|
||||||
|
|
||||||
|
const renderField = (field: typeof fields[0]) => {
|
||||||
|
return (
|
||||||
|
<Field
|
||||||
|
key={field.id}
|
||||||
|
name={field.id}
|
||||||
|
render={({ input, meta }) => <FormInput className="mb-3" error={meta.error} isInvalid={meta.invalid && (meta.submitError || meta.submitFailed)} label={field.label} {...input} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form<Record<string, string>>
|
||||||
|
initialValues={initalValues}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
validateOnBlur={true}
|
||||||
|
validate={(values) => validateAppConfig(values, fields)}
|
||||||
|
render={({ handleSubmit, validating, submitting }) => (
|
||||||
|
<form className="flex flex-col" onSubmit={handleSubmit}>
|
||||||
|
{fields.map(renderField)}
|
||||||
|
<Button isLoading={validating || submitting} className="self-end mb-2" colorScheme="green" type="submit">
|
||||||
|
{initalValues ? 'Update' : 'Install'}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InstallForm;
|
28
dashboard/src/modules/Apps/components/InstallModal.tsx
Normal file
28
dashboard/src/modules/Apps/components/InstallModal.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { AppConfig } from '../../../core/types';
|
||||||
|
import InstallForm from './InstallForm';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
app: AppConfig;
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onSubmit: (values: Record<string, any>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InstallModal: React.FC<IProps> = ({ app, isOpen, onClose, onSubmit }) => {
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Install {app.name}</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>
|
||||||
|
<InstallForm onSubmit={onSubmit} formFields={app.form_fields} />
|
||||||
|
</ModalBody>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InstallModal;
|
30
dashboard/src/modules/Apps/components/StopModal.tsx
Normal file
30
dashboard/src/modules/Apps/components/StopModal.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { Button, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { AppConfig } from '../../../core/types';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
app: AppConfig;
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StopModal: React.FC<IProps> = ({ app, isOpen, onClose, onConfirm }) => {
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Stop {app.name} ?</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>All the data will be retained.</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button onClick={onConfirm} colorScheme="red">
|
||||||
|
Stop
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StopModal;
|
30
dashboard/src/modules/Apps/components/UninstallModal.tsx
Normal file
30
dashboard/src/modules/Apps/components/UninstallModal.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { Button, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { AppConfig } from '../../../core/types';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
app: AppConfig;
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UninstallModal: React.FC<IProps> = ({ app, isOpen, onClose, onConfirm }) => {
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Uninstall {app.name} ?</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>All data for this app will be lost.</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button onClick={onConfirm} colorScheme="red">
|
||||||
|
Uninstall
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UninstallModal;
|
36
dashboard/src/modules/Apps/components/UpdateModal.tsx
Normal file
36
dashboard/src/modules/Apps/components/UpdateModal.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
import fetcher from '../../../core/fetcher';
|
||||||
|
import { AppConfig } from '../../../core/types';
|
||||||
|
import InstallForm from './InstallForm';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
app: AppConfig;
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onSubmit: (values: Record<string, any>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateModal: React.FC<IProps> = ({ app, isOpen, onClose, onSubmit }) => {
|
||||||
|
const { data, mutate } = useSWR<Record<string, string>>(`/apps/form/${app.id}`, fetcher, { refreshInterval: 10 });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
mutate({}, true);
|
||||||
|
}, [isOpen, mutate]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Update {app.name} config</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>
|
||||||
|
<InstallForm onSubmit={onSubmit} formFields={app.form_fields} initalValues={data} />
|
||||||
|
</ModalBody>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UpdateModal;
|
136
dashboard/src/modules/Apps/containers/AppDetails.tsx
Normal file
136
dashboard/src/modules/Apps/containers/AppDetails.tsx
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
import { SlideFade, Image, VStack, Flex, Divider, useDisclosure, useToast } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { FiExternalLink } from 'react-icons/fi';
|
||||||
|
import { AppConfig } from '../../../core/types';
|
||||||
|
import { useAppsStore } from '../../../state/appsStore';
|
||||||
|
import { useNetworkStore } from '../../../state/networkStore';
|
||||||
|
import AppActions from '../components/AppActions';
|
||||||
|
import InstallModal from '../components/InstallModal';
|
||||||
|
import StopModal from '../components/StopModal';
|
||||||
|
import UninstallModal from '../components/UninstallModal';
|
||||||
|
import UpdateModal from '../components/UpdateModal';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
app: AppConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppDetails: React.FC<IProps> = ({ app }) => {
|
||||||
|
const toast = useToast();
|
||||||
|
const installDisclosure = useDisclosure();
|
||||||
|
const uninstallDisclosure = useDisclosure();
|
||||||
|
const stopDisclosure = useDisclosure();
|
||||||
|
const updateDisclosure = useDisclosure();
|
||||||
|
|
||||||
|
const { internalIp } = useNetworkStore();
|
||||||
|
const { install, update, uninstall, stop, start, fetchApp } = useAppsStore();
|
||||||
|
|
||||||
|
const handleError = (error: unknown) => {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
toast({
|
||||||
|
title: 'Error',
|
||||||
|
description: error.message,
|
||||||
|
status: 'error',
|
||||||
|
position: 'top',
|
||||||
|
isClosable: true,
|
||||||
|
});
|
||||||
|
fetchApp(app.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInstallSubmit = async (values: Record<string, any>) => {
|
||||||
|
installDisclosure.onClose();
|
||||||
|
try {
|
||||||
|
await install(app.id, values);
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUnistallSubmit = async () => {
|
||||||
|
uninstallDisclosure.onClose();
|
||||||
|
try {
|
||||||
|
await uninstall(app.id);
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStopSubmit = async () => {
|
||||||
|
stopDisclosure.onClose();
|
||||||
|
try {
|
||||||
|
await stop(app.id);
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStartSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await start(app.id);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
handleError(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdateSubmit = async (values: Record<string, any>) => {
|
||||||
|
try {
|
||||||
|
await update(app.id, values);
|
||||||
|
toast({
|
||||||
|
title: 'Success',
|
||||||
|
description: 'App config updated successfully',
|
||||||
|
position: 'top',
|
||||||
|
status: 'success',
|
||||||
|
});
|
||||||
|
updateDisclosure.onClose();
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpen = () => {
|
||||||
|
window.open(`http://${internalIp}:${app.port}`, '_blank');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SlideFade in className="flex flex-1" offsetY="20px">
|
||||||
|
<div className="flex flex-1 bg-white p-4 mt-3 rounded-lg drop-shadow-xl flex-col">
|
||||||
|
<Flex className="flex-col md:flex-row">
|
||||||
|
<Image src={app?.image} height={180} width={180} className="rounded-xl self-center sm:self-auto" alt={app.name} />
|
||||||
|
<VStack align="flex-start" justify="space-between" className="ml-0 md:ml-4">
|
||||||
|
<div className="mt-3 items-center self-center flex flex-col sm:items-start sm:self-start md:mt-0">
|
||||||
|
<h1 className="font-bold text-2xl">{app?.name}</h1>
|
||||||
|
<h2 className="text-center md:text-left">{app?.short_desc}</h2>
|
||||||
|
{app.source && (
|
||||||
|
<a target="_blank" rel="noreferrer" className="text-blue-500 text-xs" href={app?.source}>
|
||||||
|
<Flex className="mt-2 items-center">
|
||||||
|
<FiExternalLink className="ml-1" />
|
||||||
|
</Flex>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
<p className="text-xs text-gray-600">By {app?.author}</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-center sm:absolute md:static top-0 right-5 self-center sm:self-auto">
|
||||||
|
<AppActions
|
||||||
|
onUpdate={updateDisclosure.onOpen}
|
||||||
|
onOpen={handleOpen}
|
||||||
|
onStart={handleStartSubmit}
|
||||||
|
onStop={stopDisclosure.onOpen}
|
||||||
|
onUninstall={uninstallDisclosure.onOpen}
|
||||||
|
onInstall={installDisclosure.onOpen}
|
||||||
|
app={app}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VStack>
|
||||||
|
</Flex>
|
||||||
|
<Divider className="mt-5" />
|
||||||
|
<p className="mt-3">{app?.description}</p>
|
||||||
|
<InstallModal onSubmit={handleInstallSubmit} isOpen={installDisclosure.isOpen} onClose={installDisclosure.onClose} app={app} />
|
||||||
|
<UninstallModal onConfirm={handleUnistallSubmit} isOpen={uninstallDisclosure.isOpen} onClose={uninstallDisclosure.onClose} app={app} />
|
||||||
|
<StopModal onConfirm={handleStopSubmit} isOpen={stopDisclosure.isOpen} onClose={stopDisclosure.onClose} app={app} />
|
||||||
|
<UpdateModal onSubmit={handleUpdateSubmit} isOpen={updateDisclosure.isOpen} onClose={updateDisclosure.onClose} app={app} />
|
||||||
|
</div>
|
||||||
|
</SlideFade>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppDetails;
|
|
@ -1,8 +1,16 @@
|
||||||
import { ChakraProvider } from "@chakra-ui/react";
|
import { ChakraProvider } from '@chakra-ui/react';
|
||||||
import "../styles/globals.css";
|
import '../styles/globals.css';
|
||||||
import type { AppProps } from "next/app";
|
import type { AppProps } from 'next/app';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useNetworkStore } from '../state/networkStore';
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }: AppProps) {
|
function MyApp({ Component, pageProps }: AppProps) {
|
||||||
|
const { fetchInternalIp } = useNetworkStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchInternalIp();
|
||||||
|
}, [fetchInternalIp]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChakraProvider>
|
<ChakraProvider>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import si from "systeminformation";
|
import si from 'systeminformation';
|
||||||
|
|
||||||
type Data = Awaited<ReturnType<typeof si.currentLoad>>;
|
type Data = Awaited<ReturnType<typeof si.currentLoad>>;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import si from "systeminformation";
|
import si from 'systeminformation';
|
||||||
|
|
||||||
type Data = Awaited<ReturnType<typeof si.fsSize>>;
|
type Data = Awaited<ReturnType<typeof si.fsSize>>;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import si from "systeminformation";
|
import si from 'systeminformation';
|
||||||
|
|
||||||
type Data = Awaited<ReturnType<typeof si.mem>>;
|
type Data = Awaited<ReturnType<typeof si.mem>>;
|
||||||
|
|
||||||
|
|
39
dashboard/src/pages/apps/[id].tsx
Normal file
39
dashboard/src/pages/apps/[id].tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import type { NextPage } from 'next';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import Layout from '../../components/Layout';
|
||||||
|
import { useAppsStore } from '../../state/appsStore';
|
||||||
|
import AppDetails from '../../modules/Apps/containers/AppDetails';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
appId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppDetailsPage: NextPage<IProps> = ({ appId }) => {
|
||||||
|
const { fetchApp, getApp } = useAppsStore((state) => state);
|
||||||
|
const app = getApp(appId);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchApp(appId);
|
||||||
|
}, [appId, fetchApp]);
|
||||||
|
|
||||||
|
const breadcrumb = [
|
||||||
|
{ name: 'Apps', href: '/apps' },
|
||||||
|
{ name: app?.name || '', href: `/apps/${appId}`, current: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout breadcrumbs={breadcrumb} loading={!app}>
|
||||||
|
{app && <AppDetails app={app} />}
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
AppDetailsPage.getInitialProps = async (ctx) => {
|
||||||
|
const { query } = ctx;
|
||||||
|
|
||||||
|
const appId = query.id as string;
|
||||||
|
|
||||||
|
return { appId };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppDetailsPage;
|
39
dashboard/src/pages/apps/index.tsx
Normal file
39
dashboard/src/pages/apps/index.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { Flex, SimpleGrid } from '@chakra-ui/react';
|
||||||
|
import type { NextPage } from 'next';
|
||||||
|
import Layout from '../../components/Layout';
|
||||||
|
import { RequestStatus } from '../../core/types';
|
||||||
|
import { useAppsStore } from '../../state/appsStore';
|
||||||
|
import AppTile from '../../components/AppTile';
|
||||||
|
|
||||||
|
const Apps: NextPage = () => {
|
||||||
|
const { available, installed, fetch, status } = useAppsStore((state) => state);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch();
|
||||||
|
}, [fetch]);
|
||||||
|
|
||||||
|
const installedCount: number = installed().length || 0;
|
||||||
|
const loading = status === RequestStatus.LOADING && !installed && !available;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout loading={loading}>
|
||||||
|
<Flex className="flex-col">
|
||||||
|
{installedCount > 0 && <h1 className="font-bold text-2xl mb-3">Your Apps ({installedCount})</h1>}
|
||||||
|
<SimpleGrid minChildWidth="400px" spacing="20px">
|
||||||
|
{installed().map((app) => (
|
||||||
|
<AppTile key={app.name} app={app} />
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
{available().length && <h1 className="font-bold text-2xl mb-3 mt-3">Available Apps</h1>}
|
||||||
|
<SimpleGrid minChildWidth="400px" spacing="20px">
|
||||||
|
{available().map((app) => (
|
||||||
|
<AppTile key={app.name} app={app} />
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
</Flex>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Apps;
|
|
@ -1,5 +1,5 @@
|
||||||
import type { NextPage } from "next";
|
import type { NextPage } from 'next';
|
||||||
import Layout from "../components/Layout";
|
import Layout from '../components/Layout';
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
return (
|
return (
|
||||||
|
|
12
dashboard/src/pages/settings.tsx
Normal file
12
dashboard/src/pages/settings.tsx
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import type { NextPage } from 'next';
|
||||||
|
import Layout from '../components/Layout';
|
||||||
|
|
||||||
|
const Settings: NextPage = () => {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<div>Settings</div>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Settings;
|
127
dashboard/src/state/appsStore.ts
Normal file
127
dashboard/src/state/appsStore.ts
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
import produce from 'immer';
|
||||||
|
import create, { GetState, SetState } from 'zustand';
|
||||||
|
import api from '../core/api';
|
||||||
|
import { AppConfig, AppStatus, RequestStatus } from '../core/types';
|
||||||
|
|
||||||
|
type AppsStore = {
|
||||||
|
apps: AppConfig[];
|
||||||
|
status: RequestStatus;
|
||||||
|
installed: () => AppConfig[];
|
||||||
|
available: () => AppConfig[];
|
||||||
|
fetch: () => void;
|
||||||
|
getApp: (id: string) => AppConfig | undefined;
|
||||||
|
fetchApp: (id: string) => void;
|
||||||
|
install: (id: string, form: Record<string, string>) => Promise<void>;
|
||||||
|
update: (id: string, form: Record<string, string>) => Promise<void>;
|
||||||
|
uninstall: (id: string) => Promise<void>;
|
||||||
|
stop: (id: string) => Promise<void>;
|
||||||
|
start: (id: string) => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Set = SetState<AppsStore>;
|
||||||
|
type Get = GetState<AppsStore>;
|
||||||
|
|
||||||
|
const sortApps = (apps: AppConfig[]) => apps.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
|
const setAppStatus = (appId: string, status: AppStatus, set: Set) => {
|
||||||
|
set((state) => {
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
const app = draft.apps.find((a) => a.id === appId);
|
||||||
|
if (app) app.status = status;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const installed = (get: Get) => {
|
||||||
|
const i = get().apps.filter((app) => app.installed);
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch one app and add it to the list of apps.
|
||||||
|
* @param appId
|
||||||
|
* @param set
|
||||||
|
*/
|
||||||
|
const fetchApp = async (appId: string, set: Set) => {
|
||||||
|
const response = await api.fetch<AppConfig>({
|
||||||
|
endpoint: `/apps/info/${appId}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
|
||||||
|
set((state) => {
|
||||||
|
const apps = state.apps.filter((app) => app.id !== appId);
|
||||||
|
apps.push(response);
|
||||||
|
|
||||||
|
return { ...state, apps: sortApps(apps) };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useAppsStore = create<AppsStore>((set, get) => ({
|
||||||
|
apps: [],
|
||||||
|
status: RequestStatus.LOADING,
|
||||||
|
installed: () => installed(get),
|
||||||
|
available: () => {
|
||||||
|
return get().apps.filter((app) => !app.installed);
|
||||||
|
},
|
||||||
|
fetchApp: async (appId: string) => fetchApp(appId, set),
|
||||||
|
fetch: async () => {
|
||||||
|
set({ status: RequestStatus.LOADING });
|
||||||
|
|
||||||
|
const response = await api.fetch<AppConfig[]>({
|
||||||
|
endpoint: '/apps/list',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
|
||||||
|
set({ apps: sortApps(response), status: RequestStatus.SUCCESS });
|
||||||
|
},
|
||||||
|
getApp: (appId: string) => {
|
||||||
|
return get().apps.find((app) => app.id === appId);
|
||||||
|
},
|
||||||
|
install: async (appId: string, form?: Record<string, string>) => {
|
||||||
|
setAppStatus(appId, AppStatus.INSTALLING, set);
|
||||||
|
|
||||||
|
await api.fetch({
|
||||||
|
endpoint: `/apps/install/${appId}`,
|
||||||
|
method: 'POST',
|
||||||
|
data: { form },
|
||||||
|
});
|
||||||
|
|
||||||
|
await get().fetchApp(appId);
|
||||||
|
},
|
||||||
|
update: async (appId: string, form?: Record<string, string>) => {
|
||||||
|
await api.fetch({
|
||||||
|
endpoint: `/apps/update/${appId}`,
|
||||||
|
method: 'POST',
|
||||||
|
data: { form },
|
||||||
|
});
|
||||||
|
|
||||||
|
await get().fetchApp(appId);
|
||||||
|
},
|
||||||
|
uninstall: async (appId: string) => {
|
||||||
|
setAppStatus(appId, AppStatus.UNINSTALLING, set);
|
||||||
|
|
||||||
|
await api.fetch({
|
||||||
|
endpoint: `/apps/uninstall/${appId}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await get().fetchApp(appId);
|
||||||
|
},
|
||||||
|
stop: async (appId: string) => {
|
||||||
|
setAppStatus(appId, AppStatus.STOPPING, set);
|
||||||
|
|
||||||
|
await api.fetch({
|
||||||
|
endpoint: `/apps/stop/${appId}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await get().fetchApp(appId);
|
||||||
|
},
|
||||||
|
start: async (appId: string) => {
|
||||||
|
setAppStatus(appId, AppStatus.STARTING, set);
|
||||||
|
|
||||||
|
await api.fetch({
|
||||||
|
endpoint: `/apps/start/${appId}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await get().fetchApp(appId);
|
||||||
|
},
|
||||||
|
}));
|
19
dashboard/src/state/networkStore.ts
Normal file
19
dashboard/src/state/networkStore.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import create from 'zustand';
|
||||||
|
import api from '../core/api';
|
||||||
|
|
||||||
|
type AppsStore = {
|
||||||
|
internalIp: string;
|
||||||
|
fetchInternalIp: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useNetworkStore = create<AppsStore>((set) => ({
|
||||||
|
internalIp: '',
|
||||||
|
fetchInternalIp: async () => {
|
||||||
|
const response = await api.fetch<string>({
|
||||||
|
endpoint: '/network/internal-ip',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
|
||||||
|
set({ internalIp: response });
|
||||||
|
},
|
||||||
|
}));
|
12
dashboard/src/state/uiStore.ts
Normal file
12
dashboard/src/state/uiStore.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import create from 'zustand';
|
||||||
|
|
||||||
|
type UIStore = {
|
||||||
|
menuItem: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUIStore = create<UIStore>((set) => ({
|
||||||
|
menuItem: 'dashboard',
|
||||||
|
setMenuItem: (menuItem: string) => {
|
||||||
|
set({ menuItem: menuItem });
|
||||||
|
},
|
||||||
|
}));
|
|
@ -1,6 +1,11 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||||
|
|
3
dashboard/src/utils/typescript.ts
Normal file
3
dashboard/src/utils/typescript.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const objectKeys = <T>(obj: T): (keyof T)[] => Object.keys(obj) as (keyof T)[];
|
||||||
|
|
||||||
|
export { objectKeys };
|
7
dashboard/tailwind.config.js
Normal file
7
dashboard/tailwind.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = {
|
||||||
|
content: ['./src/pages/**/*.{ts,tsx}', './src/components/**/*.{ts,tsx}', './src/modules/**/*.{ts,tsx}'],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
|
@ -57,6 +57,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
|
"@babel/runtime@^7.10.0", "@babel/runtime@^7.15.4":
|
||||||
|
version "7.17.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
|
||||||
|
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/types@^7.16.7":
|
"@babel/types@^7.16.7":
|
||||||
version "7.17.0"
|
version "7.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b"
|
||||||
|
@ -892,6 +899,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.8.tgz#be3e914e84eacf16dbebd311c0d0b44aa1174c64"
|
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.8.tgz#be3e914e84eacf16dbebd311c0d0b44aa1174c64"
|
||||||
integrity sha512-ZK5v4bJwgXldAUA8r3q9YKfCwOqoHTK/ZqRjSeRXQrBXWouoPnS4MQtgC4AXGiiBuUu5wxrRgTlv0ktmM4P1Aw==
|
integrity sha512-ZK5v4bJwgXldAUA8r3q9YKfCwOqoHTK/ZqRjSeRXQrBXWouoPnS4MQtgC4AXGiiBuUu5wxrRgTlv0ktmM4P1Aw==
|
||||||
|
|
||||||
|
"@types/json-schema@^7.0.9":
|
||||||
|
version "7.0.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
|
||||||
|
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
|
||||||
|
|
||||||
"@types/json5@^0.0.29":
|
"@types/json5@^0.0.29":
|
||||||
version "0.0.29"
|
version "0.0.29"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||||
|
@ -955,6 +967,21 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52"
|
resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52"
|
||||||
integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=
|
integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=
|
||||||
|
|
||||||
|
"@typescript-eslint/eslint-plugin@^5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.18.0.tgz#950df411cec65f90d75d6320a03b2c98f6c3af7d"
|
||||||
|
integrity sha512-tzrmdGMJI/uii9/V6lurMo4/o+dMTKDH82LkNjhJ3adCW22YQydoRs5MwTiqxGF9CSYxPxQ7EYb4jLNlIs+E+A==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/scope-manager" "5.18.0"
|
||||||
|
"@typescript-eslint/type-utils" "5.18.0"
|
||||||
|
"@typescript-eslint/utils" "5.18.0"
|
||||||
|
debug "^4.3.2"
|
||||||
|
functional-red-black-tree "^1.0.1"
|
||||||
|
ignore "^5.1.8"
|
||||||
|
regexpp "^3.2.0"
|
||||||
|
semver "^7.3.5"
|
||||||
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@5.10.1":
|
"@typescript-eslint/parser@5.10.1":
|
||||||
version "5.10.1"
|
version "5.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.1.tgz#4ce9633cc33fc70bc13786cb793c1a76fe5ad6bd"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.1.tgz#4ce9633cc33fc70bc13786cb793c1a76fe5ad6bd"
|
||||||
|
@ -973,11 +1000,33 @@
|
||||||
"@typescript-eslint/types" "5.10.1"
|
"@typescript-eslint/types" "5.10.1"
|
||||||
"@typescript-eslint/visitor-keys" "5.10.1"
|
"@typescript-eslint/visitor-keys" "5.10.1"
|
||||||
|
|
||||||
|
"@typescript-eslint/scope-manager@5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz#a7d7b49b973ba8cebf2a3710eefd457ef2fb5505"
|
||||||
|
integrity sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "5.18.0"
|
||||||
|
"@typescript-eslint/visitor-keys" "5.18.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/type-utils@5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.18.0.tgz#62dbfc8478abf36ba94a90ddf10be3cc8e471c74"
|
||||||
|
integrity sha512-vcn9/6J5D6jtHxpEJrgK8FhaM8r6J1/ZiNu70ZUJN554Y3D9t3iovi6u7JF8l/e7FcBIxeuTEidZDR70UuCIfA==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/utils" "5.18.0"
|
||||||
|
debug "^4.3.2"
|
||||||
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/types@5.10.1":
|
"@typescript-eslint/types@5.10.1":
|
||||||
version "5.10.1"
|
version "5.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.1.tgz#dca9bd4cb8c067fc85304a31f38ec4766ba2d1ea"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.1.tgz#dca9bd4cb8c067fc85304a31f38ec4766ba2d1ea"
|
||||||
integrity sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q==
|
integrity sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q==
|
||||||
|
|
||||||
|
"@typescript-eslint/types@5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.18.0.tgz#4f0425d85fdb863071680983853c59a62ce9566e"
|
||||||
|
integrity sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@5.10.1":
|
"@typescript-eslint/typescript-estree@5.10.1":
|
||||||
version "5.10.1"
|
version "5.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz#b268e67be0553f8790ba3fe87113282977adda15"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz#b268e67be0553f8790ba3fe87113282977adda15"
|
||||||
|
@ -991,6 +1040,31 @@
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/typescript-estree@5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz#6498e5ee69a32e82b6e18689e2f72e4060986474"
|
||||||
|
integrity sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "5.18.0"
|
||||||
|
"@typescript-eslint/visitor-keys" "5.18.0"
|
||||||
|
debug "^4.3.2"
|
||||||
|
globby "^11.0.4"
|
||||||
|
is-glob "^4.0.3"
|
||||||
|
semver "^7.3.5"
|
||||||
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/utils@5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.18.0.tgz#27fc84cf95c1a96def0aae31684cb43a37e76855"
|
||||||
|
integrity sha512-+hFGWUMMri7OFY26TsOlGa+zgjEy1ssEipxpLjtl4wSll8zy85x0GrUSju/FHdKfVorZPYJLkF3I4XPtnCTewA==
|
||||||
|
dependencies:
|
||||||
|
"@types/json-schema" "^7.0.9"
|
||||||
|
"@typescript-eslint/scope-manager" "5.18.0"
|
||||||
|
"@typescript-eslint/types" "5.18.0"
|
||||||
|
"@typescript-eslint/typescript-estree" "5.18.0"
|
||||||
|
eslint-scope "^5.1.1"
|
||||||
|
eslint-utils "^3.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@5.10.1":
|
"@typescript-eslint/visitor-keys@5.10.1":
|
||||||
version "5.10.1"
|
version "5.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz#29102de692f59d7d34ecc457ed59ab5fc558010b"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz#29102de692f59d7d34ecc457ed59ab5fc558010b"
|
||||||
|
@ -999,11 +1073,38 @@
|
||||||
"@typescript-eslint/types" "5.10.1"
|
"@typescript-eslint/types" "5.10.1"
|
||||||
eslint-visitor-keys "^3.0.0"
|
eslint-visitor-keys "^3.0.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/visitor-keys@5.18.0":
|
||||||
|
version "5.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz#c7c07709823804171d569017f3b031ced7253e60"
|
||||||
|
integrity sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "5.18.0"
|
||||||
|
eslint-visitor-keys "^3.0.0"
|
||||||
|
|
||||||
acorn-jsx@^5.3.1:
|
acorn-jsx@^5.3.1:
|
||||||
version "5.3.2"
|
version "5.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||||
|
|
||||||
|
acorn-node@^1.6.1:
|
||||||
|
version "1.8.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8"
|
||||||
|
integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==
|
||||||
|
dependencies:
|
||||||
|
acorn "^7.0.0"
|
||||||
|
acorn-walk "^7.0.0"
|
||||||
|
xtend "^4.0.2"
|
||||||
|
|
||||||
|
acorn-walk@^7.0.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
||||||
|
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
|
||||||
|
|
||||||
|
acorn@^7.0.0:
|
||||||
|
version "7.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||||
|
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||||
|
|
||||||
acorn@^8.7.0:
|
acorn@^8.7.0:
|
||||||
version "8.7.0"
|
version "8.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
|
||||||
|
@ -1038,6 +1139,19 @@ ansi-styles@^4.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^2.0.1"
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
|
anymatch@~3.1.2:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||||
|
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||||
|
dependencies:
|
||||||
|
normalize-path "^3.0.0"
|
||||||
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
|
arg@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.1.tgz#eb0c9a8f77786cad2af8ff2b862899842d7b6adb"
|
||||||
|
integrity sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==
|
||||||
|
|
||||||
argparse@^2.0.1:
|
argparse@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||||
|
@ -1097,11 +1211,30 @@ ast-types-flow@^0.0.7:
|
||||||
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||||
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
||||||
|
|
||||||
|
autoprefixer@^10.4.4:
|
||||||
|
version "10.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.4.tgz#3e85a245b32da876a893d3ac2ea19f01e7ea5a1e"
|
||||||
|
integrity sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA==
|
||||||
|
dependencies:
|
||||||
|
browserslist "^4.20.2"
|
||||||
|
caniuse-lite "^1.0.30001317"
|
||||||
|
fraction.js "^4.2.0"
|
||||||
|
normalize-range "^0.1.2"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
postcss-value-parser "^4.2.0"
|
||||||
|
|
||||||
axe-core@^4.3.5:
|
axe-core@^4.3.5:
|
||||||
version "4.4.1"
|
version "4.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413"
|
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413"
|
||||||
integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==
|
integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==
|
||||||
|
|
||||||
|
axios@^0.26.1:
|
||||||
|
version "0.26.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9"
|
||||||
|
integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==
|
||||||
|
dependencies:
|
||||||
|
follow-redirects "^1.14.8"
|
||||||
|
|
||||||
axobject-query@^2.2.0:
|
axobject-query@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
||||||
|
@ -1121,6 +1254,11 @@ balanced-match@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
|
binary-extensions@^2.0.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||||
|
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
|
@ -1129,13 +1267,24 @@ brace-expansion@^1.1.7:
|
||||||
balanced-match "^1.0.0"
|
balanced-match "^1.0.0"
|
||||||
concat-map "0.0.1"
|
concat-map "0.0.1"
|
||||||
|
|
||||||
braces@^3.0.2:
|
braces@^3.0.2, braces@~3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||||
dependencies:
|
dependencies:
|
||||||
fill-range "^7.0.1"
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
|
browserslist@^4.20.2:
|
||||||
|
version "4.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88"
|
||||||
|
integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==
|
||||||
|
dependencies:
|
||||||
|
caniuse-lite "^1.0.30001317"
|
||||||
|
electron-to-chromium "^1.4.84"
|
||||||
|
escalade "^3.1.1"
|
||||||
|
node-releases "^2.0.2"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
|
||||||
call-bind@^1.0.0, call-bind@^1.0.2:
|
call-bind@^1.0.0, call-bind@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||||
|
@ -1149,11 +1298,21 @@ callsites@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||||
|
|
||||||
|
camelcase-css@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
|
||||||
|
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
|
||||||
|
|
||||||
caniuse-lite@^1.0.30001283:
|
caniuse-lite@^1.0.30001283:
|
||||||
version "1.0.30001323"
|
version "1.0.30001323"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz#a451ff80dec7033016843f532efda18f02eec011"
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz#a451ff80dec7033016843f532efda18f02eec011"
|
||||||
integrity sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA==
|
integrity sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA==
|
||||||
|
|
||||||
|
caniuse-lite@^1.0.30001317:
|
||||||
|
version "1.0.30001327"
|
||||||
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001327.tgz#c1546d7d7bb66506f0ccdad6a7d07fc6d668c858"
|
||||||
|
integrity sha512-1/Cg4jlD9qjZzhbzkzEaAC2JHsP0WrOc8Rd/3a3LuajGzGWR/hD7TVyvq99VqmTy99eVh8Zkmdq213OgvgXx7w==
|
||||||
|
|
||||||
chalk@^2.0.0:
|
chalk@^2.0.0:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||||
|
@ -1163,7 +1322,7 @@ chalk@^2.0.0:
|
||||||
escape-string-regexp "^1.0.5"
|
escape-string-regexp "^1.0.5"
|
||||||
supports-color "^5.3.0"
|
supports-color "^5.3.0"
|
||||||
|
|
||||||
chalk@^4.0.0:
|
chalk@^4.0.0, chalk@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||||
|
@ -1171,6 +1330,26 @@ chalk@^4.0.0:
|
||||||
ansi-styles "^4.1.0"
|
ansi-styles "^4.1.0"
|
||||||
supports-color "^7.1.0"
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
|
chokidar@^3.5.3:
|
||||||
|
version "3.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||||
|
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||||
|
dependencies:
|
||||||
|
anymatch "~3.1.2"
|
||||||
|
braces "~3.0.2"
|
||||||
|
glob-parent "~5.1.2"
|
||||||
|
is-binary-path "~2.1.0"
|
||||||
|
is-glob "~4.0.1"
|
||||||
|
normalize-path "~3.0.0"
|
||||||
|
readdirp "~3.6.0"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
clsx@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||||
|
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||||
|
|
||||||
color-convert@^1.9.0:
|
color-convert@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||||
|
@ -1190,7 +1369,7 @@ color-name@1.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||||
|
|
||||||
color-name@~1.1.4:
|
color-name@^1.1.4, color-name@~1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
@ -1205,6 +1384,11 @@ concat-map@0.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
|
confusing-browser-globals@^1.0.10:
|
||||||
|
version "1.0.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81"
|
||||||
|
integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==
|
||||||
|
|
||||||
convert-source-map@^1.5.0:
|
convert-source-map@^1.5.0:
|
||||||
version "1.8.0"
|
version "1.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
|
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
|
||||||
|
@ -1235,6 +1419,17 @@ cosmiconfig@^6.0.0:
|
||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
yaml "^1.7.2"
|
yaml "^1.7.2"
|
||||||
|
|
||||||
|
cosmiconfig@^7.0.1:
|
||||||
|
version "7.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d"
|
||||||
|
integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/parse-json" "^4.0.0"
|
||||||
|
import-fresh "^3.2.1"
|
||||||
|
parse-json "^5.0.0"
|
||||||
|
path-type "^4.0.0"
|
||||||
|
yaml "^1.10.0"
|
||||||
|
|
||||||
cross-spawn@^7.0.2:
|
cross-spawn@^7.0.2:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
|
@ -1251,6 +1446,11 @@ css-box-model@1.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
tiny-invariant "^1.0.6"
|
tiny-invariant "^1.0.6"
|
||||||
|
|
||||||
|
cssesc@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||||
|
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||||
|
|
||||||
csstype@3.0.9:
|
csstype@3.0.9:
|
||||||
version "3.0.9"
|
version "3.0.9"
|
||||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b"
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b"
|
||||||
|
@ -1299,11 +1499,30 @@ define-properties@^1.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
object-keys "^1.0.12"
|
object-keys "^1.0.12"
|
||||||
|
|
||||||
|
defined@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||||
|
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
|
||||||
|
|
||||||
detect-node-es@^1.1.0:
|
detect-node-es@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
|
resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
|
||||||
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
|
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
|
||||||
|
|
||||||
|
detective@^5.2.0:
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b"
|
||||||
|
integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==
|
||||||
|
dependencies:
|
||||||
|
acorn-node "^1.6.1"
|
||||||
|
defined "^1.0.0"
|
||||||
|
minimist "^1.1.1"
|
||||||
|
|
||||||
|
didyoumean@^1.2.2:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
|
||||||
|
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
|
||||||
|
|
||||||
dir-glob@^3.0.1:
|
dir-glob@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||||
|
@ -1311,6 +1530,11 @@ dir-glob@^3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
|
|
||||||
|
dlv@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
|
||||||
|
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
|
||||||
|
|
||||||
doctrine@^2.1.0:
|
doctrine@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
||||||
|
@ -1325,6 +1549,11 @@ doctrine@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
|
|
||||||
|
electron-to-chromium@^1.4.84:
|
||||||
|
version "1.4.106"
|
||||||
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.106.tgz#e7a3bfa9d745dd9b9e597616cb17283cc349781a"
|
||||||
|
integrity sha512-ZYfpVLULm67K7CaaGP7DmjyeMY4naxsbTy+syVVxT6QHI1Ww8XbJjmr9fDckrhq44WzCrcC5kH3zGpdusxwwqg==
|
||||||
|
|
||||||
emoji-regex@^9.2.2:
|
emoji-regex@^9.2.2:
|
||||||
version "9.2.2"
|
version "9.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
||||||
|
@ -1372,6 +1601,11 @@ es-to-primitive@^1.2.1:
|
||||||
is-date-object "^1.0.1"
|
is-date-object "^1.0.1"
|
||||||
is-symbol "^1.0.2"
|
is-symbol "^1.0.2"
|
||||||
|
|
||||||
|
escalade@^3.1.1:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||||
|
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||||
|
|
||||||
escape-string-regexp@^1.0.5:
|
escape-string-regexp@^1.0.5:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||||
|
@ -1382,6 +1616,23 @@ escape-string-regexp@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||||
|
|
||||||
|
eslint-config-airbnb-base@^15.0.0:
|
||||||
|
version "15.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236"
|
||||||
|
integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==
|
||||||
|
dependencies:
|
||||||
|
confusing-browser-globals "^1.0.10"
|
||||||
|
object.assign "^4.1.2"
|
||||||
|
object.entries "^1.1.5"
|
||||||
|
semver "^6.3.0"
|
||||||
|
|
||||||
|
eslint-config-airbnb-typescript@^17.0.0:
|
||||||
|
version "17.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.0.0.tgz#360dbcf810b26bbcf2ff716198465775f1c49a07"
|
||||||
|
integrity sha512-elNiuzD0kPAPTXjFWg+lE24nMdHMtuxgYoD30OyMD6yrW1AhFZPAg27VX7d3tzOErw+dgJTNWfRSDqEcXb4V0g==
|
||||||
|
dependencies:
|
||||||
|
eslint-config-airbnb-base "^15.0.0"
|
||||||
|
|
||||||
eslint-config-next@12.1.4:
|
eslint-config-next@12.1.4:
|
||||||
version "12.1.4"
|
version "12.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.1.4.tgz#939ea2ff33034763300bf1e62482cea91212d274"
|
resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.1.4.tgz#939ea2ff33034763300bf1e62482cea91212d274"
|
||||||
|
@ -1494,6 +1745,14 @@ eslint-plugin-react@7.29.1:
|
||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
string.prototype.matchall "^4.0.6"
|
string.prototype.matchall "^4.0.6"
|
||||||
|
|
||||||
|
eslint-scope@^5.1.1:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||||
|
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
|
||||||
|
dependencies:
|
||||||
|
esrecurse "^4.3.0"
|
||||||
|
estraverse "^4.1.1"
|
||||||
|
|
||||||
eslint-scope@^7.1.1:
|
eslint-scope@^7.1.1:
|
||||||
version "7.1.1"
|
version "7.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
|
||||||
|
@ -1583,6 +1842,11 @@ esrecurse@^4.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
estraverse "^5.2.0"
|
estraverse "^5.2.0"
|
||||||
|
|
||||||
|
estraverse@^4.1.1:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||||
|
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||||
|
|
||||||
estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
|
estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||||
|
@ -1598,7 +1862,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
fast-glob@^3.2.9:
|
fast-glob@^3.2.11, fast-glob@^3.2.9:
|
||||||
version "3.2.11"
|
version "3.2.11"
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
|
||||||
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
|
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
|
||||||
|
@ -1640,6 +1904,13 @@ fill-range@^7.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
to-regex-range "^5.0.1"
|
to-regex-range "^5.0.1"
|
||||||
|
|
||||||
|
final-form@^4.20.6:
|
||||||
|
version "4.20.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.20.6.tgz#da42f3741db068c0c875e18950a2c4a9a148c63e"
|
||||||
|
integrity sha512-fCdwIj49KOaFfDRlXB57Eo+GghIMZQWrA9TakQI3C9uQxHwaFHXqZSNRlUdfnQmNNeySwGOaGPZCvjy58hyv4w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.10.0"
|
||||||
|
|
||||||
find-root@^1.1.0:
|
find-root@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
|
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
|
||||||
|
@ -1672,6 +1943,16 @@ focus-lock@^0.9.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.0.3"
|
tslib "^2.0.3"
|
||||||
|
|
||||||
|
follow-redirects@^1.14.8:
|
||||||
|
version "1.14.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
|
||||||
|
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
|
||||||
|
|
||||||
|
fraction.js@^4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
|
||||||
|
integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==
|
||||||
|
|
||||||
framer-motion@^6:
|
framer-motion@^6:
|
||||||
version "6.2.8"
|
version "6.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.2.8.tgz#02abb529191af7e2df444185fe27e932215b715d"
|
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.2.8.tgz#02abb529191af7e2df444185fe27e932215b715d"
|
||||||
|
@ -1704,6 +1985,11 @@ fs.realpath@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||||
|
|
||||||
|
fsevents@~2.3.2:
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||||
|
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||||
|
|
||||||
function-bind@^1.1.1:
|
function-bind@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
|
@ -1736,14 +2022,14 @@ get-symbol-description@^1.0.0:
|
||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
get-intrinsic "^1.1.1"
|
get-intrinsic "^1.1.1"
|
||||||
|
|
||||||
glob-parent@^5.1.2:
|
glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||||
dependencies:
|
dependencies:
|
||||||
is-glob "^4.0.1"
|
is-glob "^4.0.1"
|
||||||
|
|
||||||
glob-parent@^6.0.1:
|
glob-parent@^6.0.1, glob-parent@^6.0.2:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||||
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
||||||
|
@ -1839,11 +2125,16 @@ hoist-non-react-statics@^3.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
react-is "^16.7.0"
|
react-is "^16.7.0"
|
||||||
|
|
||||||
ignore@^5.2.0:
|
ignore@^5.1.8, ignore@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
|
||||||
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
|
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
|
||||||
|
|
||||||
|
immer@^9.0.12:
|
||||||
|
version "9.0.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.12.tgz#2d33ddf3ee1d247deab9d707ca472c8c942a0f20"
|
||||||
|
integrity sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==
|
||||||
|
|
||||||
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
|
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||||
|
@ -1898,6 +2189,13 @@ is-bigint@^1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
has-bigints "^1.0.1"
|
has-bigints "^1.0.1"
|
||||||
|
|
||||||
|
is-binary-path@~2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||||
|
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||||
|
dependencies:
|
||||||
|
binary-extensions "^2.0.0"
|
||||||
|
|
||||||
is-boolean-object@^1.1.0:
|
is-boolean-object@^1.1.0:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
|
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
|
||||||
|
@ -1930,7 +2228,7 @@ is-extglob@^2.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||||
|
|
||||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
|
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||||
|
@ -2055,6 +2353,11 @@ levn@^0.4.1:
|
||||||
prelude-ls "^1.2.1"
|
prelude-ls "^1.2.1"
|
||||||
type-check "~0.4.0"
|
type-check "~0.4.0"
|
||||||
|
|
||||||
|
lilconfig@^2.0.5:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.5.tgz#19e57fd06ccc3848fd1891655b5a447092225b25"
|
||||||
|
integrity sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==
|
||||||
|
|
||||||
lines-and-columns@^1.1.6:
|
lines-and-columns@^1.1.6:
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||||
|
@ -2112,7 +2415,7 @@ minimatch@^3.0.4, minimatch@^3.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.2.0, minimist@^1.2.6:
|
minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6:
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
@ -2132,7 +2435,7 @@ ms@^2.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
nanoid@^3.1.30:
|
nanoid@^3.1.30, nanoid@^3.3.1:
|
||||||
version "3.3.2"
|
version "3.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557"
|
||||||
integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==
|
integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==
|
||||||
|
@ -2165,11 +2468,31 @@ next@12.1.4:
|
||||||
"@next/swc-win32-ia32-msvc" "12.1.4"
|
"@next/swc-win32-ia32-msvc" "12.1.4"
|
||||||
"@next/swc-win32-x64-msvc" "12.1.4"
|
"@next/swc-win32-x64-msvc" "12.1.4"
|
||||||
|
|
||||||
|
node-releases@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
|
||||||
|
integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
|
||||||
|
|
||||||
|
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||||
|
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||||
|
|
||||||
|
normalize-range@^0.1.2:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||||
|
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
|
||||||
|
|
||||||
object-assign@^4.1.1:
|
object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||||
|
|
||||||
|
object-hash@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
|
||||||
|
integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
|
||||||
|
|
||||||
object-inspect@^1.12.0, object-inspect@^1.9.0:
|
object-inspect@^1.12.0, object-inspect@^1.9.0:
|
||||||
version "1.12.0"
|
version "1.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
|
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
|
||||||
|
@ -2310,7 +2633,7 @@ picocolors@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||||
|
|
||||||
picomatch@^2.3.1:
|
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||||
|
@ -2325,6 +2648,41 @@ popmotion@11.0.3:
|
||||||
style-value-types "5.0.0"
|
style-value-types "5.0.0"
|
||||||
tslib "^2.1.0"
|
tslib "^2.1.0"
|
||||||
|
|
||||||
|
postcss-js@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00"
|
||||||
|
integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==
|
||||||
|
dependencies:
|
||||||
|
camelcase-css "^2.0.1"
|
||||||
|
|
||||||
|
postcss-load-config@^3.1.0:
|
||||||
|
version "3.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855"
|
||||||
|
integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==
|
||||||
|
dependencies:
|
||||||
|
lilconfig "^2.0.5"
|
||||||
|
yaml "^1.10.2"
|
||||||
|
|
||||||
|
postcss-nested@5.0.6:
|
||||||
|
version "5.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc"
|
||||||
|
integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==
|
||||||
|
dependencies:
|
||||||
|
postcss-selector-parser "^6.0.6"
|
||||||
|
|
||||||
|
postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9:
|
||||||
|
version "6.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
|
||||||
|
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
|
||||||
|
dependencies:
|
||||||
|
cssesc "^3.0.0"
|
||||||
|
util-deprecate "^1.0.2"
|
||||||
|
|
||||||
|
postcss-value-parser@^4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||||
|
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||||
|
|
||||||
postcss@8.4.5:
|
postcss@8.4.5:
|
||||||
version "8.4.5"
|
version "8.4.5"
|
||||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
|
||||||
|
@ -2334,6 +2692,15 @@ postcss@8.4.5:
|
||||||
picocolors "^1.0.0"
|
picocolors "^1.0.0"
|
||||||
source-map-js "^1.0.1"
|
source-map-js "^1.0.1"
|
||||||
|
|
||||||
|
postcss@^8.4.12, postcss@^8.4.6:
|
||||||
|
version "8.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905"
|
||||||
|
integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.3.1"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
source-map-js "^1.0.2"
|
||||||
|
|
||||||
prelude-ls@^1.2.1:
|
prelude-ls@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||||
|
@ -2358,6 +2725,11 @@ queue-microtask@^1.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||||
|
|
||||||
|
quick-lru@^5.1.1:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
|
||||||
|
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
|
||||||
|
|
||||||
react-clientside-effect@^1.2.5:
|
react-clientside-effect@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz#e2c4dc3c9ee109f642fac4f5b6e9bf5bcd2219a3"
|
resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz#e2c4dc3c9ee109f642fac4f5b6e9bf5bcd2219a3"
|
||||||
|
@ -2378,6 +2750,13 @@ react-fast-compare@3.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||||
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
||||||
|
|
||||||
|
react-final-form@^6.5.9:
|
||||||
|
version "6.5.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.5.9.tgz#644797d4c122801b37b58a76c87761547411190b"
|
||||||
|
integrity sha512-x3XYvozolECp3nIjly+4QqxdjSSWfcnpGEL5K8OBT6xmGrq5kBqbA6+/tOqoom9NwqIPPbxPNsOViFlbKgowbA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.15.4"
|
||||||
|
|
||||||
react-focus-lock@2.5.2:
|
react-focus-lock@2.5.2:
|
||||||
version "2.5.2"
|
version "2.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.5.2.tgz#f1e4db5e25cd8789351f2bd5ebe91e9dcb9c2922"
|
resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.5.2.tgz#f1e4db5e25cd8789351f2bd5ebe91e9dcb9c2922"
|
||||||
|
@ -2390,6 +2769,11 @@ react-focus-lock@2.5.2:
|
||||||
use-callback-ref "^1.2.5"
|
use-callback-ref "^1.2.5"
|
||||||
use-sidecar "^1.0.5"
|
use-sidecar "^1.0.5"
|
||||||
|
|
||||||
|
react-icons@^4.3.1:
|
||||||
|
version "4.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
|
||||||
|
integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
|
||||||
|
|
||||||
react-is@^16.13.1, react-is@^16.7.0:
|
react-is@^16.13.1, react-is@^16.7.0:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
|
@ -2430,6 +2814,13 @@ react@18.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
|
|
||||||
|
readdirp@~3.6.0:
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||||
|
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||||
|
dependencies:
|
||||||
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
regenerator-runtime@^0.13.4:
|
regenerator-runtime@^0.13.4:
|
||||||
version "0.13.9"
|
version "0.13.9"
|
||||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||||
|
@ -2453,7 +2844,7 @@ resolve-from@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||||
|
|
||||||
resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.20.0:
|
resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.0:
|
||||||
version "1.22.0"
|
version "1.22.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
||||||
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
|
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
|
||||||
|
@ -2539,7 +2930,7 @@ slash@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
source-map-js@^1.0.1:
|
source-map-js@^1.0.1, source-map-js@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||||
|
@ -2633,11 +3024,43 @@ supports-preserve-symlinks-flag@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
|
swr@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8"
|
||||||
|
integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==
|
||||||
|
|
||||||
systeminformation@^5.11.9:
|
systeminformation@^5.11.9:
|
||||||
version "5.11.9"
|
version "5.11.9"
|
||||||
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.9.tgz#95f2334e739dd224178948a2afaced7d9abfdf9d"
|
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.9.tgz#95f2334e739dd224178948a2afaced7d9abfdf9d"
|
||||||
integrity sha512-eeMtL9UJFR/LYG+2rpeAgZ0Va4ojlNQTkYiQH/xbbPwDjDMsaetj3Pkc+C1aH5G8mav6HvDY8kI4Vl4noksSkA==
|
integrity sha512-eeMtL9UJFR/LYG+2rpeAgZ0Va4ojlNQTkYiQH/xbbPwDjDMsaetj3Pkc+C1aH5G8mav6HvDY8kI4Vl4noksSkA==
|
||||||
|
|
||||||
|
tailwindcss@^3.0.23:
|
||||||
|
version "3.0.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.23.tgz#c620521d53a289650872a66adfcb4129d2200d10"
|
||||||
|
integrity sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA==
|
||||||
|
dependencies:
|
||||||
|
arg "^5.0.1"
|
||||||
|
chalk "^4.1.2"
|
||||||
|
chokidar "^3.5.3"
|
||||||
|
color-name "^1.1.4"
|
||||||
|
cosmiconfig "^7.0.1"
|
||||||
|
detective "^5.2.0"
|
||||||
|
didyoumean "^1.2.2"
|
||||||
|
dlv "^1.1.3"
|
||||||
|
fast-glob "^3.2.11"
|
||||||
|
glob-parent "^6.0.2"
|
||||||
|
is-glob "^4.0.3"
|
||||||
|
normalize-path "^3.0.0"
|
||||||
|
object-hash "^2.2.0"
|
||||||
|
postcss "^8.4.6"
|
||||||
|
postcss-js "^4.0.0"
|
||||||
|
postcss-load-config "^3.1.0"
|
||||||
|
postcss-nested "5.0.6"
|
||||||
|
postcss-selector-parser "^6.0.9"
|
||||||
|
postcss-value-parser "^4.2.0"
|
||||||
|
quick-lru "^5.1.1"
|
||||||
|
resolve "^1.22.0"
|
||||||
|
|
||||||
text-table@^0.2.0:
|
text-table@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||||
|
@ -2739,6 +3162,11 @@ use-sidecar@^1.0.1, use-sidecar@^1.0.5:
|
||||||
detect-node-es "^1.1.0"
|
detect-node-es "^1.1.0"
|
||||||
tslib "^1.9.3"
|
tslib "^1.9.3"
|
||||||
|
|
||||||
|
util-deprecate@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
|
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||||
|
|
||||||
v8-compile-cache@^2.0.3:
|
v8-compile-cache@^2.0.3:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||||
|
@ -2784,12 +3212,22 @@ wrappy@1:
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||||
|
|
||||||
|
xtend@^4.0.2:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||||
|
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||||
|
|
||||||
yallist@^4.0.0:
|
yallist@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||||
|
|
||||||
yaml@^1.7.2:
|
yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2:
|
||||||
version "1.10.2"
|
version "1.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||||
|
|
||||||
|
zustand@^3.7.2:
|
||||||
|
version "3.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.7.2.tgz#7b44c4f4a5bfd7a8296a3957b13e1c346f42514d"
|
||||||
|
integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: '3.7'
|
version: "3.7"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# gluetun:
|
# gluetun:
|
||||||
|
@ -19,41 +19,47 @@ services:
|
||||||
# networks:
|
# networks:
|
||||||
# - tipi_main_network
|
# - tipi_main_network
|
||||||
|
|
||||||
reverse-proxy:
|
# reverse-proxy:
|
||||||
container_name: reverse-proxy
|
# container_name: reverse-proxy
|
||||||
image: traefik:v2.6
|
# image: traefik:v2.6
|
||||||
restart: always
|
# restart: always
|
||||||
ports:
|
# ports:
|
||||||
- 80:80
|
# - 80:80
|
||||||
- 443:443
|
# - 443:443
|
||||||
- 8080:8080
|
# - 8080:8080
|
||||||
security_opt:
|
# security_opt:
|
||||||
- no-new-privileges:true
|
# - no-new-privileges:true
|
||||||
volumes:
|
# volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
# - /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
- ${PWD}/traefik:/root/.config
|
# - ${PWD}/traefik:/root/.config
|
||||||
networks:
|
# networks:
|
||||||
- tipi_main_network
|
# - tipi_main_network
|
||||||
|
|
||||||
dashboard:
|
dashboard:
|
||||||
build:
|
build:
|
||||||
context: ./dashboard
|
context: ./dashboard
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
INTERNAL_IP_ARG: ${INTERNAL_IP}
|
||||||
container_name: dashboard
|
container_name: dashboard
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/state:/app/state
|
- ${PWD}/state:/app/state
|
||||||
- ${PWD}/config:/app/config:ro
|
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
networks:
|
networks:
|
||||||
- tipi_main_network
|
- tipi_main_network
|
||||||
labels:
|
# labels:
|
||||||
traefik.enable: true
|
# traefik.enable: true
|
||||||
traefik.http.routers.dashboard.rule: Host(`tipi.local`)
|
# traefik.http.routers.dashboard.rule: Host(`tipi.local`)
|
||||||
# traefik.http.routers.dashboard.tls: true
|
# # traefik.http.routers.dashboard.tls: true
|
||||||
traefik.http.routers.dashboard.entrypoints: webinsecure
|
# traefik.http.routers.dashboard.entrypoints: webinsecure
|
||||||
traefik.http.routers.dashboard.service: dashboard
|
# traefik.http.routers.dashboard.service: dashboard
|
||||||
traefik.http.services.dashboard.loadbalancer.server.port: 3000
|
# traefik.http.services.dashboard.loadbalancer.server.port: 3000
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
tipi_main_network:
|
tipi_main_network:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 10.21.21.0/24
|
||||||
|
|
|
@ -87,12 +87,17 @@ compose() {
|
||||||
|
|
||||||
# Vars to use in compose file
|
# Vars to use in compose file
|
||||||
export APP_DATA_DIR="${app_data_dir}"
|
export APP_DATA_DIR="${app_data_dir}"
|
||||||
export APP_PASSWORD="password"
|
|
||||||
export APP_DIR="${app_dir}"
|
export APP_DIR="${app_dir}"
|
||||||
|
|
||||||
|
# TODO: Fix for dynamic detection
|
||||||
|
export DEVICE_IP="192.168.2.132"
|
||||||
|
export ROOT_FOLDER="${ROOT_FOLDER}"
|
||||||
|
|
||||||
|
# Docker-compose does not support multiple env files
|
||||||
|
# --env-file "${env_file}" \
|
||||||
|
|
||||||
docker-compose \
|
docker-compose \
|
||||||
--env-file "${env_file}" \
|
--env-file "${ROOT_FOLDER}/app-data/${app}/app.env" \
|
||||||
--env-file "${app_dir}/.env" \
|
|
||||||
--project-name "${app}" \
|
--project-name "${app}" \
|
||||||
--file "${app_compose_file}" \
|
--file "${app_compose_file}" \
|
||||||
--file "${common_compose_file}" \
|
--file "${common_compose_file}" \
|
||||||
|
@ -103,24 +108,25 @@ compose() {
|
||||||
if [[ "$command" = "install" ]]; then
|
if [[ "$command" = "install" ]]; then
|
||||||
compose "${app}" pull
|
compose "${app}" pull
|
||||||
|
|
||||||
|
# Copy default data dir to app data dir if it exists
|
||||||
|
if [[ -d "${ROOT_FOLDER}/apps/${app}/data" ]]; then
|
||||||
|
cp -r "${ROOT_FOLDER}/apps/${app}/data" "${app_data_dir}/data"
|
||||||
|
fi
|
||||||
|
|
||||||
compose "${app}" up -d
|
compose "${app}" up -d
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Removes images and destroys all data for an app
|
# Removes images and destroys all data for an app
|
||||||
if [[ "$command" = "uninstall" ]]; then
|
if [[ "$command" = "uninstall" ]]; then
|
||||||
|
|
||||||
echo "Removing images for app ${app}..."
|
echo "Removing images for app ${app}..."
|
||||||
compose "${app}" down --rmi all --remove-orphans
|
compose "${app}" down --remove-orphans
|
||||||
|
|
||||||
echo "Deleting app data for app ${app}..."
|
echo "Deleting app data for app ${app}..."
|
||||||
if [[ -d "${app_data_dir}" ]]; then
|
if [[ -d "${app_data_dir}" ]]; then
|
||||||
rm -rf "${app_data_dir}"
|
rm -rf "${app_data_dir}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Removing app ${app} from DB..."
|
|
||||||
update_installed_apps remove "${app}"
|
|
||||||
|
|
||||||
echo "Successfully uninstalled app ${app}"
|
echo "Successfully uninstalled app ${app}"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
ROOT_FOLDER="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/..)"
|
#!/usr/bin/env bash
|
||||||
|
set -e # Exit immediately if a command exits with a non-zero status.
|
||||||
|
|
||||||
# Constants
|
ROOT_FOLDER="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/..)"
|
||||||
NGINX_PORT="80"
|
|
||||||
# Apps
|
|
||||||
APP_PI_HOLE_PORT="8081"
|
|
||||||
APP_WG_EASY_PORT="8082"
|
|
||||||
APP_NEXTCLOUD_PORT="8082"
|
|
||||||
APP_ANONADDY_PORT="8083"
|
|
||||||
APP_SIMPLETORRENT_PORT="8084"
|
|
||||||
APP_FRESHRSS_PORT="8085"
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "======================================"
|
echo "======================================"
|
||||||
|
@ -21,43 +14,19 @@ echo "=============== TIPI ================="
|
||||||
echo "======================================"
|
echo "======================================"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Store paths to intermediary config files
|
|
||||||
ENV_FILE="./templates/.env"
|
|
||||||
|
|
||||||
# Remove intermediary config files
|
|
||||||
[[ -f "$ENV_FILE" ]] && rm -f "$ENV_FILE"
|
|
||||||
|
|
||||||
# Copy template configs to intermediary configs
|
|
||||||
[[ -f "./templates/.env-sample" ]] && cp "./templates/.env-sample" "$ENV_FILE"
|
|
||||||
|
|
||||||
# Install ansible if not installed
|
# Install ansible if not installed
|
||||||
if ! command -v ansible-playbook > /dev/null; then
|
if ! command -v ansible-playbook > /dev/null; then
|
||||||
echo "Installing Ansible..."
|
echo "Installing Ansible..."
|
||||||
sudo apt-get install -y software-properties-common
|
|
||||||
sudo apt-add-repository -y ppa:ansible/ansible
|
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y ansible
|
sudo apt-get install python3 python3-pip -y
|
||||||
|
sudo pip3 install ansible
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ansible-playbook ansible/setup.yml -i ansible/hosts -K
|
ansible-playbook ansible/setup.yml -i ansible/hosts -K
|
||||||
|
|
||||||
echo "Generating config files..."
|
# echo "Configuring permissions..."
|
||||||
for template in "${ENV_FILE}"; do
|
# echo
|
||||||
sed -i "s/<nginx-port>/${NGINX_PORT}/g" "${template}"
|
# find "$ROOT_FOLDER" -path "$ROOT_FOLDER/app-data" -prune -o -exec chown 1000:1000 {} + || true
|
||||||
# Apps
|
|
||||||
sed -i "s/<app-pi-hole-port>/${APP_PI_HOLE_PORT}/g" "${template}"
|
|
||||||
sed -i "s/<app-wgeasy-port>/${APP_WG_EASY_PORT}/g" "${template}"
|
|
||||||
sed -i "s/<app-nextcloud-port>/${APP_NEXTCLOUD_PORT}/g" "${template}"
|
|
||||||
sed -i "s/<app-anonaddy-port>/${APP_ANONADDY_PORT}/g" "${template}"
|
|
||||||
sed -i "s/<app-simpletorrent-port>/${APP_SIMPLETORRENT_PORT}/g" "${template}"
|
|
||||||
sed -i "s/<app-freshrss-port>/${APP_FRESHRSS_PORT}/g" "${template}"
|
|
||||||
done
|
|
||||||
|
|
||||||
mv -f "$ENV_FILE" "$ROOT_FOLDER/.env"
|
|
||||||
|
|
||||||
echo "Configuring permissions..."
|
|
||||||
echo
|
|
||||||
find "$ROOT_FOLDER" -path "$ROOT_FOLDER/app-data" -prune -o -exec chown 1000:1000 {} + || true
|
|
||||||
|
|
||||||
# Create configured status
|
# Create configured status
|
||||||
touch "${ROOT_FOLDER}/state/configured"
|
touch "${ROOT_FOLDER}/state/configured"
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
set -e # Exit immediately if a command exits with a non-zero status.
|
||||||
|
|
||||||
# use greadlink instead of readlink on osx
|
# use greadlink instead of readlink on osx
|
||||||
if [[ "$(uname)" == "Darwin" ]]; then
|
if [[ "$(uname)" == "Darwin" ]]; then
|
||||||
|
@ -9,7 +10,11 @@ fi
|
||||||
|
|
||||||
ROOT_FOLDER="$($readlink -f $(dirname "${BASH_SOURCE[0]}")/..)"
|
ROOT_FOLDER="$($readlink -f $(dirname "${BASH_SOURCE[0]}")/..)"
|
||||||
STATE_FOLDER="${ROOT_FOLDER}/state"
|
STATE_FOLDER="${ROOT_FOLDER}/state"
|
||||||
DOMAIN=local
|
|
||||||
|
INTERNAL_IP="$(hostname -I | awk '{print $1}')"
|
||||||
|
PUID="$(id -u)"
|
||||||
|
PGID="$(id -g)"
|
||||||
|
TZ="$(cat /etc/timezone | sed 's/\//\\\//g' || echo "Europe/Berlin")"
|
||||||
|
|
||||||
if [[ $UID != 0 ]]; then
|
if [[ $UID != 0 ]]; then
|
||||||
echo "Tipi must be started as root"
|
echo "Tipi must be started as root"
|
||||||
|
@ -23,13 +28,40 @@ if [[ ! -f "${STATE_FOLDER}/configured" ]]; then
|
||||||
"${ROOT_FOLDER}/scripts/configure.sh"
|
"${ROOT_FOLDER}/scripts/configure.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ansible-playbook ansible/start.yml -i ansible/hosts -K
|
# Copy the app state if it isn't here
|
||||||
|
if [[ ! -f "${STATE_FOLDER}/apps.json" ]]; then
|
||||||
|
cp "${ROOT_FOLDER}/templates/apps-sample.json" "${STATE_FOLDER}/apps.json"
|
||||||
|
fi
|
||||||
|
|
||||||
export DOCKER_CLIENT_TIMEOUT=240
|
export DOCKER_CLIENT_TIMEOUT=240
|
||||||
export COMPOSE_HTTP_TIMEOUT=240
|
export COMPOSE_HTTP_TIMEOUT=240
|
||||||
|
|
||||||
|
echo "Generating config files..."
|
||||||
|
# Remove current .env file
|
||||||
|
[[ -f "${ROOT_FOLDER}/.env" ]] && rm -f "${ROOT_FOLDER}/.env"
|
||||||
|
|
||||||
|
# Store paths to intermediary config files
|
||||||
|
ENV_FILE="$ROOT_FOLDER/templates/.env"
|
||||||
|
|
||||||
|
# Remove intermediary config files
|
||||||
|
[[ -f "$ENV_FILE" ]] && rm -f "$ENV_FILE"
|
||||||
|
|
||||||
|
# Copy template configs to intermediary configs
|
||||||
|
[[ -f "$ROOT_FOLDER/templates/env-sample" ]] && cp "$ROOT_FOLDER/templates/env-sample" "$ENV_FILE"
|
||||||
|
|
||||||
|
for template in "${ENV_FILE}"; do
|
||||||
|
sed -i "s/<internal_ip>/${INTERNAL_IP}/g" "${template}"
|
||||||
|
sed -i "s/<puid>/${PUID}/g" "${template}"
|
||||||
|
sed -i "s/<pgid>/${PGID}/g" "${template}"
|
||||||
|
sed -i "s/<tz>/${TZ}/g" "${template}"
|
||||||
|
done
|
||||||
|
|
||||||
|
mv -f "$ENV_FILE" "$ROOT_FOLDER/.env"
|
||||||
|
|
||||||
|
ansible-playbook ansible/start.yml -i ansible/hosts -K
|
||||||
|
|
||||||
# Run docker-compose
|
# Run docker-compose
|
||||||
docker-compose up --detach --remove-orphans --build || {
|
docker-compose --env-file "${ROOT_FOLDER}/.env" up --detach --remove-orphans --build || {
|
||||||
echo "Failed to start containers"
|
echo "Failed to start containers"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
@ -49,3 +81,32 @@ for app in "${apps_to_start[@]}"; do
|
||||||
"${ROOT_FOLDER}/scripts/app.sh" start $app
|
"${ROOT_FOLDER}/scripts/app.sh" start $app
|
||||||
done
|
done
|
||||||
|
|
||||||
|
echo "Tipi is now running"
|
||||||
|
echo ""
|
||||||
|
cat << "EOF"
|
||||||
|
_,.
|
||||||
|
,` -.)
|
||||||
|
'( _/'-\\-.
|
||||||
|
/,|`--._,-^| ,
|
||||||
|
\_| |`-._/|| ,'|
|
||||||
|
| `-, / | / /
|
||||||
|
| || | / /
|
||||||
|
`r-._||/ __ / /
|
||||||
|
__,-<_ )`-/ `./ /
|
||||||
|
' \ `---' \ / /
|
||||||
|
| |./ /
|
||||||
|
/ // /
|
||||||
|
\_/' \ |/ /
|
||||||
|
| | _,^-'/ /
|
||||||
|
| , `` (\/ /_
|
||||||
|
\,.->._ \X-=/^
|
||||||
|
( / `-._//^`
|
||||||
|
`Y-.____(__}
|
||||||
|
| {__)
|
||||||
|
()`
|
||||||
|
EOF
|
||||||
|
echo ""
|
||||||
|
echo "Visit http://${INTERNAL_IP}:3000 to view the dashboard"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"installed": "",
|
|
||||||
"environment": {
|
|
||||||
"anonaddy": {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +1,18 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
env: { node: true },
|
env: { node: true },
|
||||||
extends: ['airbnb-base', 'eslint:recommended', 'plugin:import/typescript'],
|
extends: ['airbnb-typescript', 'eslint:recommended', 'plugin:import/typescript'],
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
|
project: './tsconfig.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
ecmaVersion: 'latest',
|
ecmaVersion: 'latest',
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
plugins: ['@typescript-eslint', 'import'],
|
plugins: ['@typescript-eslint', 'import', 'react'],
|
||||||
rules: {
|
rules: {
|
||||||
'arrow-body-style': 0,
|
'arrow-body-style': 0,
|
||||||
'no-restricted-exports': 0,
|
'no-restricted-exports': 0,
|
||||||
'max-len': [{ code: 200 }],
|
'max-len': [1, { code: 200 }],
|
||||||
'import/extensions': ['error', 'ignorePackages', { js: 'never', jsx: 'never', ts: 'never', tsx: 'never' }],
|
'import/extensions': ['error', 'ignorePackages', { js: 'never', jsx: 'never', ts: 'never', tsx: 'never' }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
464
system-api/package-lock.json
generated
464
system-api/package-lock.json
generated
|
@ -10,16 +10,22 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"helmet": "^5.0.2",
|
"helmet": "^5.0.2",
|
||||||
|
"internal-ip": "^7.0.0",
|
||||||
"node-port-scanner": "^3.0.1",
|
"node-port-scanner": "^3.0.1",
|
||||||
|
"p-iteration": "^1.1.8",
|
||||||
"public-ip": "^5.0.0",
|
"public-ip": "^5.0.0",
|
||||||
"systeminformation": "^5.11.9"
|
"systeminformation": "^5.11.9",
|
||||||
|
"tcp-port-used": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
|
"@types/cors": "^2.8.12",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/tcp-port-used": "^1.0.1",
|
||||||
"@types/validator": "^13.7.2",
|
"@types/validator": "^13.7.2",
|
||||||
"concurrently": "^7.1.0",
|
"concurrently": "^7.1.0",
|
||||||
"esbuild": "^0.14.32",
|
"esbuild": "^0.14.32",
|
||||||
|
@ -27,8 +33,10 @@
|
||||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
"eslint-config-hardcore": "^24.5.0",
|
"eslint-config-hardcore": "^24.5.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-config-react": "^1.1.7",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"eslint-plugin-react": "^7.29.4",
|
||||||
"eslint-plugin-unicorn": "^42.0.0",
|
"eslint-plugin-unicorn": "^42.0.0",
|
||||||
"nodemon": "^2.0.15",
|
"nodemon": "^2.0.15",
|
||||||
"prettier": "2.6.2"
|
"prettier": "2.6.2"
|
||||||
|
@ -3176,6 +3184,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/cors": {
|
||||||
|
"version": "2.8.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
||||||
|
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/debug": {
|
"node_modules/@types/debug": {
|
||||||
"version": "4.1.7",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
|
||||||
|
@ -3336,6 +3350,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/tcp-port-used": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/tcp-port-used/-/tcp-port-used-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-6pwWTx8oUtWvsiZUCrhrK/53MzKVLnuNSSaZILPy3uMes9QnTrLMar9BDlJArbMOjDcjb3QXFk6Rz8qmmuySZw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/unist": {
|
"node_modules/@types/unist": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
||||||
|
@ -4841,6 +4861,18 @@
|
||||||
"url": "https://opencollective.com/core-js"
|
"url": "https://opencollective.com/core-js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cosmiconfig": {
|
"node_modules/cosmiconfig": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
|
||||||
|
@ -4909,7 +4941,6 @@
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
"shebang-command": "^2.0.0",
|
"shebang-command": "^2.0.0",
|
||||||
|
@ -5081,8 +5112,7 @@
|
||||||
"node_modules/deep-is": {
|
"node_modules/deep-is": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/deepmerge": {
|
"node_modules/deepmerge": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
|
@ -5093,6 +5123,17 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/default-gateway": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"execa": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/defer-to-connect": {
|
"node_modules/defer-to-connect": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||||
|
@ -5921,6 +5962,12 @@
|
||||||
"eslint": ">=7.0.0"
|
"eslint": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-config-react": {
|
||||||
|
"version": "1.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-react/-/eslint-config-react-1.1.7.tgz",
|
||||||
|
"integrity": "sha1-oJGND8R9DpvRYaRzCAIdqF0lhbM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/eslint-etc": {
|
"node_modules/eslint-etc": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-etc/-/eslint-etc-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-etc/-/eslint-etc-5.1.0.tgz",
|
||||||
|
@ -7095,6 +7142,28 @@
|
||||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
|
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/execa": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.3",
|
||||||
|
"get-stream": "^6.0.0",
|
||||||
|
"human-signals": "^2.1.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"npm-run-path": "^4.0.1",
|
||||||
|
"onetime": "^5.1.2",
|
||||||
|
"signal-exit": "^3.0.3",
|
||||||
|
"strip-final-newline": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/execall": {
|
"node_modules/execall": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
|
||||||
|
@ -7956,6 +8025,14 @@
|
||||||
"node": ">=10.19.0"
|
"node": ">=10.19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/human-signals": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
@ -8090,6 +8167,31 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/internal-ip": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-qE4TeD4brqC45Vq/+VASeMiS1KRyfBkR6HT2sh9pZVVCzSjPkaCEfKFU+dL0PRv7NHJtvoKN2r82G6wTfzorkw==",
|
||||||
|
"dependencies": {
|
||||||
|
"default-gateway": "^6.0.3",
|
||||||
|
"ipaddr.js": "^2.0.1",
|
||||||
|
"is-ip": "^3.1.0",
|
||||||
|
"p-event": "^4.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/internal-ip?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/internal-ip/node_modules/ipaddr.js": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/internal-slot": {
|
"node_modules/internal-slot": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
||||||
|
@ -8514,6 +8616,17 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-string": {
|
"node_modules/is-string": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
||||||
|
@ -8562,6 +8675,11 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-url": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
|
||||||
|
},
|
||||||
"node_modules/is-weakref": {
|
"node_modules/is-weakref": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
||||||
|
@ -8580,11 +8698,23 @@
|
||||||
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
|
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/is2": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
|
||||||
|
"dependencies": {
|
||||||
|
"deep-is": "^0.1.3",
|
||||||
|
"ip-regex": "^4.1.0",
|
||||||
|
"is-url": "^1.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/isexe": {
|
"node_modules/isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/isomorphic-git": {
|
"node_modules/isomorphic-git": {
|
||||||
"version": "1.17.0",
|
"version": "1.17.0",
|
||||||
|
@ -8938,6 +9068,7 @@
|
||||||
"version": "7.8.0",
|
"version": "7.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.0.tgz",
|
||||||
"integrity": "sha512-AmXqneQZL3KZMIgBpaPTeI6pfwh+xQ2vutMsyqOu1TBdEXFZgpG/80wuJ531w2ZN7TI0/oc8CPxzh/DKQudZqg==",
|
"integrity": "sha512-AmXqneQZL3KZMIgBpaPTeI6pfwh+xQ2vutMsyqOu1TBdEXFZgpG/80wuJ531w2ZN7TI0/oc8CPxzh/DKQudZqg==",
|
||||||
|
"deprecated": "Please update to latest patch version to fix memory leak https://github.com/isaacs/node-lru-cache/issues/227",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
|
@ -9310,6 +9441,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
},
|
},
|
||||||
|
"node_modules/merge-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||||
|
},
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
|
@ -9853,6 +9989,14 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mimic-fn": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mimic-response": {
|
"node_modules/mimic-response": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||||
|
@ -10126,6 +10270,17 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/npm-run-path": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/obj-props": {
|
"node_modules/obj-props": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz",
|
||||||
|
@ -10139,7 +10294,6 @@
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
@ -10268,6 +10422,20 @@
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/onetime": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
|
"dependencies": {
|
||||||
|
"mimic-fn": "^2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/optionator": {
|
"node_modules/optionator": {
|
||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||||
|
@ -10293,6 +10461,36 @@
|
||||||
"node": ">=12.20"
|
"node": ">=12.20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/p-event": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"p-timeout": "^3.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/p-finally": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/p-iteration": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-limit": {
|
"node_modules/p-limit": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
|
||||||
|
@ -10317,6 +10515,17 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/p-timeout": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"p-finally": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-try": {
|
"node_modules/p-try": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
||||||
|
@ -10630,7 +10839,6 @@
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
@ -12314,7 +12522,6 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"shebang-regex": "^3.0.0"
|
"shebang-regex": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
@ -12326,7 +12533,6 @@
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
@ -12348,8 +12554,7 @@
|
||||||
"node_modules/signal-exit": {
|
"node_modules/signal-exit": {
|
||||||
"version": "3.0.7",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/simple-concat": {
|
"node_modules/simple-concat": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
@ -12645,6 +12850,14 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strip-final-newline": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/strip-indent": {
|
"node_modules/strip-indent": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||||
|
@ -13146,6 +13359,36 @@
|
||||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/tcp-port-used": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "4.3.1",
|
||||||
|
"is2": "^2.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tcp-port-used/node_modules/debug": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tcp-port-used/node_modules/ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
},
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
@ -13915,7 +14158,6 @@
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
},
|
},
|
||||||
|
@ -16327,6 +16569,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/cors": {
|
||||||
|
"version": "2.8.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
||||||
|
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/debug": {
|
"@types/debug": {
|
||||||
"version": "4.1.7",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
|
||||||
|
@ -16487,6 +16735,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/tcp-port-used": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/tcp-port-used/-/tcp-port-used-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-6pwWTx8oUtWvsiZUCrhrK/53MzKVLnuNSSaZILPy3uMes9QnTrLMar9BDlJArbMOjDcjb3QXFk6Rz8qmmuySZw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/unist": {
|
"@types/unist": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
||||||
|
@ -17557,6 +17811,15 @@
|
||||||
"integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==",
|
"integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cosmiconfig": {
|
"cosmiconfig": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
|
||||||
|
@ -17613,7 +17876,6 @@
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
"shebang-command": "^2.0.0",
|
"shebang-command": "^2.0.0",
|
||||||
|
@ -17733,8 +17995,7 @@
|
||||||
"deep-is": {
|
"deep-is": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"deepmerge": {
|
"deepmerge": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
|
@ -17742,6 +18003,14 @@
|
||||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"default-gateway": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
|
||||||
|
"requires": {
|
||||||
|
"execa": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"defer-to-connect": {
|
"defer-to-connect": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||||
|
@ -18320,6 +18589,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
"eslint-config-react": {
|
||||||
|
"version": "1.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-react/-/eslint-config-react-1.1.7.tgz",
|
||||||
|
"integrity": "sha1-oJGND8R9DpvRYaRzCAIdqF0lhbM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"eslint-etc": {
|
"eslint-etc": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-etc/-/eslint-etc-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-etc/-/eslint-etc-5.1.0.tgz",
|
||||||
|
@ -19125,6 +19400,22 @@
|
||||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
|
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"execa": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||||
|
"requires": {
|
||||||
|
"cross-spawn": "^7.0.3",
|
||||||
|
"get-stream": "^6.0.0",
|
||||||
|
"human-signals": "^2.1.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"npm-run-path": "^4.0.1",
|
||||||
|
"onetime": "^5.1.2",
|
||||||
|
"signal-exit": "^3.0.3",
|
||||||
|
"strip-final-newline": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"execall": {
|
"execall": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
|
||||||
|
@ -19769,6 +20060,11 @@
|
||||||
"resolve-alpn": "^1.2.0"
|
"resolve-alpn": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"human-signals": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
@ -19861,6 +20157,24 @@
|
||||||
"integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
|
"integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"internal-ip": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-qE4TeD4brqC45Vq/+VASeMiS1KRyfBkR6HT2sh9pZVVCzSjPkaCEfKFU+dL0PRv7NHJtvoKN2r82G6wTfzorkw==",
|
||||||
|
"requires": {
|
||||||
|
"default-gateway": "^6.0.3",
|
||||||
|
"ipaddr.js": "^2.0.1",
|
||||||
|
"is-ip": "^3.1.0",
|
||||||
|
"p-event": "^4.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ipaddr.js": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"internal-slot": {
|
"internal-slot": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
||||||
|
@ -20157,6 +20471,11 @@
|
||||||
"call-bind": "^1.0.2"
|
"call-bind": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
|
||||||
|
},
|
||||||
"is-string": {
|
"is-string": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
||||||
|
@ -20190,6 +20509,11 @@
|
||||||
"unc-path-regex": "^0.1.2"
|
"unc-path-regex": "^0.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-url": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
|
||||||
|
},
|
||||||
"is-weakref": {
|
"is-weakref": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
||||||
|
@ -20205,11 +20529,20 @@
|
||||||
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
|
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is2": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
|
||||||
|
"requires": {
|
||||||
|
"deep-is": "^0.1.3",
|
||||||
|
"ip-regex": "^4.1.0",
|
||||||
|
"is-url": "^1.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"isexe": {
|
"isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"isomorphic-git": {
|
"isomorphic-git": {
|
||||||
"version": "1.17.0",
|
"version": "1.17.0",
|
||||||
|
@ -20762,6 +21095,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
},
|
},
|
||||||
|
"merge-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||||
|
},
|
||||||
"merge2": {
|
"merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
|
@ -21058,6 +21396,11 @@
|
||||||
"mime-db": "1.52.0"
|
"mime-db": "1.52.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mimic-fn": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
|
||||||
|
},
|
||||||
"mimic-response": {
|
"mimic-response": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||||
|
@ -21273,6 +21616,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
||||||
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
|
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
|
||||||
},
|
},
|
||||||
|
"npm-run-path": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
|
||||||
|
"requires": {
|
||||||
|
"path-key": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"obj-props": {
|
"obj-props": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz",
|
||||||
|
@ -21282,8 +21633,7 @@
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"object-inspect": {
|
"object-inspect": {
|
||||||
"version": "1.12.0",
|
"version": "1.12.0",
|
||||||
|
@ -21373,6 +21723,14 @@
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"onetime": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
|
"requires": {
|
||||||
|
"mimic-fn": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"optionator": {
|
"optionator": {
|
||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||||
|
@ -21392,6 +21750,24 @@
|
||||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
|
||||||
"integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw=="
|
"integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw=="
|
||||||
},
|
},
|
||||||
|
"p-event": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==",
|
||||||
|
"requires": {
|
||||||
|
"p-timeout": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-finally": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
|
||||||
|
},
|
||||||
|
"p-iteration": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ=="
|
||||||
|
},
|
||||||
"p-limit": {
|
"p-limit": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
|
||||||
|
@ -21410,6 +21786,14 @@
|
||||||
"p-limit": "^1.1.0"
|
"p-limit": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"p-timeout": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
|
||||||
|
"requires": {
|
||||||
|
"p-finally": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"p-try": {
|
"p-try": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
||||||
|
@ -21669,8 +22053,7 @@
|
||||||
"path-key": {
|
"path-key": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"path-parse": {
|
"path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
|
@ -22948,7 +23331,6 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"shebang-regex": "^3.0.0"
|
"shebang-regex": "^3.0.0"
|
||||||
}
|
}
|
||||||
|
@ -22956,8 +23338,7 @@
|
||||||
"shebang-regex": {
|
"shebang-regex": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"side-channel": {
|
"side-channel": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
@ -22973,8 +23354,7 @@
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.7",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"simple-concat": {
|
"simple-concat": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
@ -23192,6 +23572,11 @@
|
||||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"strip-final-newline": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
|
||||||
|
},
|
||||||
"strip-indent": {
|
"strip-indent": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||||
|
@ -23557,6 +23942,30 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tcp-port-used": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "4.3.1",
|
||||||
|
"is2": "^2.0.6"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"text-table": {
|
"text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
@ -24144,7 +24553,6 @@
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,22 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"helmet": "^5.0.2",
|
"helmet": "^5.0.2",
|
||||||
|
"internal-ip": "^7.0.0",
|
||||||
"node-port-scanner": "^3.0.1",
|
"node-port-scanner": "^3.0.1",
|
||||||
|
"p-iteration": "^1.1.8",
|
||||||
"public-ip": "^5.0.0",
|
"public-ip": "^5.0.0",
|
||||||
"systeminformation": "^5.11.9"
|
"systeminformation": "^5.11.9",
|
||||||
|
"tcp-port-used": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
|
"@types/cors": "^2.8.12",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/tcp-port-used": "^1.0.1",
|
||||||
"@types/validator": "^13.7.2",
|
"@types/validator": "^13.7.2",
|
||||||
"concurrently": "^7.1.0",
|
"concurrently": "^7.1.0",
|
||||||
"esbuild": "^0.14.32",
|
"esbuild": "^0.14.32",
|
||||||
|
@ -34,8 +40,10 @@
|
||||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
"eslint-config-hardcore": "^24.5.0",
|
"eslint-config-hardcore": "^24.5.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-config-react": "^1.1.7",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"eslint-plugin-react": "^7.29.4",
|
||||||
"eslint-plugin-unicorn": "^42.0.0",
|
"eslint-plugin-unicorn": "^42.0.0",
|
||||||
"nodemon": "^2.0.15",
|
"nodemon": "^2.0.15",
|
||||||
"prettier": "2.6.2"
|
"prettier": "2.6.2"
|
||||||
|
|
1
system-api/src/config/apps.ts
Normal file
1
system-api/src/config/apps.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const appNames = ['nextcloud', 'freshrss', 'anonaddy', 'filerun', 'wg-easy', 'radarr', 'transmission', 'jellyfin', 'pihole', 'busybox'];
|
|
@ -1,15 +1,34 @@
|
||||||
|
export enum FieldTypes {
|
||||||
|
text = 'text',
|
||||||
|
password = 'password',
|
||||||
|
email = 'email',
|
||||||
|
number = 'number',
|
||||||
|
fqdn = 'fqdn',
|
||||||
|
}
|
||||||
|
|
||||||
interface FormField {
|
interface FormField {
|
||||||
type: string;
|
type: FieldTypes;
|
||||||
label: string;
|
label: string;
|
||||||
max?: number;
|
max?: number;
|
||||||
min?: number;
|
min?: number;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
env_variable?: string;
|
env_variable: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppConfig {
|
export interface AppConfig {
|
||||||
|
id: string;
|
||||||
|
port: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
requirements?: {
|
||||||
|
ports?: number[];
|
||||||
|
};
|
||||||
description: string;
|
description: string;
|
||||||
version: string;
|
version: string;
|
||||||
|
image: string;
|
||||||
form_fields: Record<string, FormField>;
|
form_fields: Record<string, FormField>;
|
||||||
|
short_desc: string;
|
||||||
|
author: string;
|
||||||
|
source: string;
|
||||||
|
installed: boolean;
|
||||||
|
status: 'running' | 'stopped';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
|
import si from 'systeminformation';
|
||||||
|
import { appNames } from '../../config/apps';
|
||||||
import { AppConfig } from '../../config/types';
|
import { AppConfig } from '../../config/types';
|
||||||
import { createFolder, fileExists, readJsonFile, writeFile, copyFile, runScript, deleteFolder } from '../fs/fs.helpers';
|
import { createFolder, fileExists, readJsonFile, writeFile, readFile } from '../fs/fs.helpers';
|
||||||
|
import { checkAppExists, checkAppRequirements, checkEnvFile, ensureAppState, getInitalFormValues, runAppScript } from './apps.helpers';
|
||||||
|
|
||||||
type AppsState = { installed: string };
|
type AppsState = { installed: string };
|
||||||
|
|
||||||
|
@ -9,14 +12,9 @@ const getStateFile = (): AppsState => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateEnvFile = (appName: string, form: Record<string, string>) => {
|
const generateEnvFile = (appName: string, form: Record<string, string>) => {
|
||||||
const appExists = fileExists(`/app-data/${appName}`);
|
|
||||||
|
|
||||||
if (!appExists) {
|
|
||||||
throw new Error(`App ${appName} not installed`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const configFile: AppConfig = readJsonFile(`/apps/${appName}/config.json`);
|
const configFile: AppConfig = readJsonFile(`/apps/${appName}/config.json`);
|
||||||
let envFile = '';
|
const baseEnvFile = readFile('/.env').toString();
|
||||||
|
let envFile = `${baseEnvFile}\nAPP_PORT=${configFile.port}\n`;
|
||||||
|
|
||||||
Object.keys(configFile.form_fields).forEach((key) => {
|
Object.keys(configFile.form_fields).forEach((key) => {
|
||||||
const value = form[key];
|
const value = form[key];
|
||||||
|
@ -29,151 +27,191 @@ const generateEnvFile = (appName: string, form: Record<string, string>) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
writeFile(`/app-data/${appName}/.env`, envFile);
|
writeFile(`/app-data/${appName}/app.env`, envFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
const installApp = (req: Request, res: Response) => {
|
const uninstallApp = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const { appName, form } = req.body;
|
const { id: appName } = req.params;
|
||||||
|
|
||||||
if (!appName) {
|
if (!appName) {
|
||||||
throw new Error('App name is required');
|
throw new Error('App name is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
const appExists = fileExists(`/app-data/${appName}`);
|
checkAppExists(appName);
|
||||||
|
ensureAppState(appName, false);
|
||||||
if (appExists) {
|
|
||||||
throw new Error(`App ${appName} already installed`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create app folder
|
|
||||||
createFolder(`/app-data/${appName}`);
|
|
||||||
// Copy default app files from app-data folder
|
|
||||||
copyFile(`/apps/${appName}/data`, `/app-data/${appName}/data`);
|
|
||||||
|
|
||||||
// Create env file
|
|
||||||
generateEnvFile(appName, form);
|
|
||||||
const state = getStateFile();
|
|
||||||
state.installed += ` ${appName}`;
|
|
||||||
writeFile('/state/apps.json', JSON.stringify(state));
|
|
||||||
|
|
||||||
// Run script
|
// Run script
|
||||||
runScript('/scripts/app.sh', ['install', appName]);
|
await runAppScript(['uninstall', appName]);
|
||||||
|
|
||||||
res.status(200).json({ message: 'App installed successfully' });
|
|
||||||
} catch (e) {
|
|
||||||
res.status(500).send(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const uninstallApp = (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
const { appName } = req.body;
|
|
||||||
|
|
||||||
if (!appName) {
|
|
||||||
throw new Error('App name is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
const appExists = fileExists(`/app-data/${appName}`);
|
|
||||||
|
|
||||||
if (!appExists) {
|
|
||||||
throw new Error(`App ${appName} not installed`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete app folder
|
|
||||||
deleteFolder(`/app-data/${appName}`);
|
|
||||||
|
|
||||||
// Remove app from apps.json
|
|
||||||
const state = getStateFile();
|
|
||||||
state.installed = state.installed.replace(` ${appName}`, '');
|
|
||||||
writeFile('/state/apps.json', JSON.stringify(state));
|
|
||||||
|
|
||||||
// Run script
|
|
||||||
runScript('/scripts/app.sh', ['uninstall', appName]);
|
|
||||||
|
|
||||||
res.status(200).json({ message: 'App uninstalled successfully' });
|
res.status(200).json({ message: 'App uninstalled successfully' });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).send(e);
|
next(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopApp = (req: Request, res: Response) => {
|
const stopApp = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const { appName } = req.body;
|
const { id: appName } = req.params;
|
||||||
|
|
||||||
if (!appName) {
|
if (!appName) {
|
||||||
throw new Error('App name is required');
|
throw new Error('App name is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
const appExists = fileExists(`/app-data/${appName}`);
|
checkAppExists(appName);
|
||||||
|
|
||||||
if (!appExists) {
|
|
||||||
throw new Error(`App ${appName} not installed`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run script
|
// Run script
|
||||||
runScript('/scripts/app.sh', ['stop', appName]);
|
await runAppScript(['stop', appName]);
|
||||||
|
|
||||||
res.status(200).json({ message: 'App stopped successfully' });
|
res.status(200).json({ message: 'App stopped successfully' });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).end(e);
|
next(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateAppConfig = (req: Request, res: Response) => {
|
const updateAppConfig = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const { appName, form } = req.body;
|
const { id: appName } = req.params;
|
||||||
|
const { form } = req.body;
|
||||||
|
|
||||||
if (!appName) {
|
if (!appName) {
|
||||||
throw new Error('App name is required');
|
throw new Error('App name is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
const appExists = fileExists(`/app-data/${appName}`);
|
checkAppExists(appName);
|
||||||
|
|
||||||
if (!appExists) {
|
|
||||||
throw new Error(`App ${appName} not installed`);
|
|
||||||
}
|
|
||||||
|
|
||||||
generateEnvFile(appName, form);
|
generateEnvFile(appName, form);
|
||||||
|
|
||||||
// Run script
|
|
||||||
runScript('/scripts/app.sh', ['stop', appName]);
|
|
||||||
runScript('/scripts/app.sh', ['start', appName]);
|
|
||||||
|
|
||||||
res.status(200).json({ message: 'App updated successfully' });
|
res.status(200).json({ message: 'App updated successfully' });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).end(e);
|
next(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const installedApps = (req: Request, res: Response) => {
|
const getAppInfo = async (req: Request, res: Response<AppConfig>, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const apps = readJsonFile('/state/apps.json');
|
const { id } = req.params;
|
||||||
const appNames = apps.installed.split(' ');
|
|
||||||
|
|
||||||
if (appNames.length === 0) {
|
if (!id) {
|
||||||
res.status(204).json([]);
|
throw new Error('App name is required');
|
||||||
} else {
|
|
||||||
res.status(200).json(appNames);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dockerContainers = await si.dockerContainers();
|
||||||
|
const configFile: AppConfig = readJsonFile(`/apps/${id}/config.json`);
|
||||||
|
|
||||||
|
const state = getStateFile();
|
||||||
|
const installed: string[] = state.installed.split(' ').filter(Boolean);
|
||||||
|
configFile.installed = installed.includes(id);
|
||||||
|
configFile.status = (dockerContainers.find((container) => container.name === `${id}`)?.state as 'running') || 'stopped';
|
||||||
|
|
||||||
|
res.status(200).json(configFile);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).end(e);
|
next(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAppInfo = (req: Request, res: Response<AppConfig>) => {
|
const listApps = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const { appName } = req.body;
|
const apps = appNames
|
||||||
|
.map((app) => {
|
||||||
|
try {
|
||||||
|
return readJsonFile(`/apps/${app}/config.json`);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
const dockerContainers = await si.dockerContainers();
|
||||||
|
|
||||||
|
const state = getStateFile();
|
||||||
|
const installed: string[] = state.installed.split(' ').filter(Boolean);
|
||||||
|
|
||||||
|
apps.forEach((app) => {
|
||||||
|
app.installed = installed.includes(app.id);
|
||||||
|
app.status = dockerContainers.find((container) => container.name === `${app.id}`)?.state || 'stopped';
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json(apps);
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const startApp = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const { id: appName } = req.params;
|
||||||
|
|
||||||
if (!appName) {
|
if (!appName) {
|
||||||
throw new Error('App name is required');
|
throw new Error('App name is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
const configFile: AppConfig = readJsonFile(`/apps/${appName}/config.json`);
|
checkAppExists(appName);
|
||||||
|
checkEnvFile(appName);
|
||||||
|
|
||||||
res.status(200).json(configFile);
|
// Run script
|
||||||
|
await runAppScript(['start', appName]);
|
||||||
|
|
||||||
|
ensureAppState(appName, true);
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'App started successfully' });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).end(e);
|
next(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const installApp = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { form } = req.body;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
throw new Error('App name is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const appIsAvailable = appNames.includes(id);
|
||||||
|
|
||||||
|
if (!appIsAvailable) {
|
||||||
|
throw new Error(`App ${id} not available`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const appExists = fileExists(`/app-data/${id}`);
|
||||||
|
|
||||||
|
if (appExists) {
|
||||||
|
await startApp(req, res, next);
|
||||||
|
} else {
|
||||||
|
const appIsValid = await checkAppRequirements(id);
|
||||||
|
|
||||||
|
if (!appIsValid) {
|
||||||
|
throw new Error(`App ${id} requirements not met`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create app folder
|
||||||
|
createFolder(`/app-data/${id}`);
|
||||||
|
|
||||||
|
// Create env file
|
||||||
|
generateEnvFile(id, form);
|
||||||
|
ensureAppState(id, true);
|
||||||
|
|
||||||
|
// Run script
|
||||||
|
await runAppScript(['install', id]);
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'App installed successfully' });
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initalFormValues = (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const { id } = req.params;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
throw new Error('App name is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json(getInitalFormValues(id));
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,8 +220,10 @@ const AppController = {
|
||||||
installApp,
|
installApp,
|
||||||
stopApp,
|
stopApp,
|
||||||
updateAppConfig,
|
updateAppConfig,
|
||||||
installedApps,
|
|
||||||
getAppInfo,
|
getAppInfo,
|
||||||
|
listApps,
|
||||||
|
startApp,
|
||||||
|
initalFormValues,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AppController;
|
export default AppController;
|
||||||
|
|
101
system-api/src/modules/apps/apps.helpers.ts
Normal file
101
system-api/src/modules/apps/apps.helpers.ts
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
import portUsed from 'tcp-port-used';
|
||||||
|
import p from 'p-iteration';
|
||||||
|
import { AppConfig } from '../../config/types';
|
||||||
|
import { fileExists, readFile, readJsonFile, runScript, writeFile } from '../fs/fs.helpers';
|
||||||
|
import { internalIpV4 } from 'internal-ip';
|
||||||
|
|
||||||
|
export const checkAppRequirements = async (appName: string) => {
|
||||||
|
let valid = true;
|
||||||
|
const configFile: AppConfig = readJsonFile(`/apps/${appName}/config.json`);
|
||||||
|
|
||||||
|
if (configFile.requirements?.ports) {
|
||||||
|
await p.forEachSeries(configFile.requirements.ports, async (port: number) => {
|
||||||
|
const ip = await internalIpV4();
|
||||||
|
const used = await portUsed.check(port, ip);
|
||||||
|
|
||||||
|
if (used) valid = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getEnvMap = (appName: string): Map<string, string> => {
|
||||||
|
const envFile = readFile(`/app-data/${appName}/app.env`).toString();
|
||||||
|
const envVars = envFile.split('\n');
|
||||||
|
const envVarsMap = new Map<string, string>();
|
||||||
|
|
||||||
|
envVars.forEach((envVar) => {
|
||||||
|
const [key, value] = envVar.split('=');
|
||||||
|
envVarsMap.set(key, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return envVarsMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkEnvFile = (appName: string) => {
|
||||||
|
const configFile: AppConfig = readJsonFile(`/apps/${appName}/config.json`);
|
||||||
|
const envMap = getEnvMap(appName);
|
||||||
|
|
||||||
|
Object.keys(configFile.form_fields).forEach((key) => {
|
||||||
|
const envVar = configFile.form_fields[key].env_variable;
|
||||||
|
const envVarValue = envMap.get(envVar);
|
||||||
|
|
||||||
|
if (!envVarValue && configFile.form_fields[key].required) {
|
||||||
|
throw new Error('New info needed. App config needs to be updated');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getInitalFormValues = (appName: string): Record<string, string> => {
|
||||||
|
const configFile: AppConfig = readJsonFile(`/apps/${appName}/config.json`);
|
||||||
|
const envMap = getEnvMap(appName);
|
||||||
|
const formValues: Record<string, string> = {};
|
||||||
|
|
||||||
|
Object.keys(configFile.form_fields).forEach((key) => {
|
||||||
|
const envVar = configFile.form_fields[key].env_variable;
|
||||||
|
const envVarValue = envMap.get(envVar);
|
||||||
|
|
||||||
|
if (envVarValue) {
|
||||||
|
formValues[key] = envVarValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return formValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkAppExists = (appName: string) => {
|
||||||
|
const appExists = fileExists(`/app-data/${appName}`);
|
||||||
|
|
||||||
|
if (!appExists) {
|
||||||
|
throw new Error(`App ${appName} not installed`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const runAppScript = (params: string[]): Promise<void> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
runScript('/scripts/app.sh', params, (err: string) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ensureAppState = (appName: string, installed: boolean) => {
|
||||||
|
const state = readJsonFile('/state/apps.json');
|
||||||
|
|
||||||
|
if (installed) {
|
||||||
|
if (state.installed.indexOf(appName) === -1) {
|
||||||
|
state.installed += ` ${appName}`;
|
||||||
|
writeFile('/state/apps.json', JSON.stringify(state));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (state.installed.indexOf(appName) !== -1) {
|
||||||
|
state.installed = state.installed.replace(` ${appName}`, '');
|
||||||
|
writeFile('/state/apps.json', JSON.stringify(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,8 +3,13 @@ import AppController from './apps.controller';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.route('/install').post(AppController.installApp);
|
router.route('/install/:id').post(AppController.installApp);
|
||||||
router.route('/uninstall').post(AppController.uninstallApp);
|
router.route('/update/:id').post(AppController.updateAppConfig);
|
||||||
router.route('/list').get(AppController.installedApps);
|
router.route('/uninstall/:id').get(AppController.uninstallApp);
|
||||||
|
router.route('/stop/:id').get(AppController.stopApp);
|
||||||
|
router.route('/start/:id').get(AppController.startApp);
|
||||||
|
router.route('/list').get(AppController.listApps);
|
||||||
|
router.route('/info/:id').get(AppController.getAppInfo);
|
||||||
|
router.route('/form/:id').get(AppController.initalFormValues);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
@ -9,6 +9,8 @@ export const readJsonFile = (path: string): any => {
|
||||||
return JSON.parse(rawFile);
|
return JSON.parse(rawFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const readFile = (path: string): string => fs.readFileSync(getAbsolutePath(path)).toString();
|
||||||
|
|
||||||
export const fileExists = (path: string): boolean => fs.existsSync(getAbsolutePath(path));
|
export const fileExists = (path: string): boolean => fs.existsSync(getAbsolutePath(path));
|
||||||
|
|
||||||
export const writeFile = (path: string, data: any) => fs.writeFileSync(getAbsolutePath(path), data);
|
export const writeFile = (path: string, data: any) => fs.writeFileSync(getAbsolutePath(path), data);
|
||||||
|
@ -18,4 +20,4 @@ export const deleteFolder = (path: string) => fs.rmSync(getAbsolutePath(path), {
|
||||||
|
|
||||||
export const copyFile = (source: string, destination: string) => fs.copyFileSync(getAbsolutePath(source), getAbsolutePath(destination));
|
export const copyFile = (source: string, destination: string) => fs.copyFileSync(getAbsolutePath(source), getAbsolutePath(destination));
|
||||||
|
|
||||||
export const runScript = (path: string, args: string[]) => childProcess.spawnSync(getAbsolutePath(path), args, {});
|
export const runScript = (path: string, args: string[], callback?: any) => childProcess.execFile(getAbsolutePath(path), args, {}, callback);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue