Docker Changes
- Build off of fedora
- Schedule builds every Sunday
- Build and push to Docker Hub
- Test in CI
- Build for arm64 and amd64
- Implement healthchecks
- Only 2 layers :D
- Base building can be moved to TN
- Introduce a docker-compose.yml
- Automatically check code with eslint GHA
- PR's are checked to ensure they run
- Gracefully handle SIGINT/SIGTERM
- Bump deps
- Add devcontainer
- Configure dependabot
This commit is contained in:
parent
60a168a55b
commit
4831239c9e
11 changed files with 495 additions and 167 deletions
12
.devcontainer/devcontainer.json
Normal file
12
.devcontainer/devcontainer.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "Ultraviolet-Devel",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "../docker/Dockerfile",
|
||||||
|
"target": "devel",
|
||||||
|
"context": "../"
|
||||||
|
},
|
||||||
|
"forwardPorts": [
|
||||||
|
8080
|
||||||
|
],
|
||||||
|
"workspaceFolder": "/app"
|
||||||
|
}
|
||||||
27
.github/dependabot.yml
vendored
Normal file
27
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#
|
||||||
|
# Copyright 2021 The Sigstore Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: npm
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
open-pull-requests-limit: 10
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
open-pull-requests-limit: 10
|
||||||
77
.github/workflows/docker-image.yml
vendored
77
.github/workflows/docker-image.yml
vendored
|
|
@ -1,45 +1,70 @@
|
||||||
name: Docker Image CI
|
name: Build and Push to Docker Hub
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
branches: [ main ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ["main"]
|
branches: [ main ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "30 12 * * 0" # Run once every Sunday
|
- cron: "30 12 * * 0" # Run once every Sunday
|
||||||
|
|
||||||
|
env:
|
||||||
|
REPO: ultraviolet-node
|
||||||
|
PLATFORMS: linux/amd64,linux/arm64
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
push_to_registry:
|
build_and_push_docker_images:
|
||||||
name: Push Docker image to Docker Hub
|
name: Push Docker image to Docker Hub
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Docker meta
|
|
||||||
id: meta
|
|
||||||
uses: docker/metadata-action@v4
|
|
||||||
with:
|
|
||||||
images: ${{ secrets.DOCKER_USERNAME }}/ultraviolet-node
|
|
||||||
tags: |
|
|
||||||
type=raw,value={{date 'YYYYMMDD'}}
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v2
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKERUSERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKERPASSWORD }}
|
||||||
|
|
||||||
- name: Build & push Docker image
|
- name: Build Test Image
|
||||||
uses: docker/build-push-action@v3
|
uses: redhat-actions/buildah-build@v2
|
||||||
with:
|
with:
|
||||||
context: .
|
image: ${{ env.REPO }}
|
||||||
platforms: linux/amd64,linux/arm64
|
tags: test
|
||||||
push: true
|
containerfiles: |
|
||||||
tags: ${{ secrets.DOCKER_USERNAME }}/ultraviolet-node:latest,${{ steps.meta.outputs.tags }}
|
./docker/Dockerfile
|
||||||
|
build-args: |
|
||||||
|
NPM_BUILD=npm ci --omit=dev --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
podman run --rm -d -p 8080:8080 localhost/${{ env.REPO }}:test
|
||||||
|
chmod +x ./docker/test.sh
|
||||||
|
./docker/test.sh -p 8080 -h 0.0.0.0 -t 15
|
||||||
|
|
||||||
|
- name: Install qemu
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y qemu-user-static
|
||||||
|
|
||||||
|
- name: Build Production Images
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
id: build-image
|
||||||
|
uses: redhat-actions/buildah-build@v2
|
||||||
|
with:
|
||||||
|
image: ${{ env.REPO }}
|
||||||
|
tags: latest ${{ github.sha }}
|
||||||
|
containerfiles: |
|
||||||
|
./docker/Dockerfile
|
||||||
|
platforms: ${{ env.PLATFORMS }}
|
||||||
|
build-args: |
|
||||||
|
NPM_BUILD=npm ci --omit=dev --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Push To Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: redhat-actions/push-to-registry@v2
|
||||||
|
with:
|
||||||
|
image: ${{ steps.build-image.outputs.image }}
|
||||||
|
tags: ${{ steps.build-image.outputs.tags }}
|
||||||
|
registry: docker.io/${{ secrets.DOCKERUSERNAME }}
|
||||||
|
|
|
||||||
51
.github/workflows/eslint.yml
vendored
Normal file
51
.github/workflows/eslint.yml
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
# This workflow uses actions that are not certified by GitHub.
|
||||||
|
# They are provided by a third-party and are governed by
|
||||||
|
# separate terms of service, privacy policy, and support
|
||||||
|
# documentation.
|
||||||
|
# ESLint is a tool for identifying and reporting on patterns
|
||||||
|
# found in ECMAScript/JavaScript code.
|
||||||
|
# More details at https://github.com/eslint/eslint
|
||||||
|
# and https://eslint.org
|
||||||
|
|
||||||
|
# https://github.com/actions/starter-workflows/blob/main/code-scanning/eslint.yml
|
||||||
|
|
||||||
|
name: ESLint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
pull_request:
|
||||||
|
branches: ["main"]
|
||||||
|
schedule:
|
||||||
|
- cron: "30 12 * * 0" # Run once every Sunday
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
eslint:
|
||||||
|
name: Run eslint scanning
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install ESLint
|
||||||
|
run: |
|
||||||
|
npm install eslint@8.10.0
|
||||||
|
npm install @microsoft/eslint-formatter-sarif@2.1.7
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: npx eslint .
|
||||||
|
--config .eslintrc.json
|
||||||
|
--ext .js,.jsx,.ts,.tsx
|
||||||
|
--format @microsoft/eslint-formatter-sarif
|
||||||
|
--output-file eslint-results.sarif
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Upload analysis results to GitHub
|
||||||
|
uses: github/codeql-action/upload-sarif@v2
|
||||||
|
with:
|
||||||
|
sarif_file: eslint-results.sarif
|
||||||
|
wait-for-processing: true
|
||||||
19
Dockerfile
19
Dockerfile
|
|
@ -1,19 +0,0 @@
|
||||||
# build app
|
|
||||||
FROM docker.io/node AS builder
|
|
||||||
|
|
||||||
RUN apt update
|
|
||||||
RUN apt install git
|
|
||||||
|
|
||||||
COPY . /app
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# build final
|
|
||||||
FROM gcr.io/distroless/nodejs:16
|
|
||||||
|
|
||||||
EXPOSE 8080/tcp
|
|
||||||
|
|
||||||
COPY --from=builder /app /
|
|
||||||
|
|
||||||
CMD ["src/index.js"]
|
|
||||||
9
docker-compose.yml
Normal file
9
docker-compose.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
services:
|
||||||
|
ultraviolet:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
args:
|
||||||
|
- NPM_BUILD=npm ci --omit=dev --frozen-lockfile
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
32
docker/Dockerfile
Normal file
32
docker/Dockerfile
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
FROM quay.io/np22-jpg/fedora-npm AS devel
|
||||||
|
ARG NPM_BUILD="npm install"
|
||||||
|
|
||||||
|
RUN mkdir /app
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN $NPM_BUILD
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
|
||||||
|
FROM quay.io/np22-jpg/fedora-node AS release
|
||||||
|
|
||||||
|
LABEL maintainer="TitaniumNetwork Ultraviolet Team"
|
||||||
|
LABEL summary="Ultraviolet Proxy Image"
|
||||||
|
LABEL description="Example application of Ultraviolet which can be deployed in production."
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
USER node
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=devel --chown=1000:1000 /app/node_modules node_modules
|
||||||
|
COPY --from=devel --chown=1000:1000 /app/src/index.js src/index.js
|
||||||
|
COPY --from=devel --chown=1000:1000 /app/package.json package.json
|
||||||
|
|
||||||
|
EXPOSE 8080/tcp
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=5s --timeout=3s --start-period=5s \
|
||||||
|
CMD /usr/bin/curl -f http://localhost:8080 || false
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/usr/bin/node" ]
|
||||||
|
CMD [ "src/index.js" ]
|
||||||
185
docker/test.sh
Executable file
185
docker/test.sh
Executable file
|
|
@ -0,0 +1,185 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh
|
||||||
|
# Use this script to test if a given TCP host/port are available
|
||||||
|
|
||||||
|
WAITFORIT_cmdname=${0##*/}
|
||||||
|
|
||||||
|
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
cat << USAGE >&2
|
||||||
|
Usage:
|
||||||
|
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
|
||||||
|
-h HOST | --host=HOST Host or IP under test
|
||||||
|
-p PORT | --port=PORT TCP port under test
|
||||||
|
Alternatively, you specify the host and port as host:port
|
||||||
|
-s | --strict Only execute subcommand if the test succeeds
|
||||||
|
-q | --quiet Don't output any status messages
|
||||||
|
-t TIMEOUT | --timeout=TIMEOUT
|
||||||
|
Timeout in seconds, zero for no timeout
|
||||||
|
-- COMMAND ARGS Execute command with args after the test finishes
|
||||||
|
USAGE
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for()
|
||||||
|
{
|
||||||
|
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||||
|
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||||
|
else
|
||||||
|
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
|
||||||
|
fi
|
||||||
|
WAITFORIT_start_ts=$(date +%s)
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
|
||||||
|
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
|
||||||
|
WAITFORIT_result=$?
|
||||||
|
else
|
||||||
|
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
|
||||||
|
WAITFORIT_result=$?
|
||||||
|
fi
|
||||||
|
if [[ $WAITFORIT_result -eq 0 ]]; then
|
||||||
|
WAITFORIT_end_ts=$(date +%s)
|
||||||
|
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
return $WAITFORIT_result
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_wrapper()
|
||||||
|
{
|
||||||
|
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
|
||||||
|
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
|
||||||
|
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||||
|
else
|
||||||
|
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||||
|
fi
|
||||||
|
WAITFORIT_PID=$!
|
||||||
|
trap "kill -INT -$WAITFORIT_PID" INT
|
||||||
|
wait $WAITFORIT_PID
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
|
||||||
|
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||||
|
fi
|
||||||
|
return $WAITFORIT_RESULT
|
||||||
|
}
|
||||||
|
|
||||||
|
# process arguments
|
||||||
|
while [[ $# -gt 0 ]]
|
||||||
|
do
|
||||||
|
case "$1" in
|
||||||
|
*:* )
|
||||||
|
WAITFORIT_hostport=(${1//:/ })
|
||||||
|
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
|
||||||
|
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--child)
|
||||||
|
WAITFORIT_CHILD=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-q | --quiet)
|
||||||
|
WAITFORIT_QUIET=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-s | --strict)
|
||||||
|
WAITFORIT_STRICT=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-h)
|
||||||
|
WAITFORIT_HOST="$2"
|
||||||
|
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--host=*)
|
||||||
|
WAITFORIT_HOST="${1#*=}"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-p)
|
||||||
|
WAITFORIT_PORT="$2"
|
||||||
|
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--port=*)
|
||||||
|
WAITFORIT_PORT="${1#*=}"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-t)
|
||||||
|
WAITFORIT_TIMEOUT="$2"
|
||||||
|
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--timeout=*)
|
||||||
|
WAITFORIT_TIMEOUT="${1#*=}"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
WAITFORIT_CLI=("$@")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echoerr "Unknown argument: $1"
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
|
||||||
|
echoerr "Error: you need to provide a host and port to test."
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
|
||||||
|
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
|
||||||
|
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
|
||||||
|
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
|
||||||
|
|
||||||
|
# Check to see if timeout is from busybox?
|
||||||
|
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
|
||||||
|
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
|
||||||
|
|
||||||
|
WAITFORIT_BUSYTIMEFLAG=""
|
||||||
|
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
|
||||||
|
WAITFORIT_ISBUSY=1
|
||||||
|
# Check if busybox timeout uses -t flag
|
||||||
|
# (recent Alpine versions don't support -t anymore)
|
||||||
|
if timeout &>/dev/stdout | grep -q -e '-t '; then
|
||||||
|
WAITFORIT_BUSYTIMEFLAG="-t"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
WAITFORIT_ISBUSY=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
|
||||||
|
wait_for
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
exit $WAITFORIT_RESULT
|
||||||
|
else
|
||||||
|
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||||
|
wait_for_wrapper
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
else
|
||||||
|
wait_for
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $WAITFORIT_CLI != "" ]]; then
|
||||||
|
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
|
||||||
|
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
|
||||||
|
exit $WAITFORIT_RESULT
|
||||||
|
fi
|
||||||
|
exec "${WAITFORIT_CLI[@]}"
|
||||||
|
else
|
||||||
|
exit $WAITFORIT_RESULT
|
||||||
|
fi
|
||||||
232
package-lock.json
generated
232
package-lock.json
generated
|
|
@ -9,29 +9,53 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@titaniumnetwork-dev/ultraviolet": "^1.0.8-beta",
|
"@titaniumnetwork-dev/ultraviolet": "^1.0.10",
|
||||||
"@tomphttp/bare-server-node": "^1.2.5",
|
"@tomphttp/bare-server-node": "^1.2.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"ultraviolet-static": "github:titaniumnetwork-dev/Ultraviolet-Static"
|
"ultraviolet-static": "github:titaniumnetwork-dev/Ultraviolet-Static"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^8.32.0",
|
"eslint": "^8.36.0",
|
||||||
"prettier": "^2.8.3"
|
"prettier": "^2.8.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0",
|
"node": ">=16.0.0",
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint-community/regexpp": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/eslintrc": {
|
||||||
"version": "1.4.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz",
|
||||||
"integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
|
"integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.4.0",
|
"espree": "^9.5.0",
|
||||||
"globals": "^13.19.0",
|
"globals": "^13.19.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
|
|
@ -69,6 +93,15 @@
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint/js": {
|
||||||
|
"version": "8.36.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz",
|
||||||
|
"integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.8",
|
"version": "0.11.8",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||||
|
|
@ -161,9 +194,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@titaniumnetwork-dev/ultraviolet": {
|
"node_modules/@titaniumnetwork-dev/ultraviolet": {
|
||||||
"version": "1.0.8-beta",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@titaniumnetwork-dev/ultraviolet/-/ultraviolet-1.0.8-beta.tgz",
|
"resolved": "https://registry.npmjs.org/@titaniumnetwork-dev/ultraviolet/-/ultraviolet-1.0.10.tgz",
|
||||||
"integrity": "sha512-X72N++Zqnr+yP9PniN0Lz9BKhcAZgZ6w5L48Df/enHv5aoysPJ99sza1spwxxRTeBiaRHeBApmWRAWz37H2UiQ==",
|
"integrity": "sha512-y5Hv92jQUvwmcEMIeFuImuD5CmI7b0MQGL7qkFcEZxETxlwy+jveLaHpF1UWgtGJS50GSnj9GCJWZWp/W6IwEQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tomphttp/bare-client": "^1.1.2-beta.3",
|
"@tomphttp/bare-client": "^1.1.2-beta.3",
|
||||||
"css-tree": "^2.0.4",
|
"css-tree": "^2.0.4",
|
||||||
|
|
@ -578,12 +611,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.32.0",
|
"version": "8.36.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz",
|
||||||
"integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==",
|
"integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/eslintrc": "^1.4.1",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
|
"@eslint-community/regexpp": "^4.4.0",
|
||||||
|
"@eslint/eslintrc": "^2.0.1",
|
||||||
|
"@eslint/js": "8.36.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.8",
|
"@humanwhocodes/config-array": "^0.11.8",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
|
|
@ -594,10 +630,9 @@
|
||||||
"doctrine": "^3.0.0",
|
"doctrine": "^3.0.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.1.1",
|
"eslint-scope": "^7.1.1",
|
||||||
"eslint-utils": "^3.0.0",
|
|
||||||
"eslint-visitor-keys": "^3.3.0",
|
"eslint-visitor-keys": "^3.3.0",
|
||||||
"espree": "^9.4.0",
|
"espree": "^9.5.0",
|
||||||
"esquery": "^1.4.0",
|
"esquery": "^1.4.2",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"file-entry-cache": "^6.0.1",
|
"file-entry-cache": "^6.0.1",
|
||||||
|
|
@ -618,7 +653,6 @@
|
||||||
"minimatch": "^3.1.2",
|
"minimatch": "^3.1.2",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"optionator": "^0.9.1",
|
"optionator": "^0.9.1",
|
||||||
"regexpp": "^3.2.0",
|
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
"strip-json-comments": "^3.1.0",
|
"strip-json-comments": "^3.1.0",
|
||||||
"text-table": "^0.2.0"
|
"text-table": "^0.2.0"
|
||||||
|
|
@ -646,33 +680,6 @@
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-utils": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"eslint-visitor-keys": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/mysticatea"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"eslint": ">=5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-visitor-keys": {
|
"node_modules/eslint-visitor-keys": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
|
||||||
|
|
@ -714,9 +721,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/espree": {
|
"node_modules/espree": {
|
||||||
"version": "9.4.1",
|
"version": "9.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz",
|
||||||
"integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
|
"integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.8.0",
|
"acorn": "^8.8.0",
|
||||||
|
|
@ -731,9 +738,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/esquery": {
|
"node_modules/esquery": {
|
||||||
"version": "1.4.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
|
||||||
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"estraverse": "^5.1.0"
|
"estraverse": "^5.1.0"
|
||||||
|
|
@ -993,9 +1000,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "13.19.0",
|
"version": "13.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
|
||||||
"integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
|
"integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"type-fest": "^0.20.2"
|
"type-fest": "^0.20.2"
|
||||||
|
|
@ -1480,9 +1487,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "2.8.3",
|
"version": "2.8.4",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
|
||||||
"integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
|
"integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin-prettier.js"
|
"prettier": "bin-prettier.js"
|
||||||
|
|
@ -1571,18 +1578,6 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regexpp": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/mysticatea"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/resolve-from": {
|
"node_modules/resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
|
|
@ -1953,15 +1948,30 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@eslint-community/eslint-utils": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@eslint-community/regexpp": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@eslint/eslintrc": {
|
"@eslint/eslintrc": {
|
||||||
"version": "1.4.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz",
|
||||||
"integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
|
"integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.4.0",
|
"espree": "^9.5.0",
|
||||||
"globals": "^13.19.0",
|
"globals": "^13.19.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
|
|
@ -1987,6 +1997,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@eslint/js": {
|
||||||
|
"version": "8.36.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz",
|
||||||
|
"integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.11.8",
|
"version": "0.11.8",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||||
|
|
@ -2054,9 +2070,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@titaniumnetwork-dev/ultraviolet": {
|
"@titaniumnetwork-dev/ultraviolet": {
|
||||||
"version": "1.0.8-beta",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@titaniumnetwork-dev/ultraviolet/-/ultraviolet-1.0.8-beta.tgz",
|
"resolved": "https://registry.npmjs.org/@titaniumnetwork-dev/ultraviolet/-/ultraviolet-1.0.10.tgz",
|
||||||
"integrity": "sha512-X72N++Zqnr+yP9PniN0Lz9BKhcAZgZ6w5L48Df/enHv5aoysPJ99sza1spwxxRTeBiaRHeBApmWRAWz37H2UiQ==",
|
"integrity": "sha512-y5Hv92jQUvwmcEMIeFuImuD5CmI7b0MQGL7qkFcEZxETxlwy+jveLaHpF1UWgtGJS50GSnj9GCJWZWp/W6IwEQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@tomphttp/bare-client": "^1.1.2-beta.3",
|
"@tomphttp/bare-client": "^1.1.2-beta.3",
|
||||||
"css-tree": "^2.0.4",
|
"css-tree": "^2.0.4",
|
||||||
|
|
@ -2369,12 +2385,15 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"eslint": {
|
"eslint": {
|
||||||
"version": "8.32.0",
|
"version": "8.36.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz",
|
||||||
"integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==",
|
"integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@eslint/eslintrc": "^1.4.1",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
|
"@eslint-community/regexpp": "^4.4.0",
|
||||||
|
"@eslint/eslintrc": "^2.0.1",
|
||||||
|
"@eslint/js": "8.36.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.8",
|
"@humanwhocodes/config-array": "^0.11.8",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
|
|
@ -2385,10 +2404,9 @@
|
||||||
"doctrine": "^3.0.0",
|
"doctrine": "^3.0.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.1.1",
|
"eslint-scope": "^7.1.1",
|
||||||
"eslint-utils": "^3.0.0",
|
|
||||||
"eslint-visitor-keys": "^3.3.0",
|
"eslint-visitor-keys": "^3.3.0",
|
||||||
"espree": "^9.4.0",
|
"espree": "^9.5.0",
|
||||||
"esquery": "^1.4.0",
|
"esquery": "^1.4.2",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"file-entry-cache": "^6.0.1",
|
"file-entry-cache": "^6.0.1",
|
||||||
|
|
@ -2409,7 +2427,6 @@
|
||||||
"minimatch": "^3.1.2",
|
"minimatch": "^3.1.2",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"optionator": "^0.9.1",
|
"optionator": "^0.9.1",
|
||||||
"regexpp": "^3.2.0",
|
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
"strip-json-comments": "^3.1.0",
|
"strip-json-comments": "^3.1.0",
|
||||||
"text-table": "^0.2.0"
|
"text-table": "^0.2.0"
|
||||||
|
|
@ -2442,23 +2459,6 @@
|
||||||
"estraverse": "^5.2.0"
|
"estraverse": "^5.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-utils": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"eslint-visitor-keys": "^2.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"eslint-visitor-keys": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"eslint-visitor-keys": {
|
"eslint-visitor-keys": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
|
||||||
|
|
@ -2474,9 +2474,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"espree": {
|
"espree": {
|
||||||
"version": "9.4.1",
|
"version": "9.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz",
|
||||||
"integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
|
"integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"acorn": "^8.8.0",
|
"acorn": "^8.8.0",
|
||||||
|
|
@ -2485,9 +2485,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esquery": {
|
"esquery": {
|
||||||
"version": "1.4.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
|
||||||
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"estraverse": "^5.1.0"
|
"estraverse": "^5.1.0"
|
||||||
|
|
@ -2693,9 +2693,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"version": "13.19.0",
|
"version": "13.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
|
||||||
"integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
|
"integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"type-fest": "^0.20.2"
|
"type-fest": "^0.20.2"
|
||||||
|
|
@ -3051,9 +3051,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"version": "2.8.3",
|
"version": "2.8.4",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
|
||||||
"integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
|
"integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"proxy-addr": {
|
"proxy-addr": {
|
||||||
|
|
@ -3101,12 +3101,6 @@
|
||||||
"unpipe": "1.0.0"
|
"unpipe": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regexpp": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"resolve-from": {
|
"resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@titaniumnetwork-dev/ultraviolet": "^1.0.8-beta",
|
"@titaniumnetwork-dev/ultraviolet": "^1.0.10",
|
||||||
"@tomphttp/bare-server-node": "^1.2.5",
|
"@tomphttp/bare-server-node": "^1.2.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"ultraviolet-static": "github:titaniumnetwork-dev/Ultraviolet-Static"
|
"ultraviolet-static": "github:titaniumnetwork-dev/Ultraviolet-Static"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^8.32.0",
|
"eslint": "^8.36.0",
|
||||||
"prettier": "^2.8.3"
|
"prettier": "^2.8.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/index.js
12
src/index.js
|
|
@ -58,6 +58,18 @@ server.on("listening", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// https://expressjs.com/en/advanced/healthcheck-graceful-shutdown.html
|
||||||
|
process.on("SIGINT", shutdown)
|
||||||
|
process.on("SIGTERM", shutdown)
|
||||||
|
|
||||||
|
function shutdown() {
|
||||||
|
console.log('SIGTERM signal received: closing HTTP server')
|
||||||
|
server.close(() => {
|
||||||
|
console.log('Server closed.');
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
server.listen({
|
server.listen({
|
||||||
port,
|
port,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue