mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
Basic repo files added
This commit is contained in:
commit
f238061af7
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
/out
|
||||
/node_modules
|
||||
*.log
|
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{yml, yaml, sh, conf}]
|
||||
indent_size = 2
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
87
.github/workflows/release.yml
vendored
Normal file
87
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
name: release
|
||||
|
||||
on:
|
||||
release: # Docs: <https://git.io/JeBz1#release-event-release>
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
demo:
|
||||
name: Update demonstration, hosted on github pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v1 # Action page: <https://github.com/actions/setup-node>
|
||||
with:
|
||||
node-version: 12
|
||||
|
||||
- name: Generate version value
|
||||
run: echo "::set-env name=PACKAGE_VERSION::${GITHUB_REF##*/v}"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: ./bin/generator.js -c ./configuration.json -o ./out
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: content
|
||||
path: out/
|
||||
|
||||
- name: Switch to github pages branch
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: gh-pages
|
||||
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: content
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
git config --global user.name "$GITHUB_ACTOR"
|
||||
git config --global user.email 'actions@github.com'
|
||||
git remote add github "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git"
|
||||
|
||||
- name: Stage changes
|
||||
run: git add .
|
||||
|
||||
- name: Commit changes
|
||||
run: git commit -m "Deploying ${GITHUB_SHA} to Github Pages"
|
||||
|
||||
- name: Push changes
|
||||
run: git push github --force
|
||||
|
||||
docker-image:
|
||||
name: Build docker image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Generate version value
|
||||
run: echo "::set-env name=APP_VERSION::${GITHUB_REF##*/}@`echo ${GITHUB_SHA} | cut -c1-8`"
|
||||
|
||||
- name: Generate image tag value
|
||||
run: echo "::set-env name=IMAGE_TAG::${GITHUB_REF##*/[vV]}" # `/refs/tags/v1.2.3` -> `1.2.3`
|
||||
|
||||
- name: Make docker login
|
||||
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_LOGIN }}" --password-stdin &> /dev/null
|
||||
|
||||
- name: Build image
|
||||
run: docker build --build-arg "APP_VERSION=${APP_VERSION}" --tag "tarampampam/tinifier:${IMAGE_TAG}" --tag "tarampampam/tinifier:latest" -f ./Dockerfile .
|
||||
|
||||
- name: Push version image
|
||||
run: docker push "tarampampam/tinifier:${IMAGE_TAG}"
|
||||
|
||||
- name: Push latest image
|
||||
run: docker push "tarampampam/tinifier:latest"
|
46
.github/workflows/tests.yml
vendored
Normal file
46
.github/workflows/tests.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- '**'
|
||||
pull_request:
|
||||
|
||||
jobs: # Docs: <https://git.io/JvxXE>
|
||||
generate:
|
||||
name: Try to run generator
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v1 # Action page: <https://github.com/actions/setup-node>
|
||||
with:
|
||||
node-version: 12
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
|
||||
- name: Run generator
|
||||
run: ./bin/generator.js -c ./configuration.json -o ./out
|
||||
|
||||
- name: Test file creation
|
||||
run: test -f ./out/ghost/404.html
|
||||
|
||||
docker-build:
|
||||
name: Try to run generator
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build docker image
|
||||
run: docker build -f ./Dockerfile .
|
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
## IDEs
|
||||
/.vscode
|
||||
/.idea
|
||||
|
||||
## Vendors
|
||||
/node_modules
|
||||
|
||||
## Lock files (use yarn only)
|
||||
/package-lock.json
|
||||
|
||||
## Dist
|
||||
/out
|
||||
|
||||
## Temp dirs & trash
|
||||
/npm-debug.log
|
||||
/yarn-error.log
|
||||
.DS_Store
|
||||
.env*
|
14
CHANGELOG.md
Normal file
14
CHANGELOG.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this package will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
|
||||
|
||||
## v1.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- WIP
|
||||
|
||||
[keepachangelog]:https://keepachangelog.com/en/1.0.0/
|
||||
[semver]:https://semver.org/spec/v2.0.0.html
|
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@ -0,0 +1,22 @@
|
||||
# Image page: <https://hub.docker.com/_/node>
|
||||
FROM node:12.16.2-alpine as builder
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN set -x \
|
||||
&& yarn install --frozen-lockfile \
|
||||
&& ./bin/generator.js -c ./configuration.json -o ./out
|
||||
|
||||
# Image page: <https://hub.docker.com/_/nginx>
|
||||
FROM nginx:1.18-alpine
|
||||
|
||||
COPY --from=builder --chown=nginx /src/docker/docker-entrypoint.sh /docker-entrypoint.sh
|
||||
COPY --from=builder --chown=nginx /src/docker/nginx-server.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=builder --chown=nginx /src/static /opt/html
|
||||
COPY --from=builder --chown=nginx /src/out /opt/html
|
||||
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) <https://github.com/tarampampam>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
21
Makefile
Normal file
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/make
|
||||
# Makefile readme (ru): <http://linux.yaroslavl.ru/docs/prog/gnu_make_3-79_russian_manual.html>
|
||||
# Makefile readme (en): <https://www.gnu.org/software/make/manual/html_node/index.html#SEC_Contents>
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
DOCKER_BIN = $(shell command -v docker 2> /dev/null)
|
||||
APP_NAME = $(notdir $(CURDIR))
|
||||
|
||||
.DEFAULT_GOAL : help
|
||||
|
||||
help: ## Show this help
|
||||
@printf "\033[33m%s:\033[0m\n" 'Available commands'
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[32m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
|
||||
image: ## Build docker image
|
||||
$(DOCKER_BIN) build -f ./Dockerfile -t $(APP_NAME):local .
|
||||
@printf "\n \e[30;42m %s \033[0m\n\n" 'Now you can use image like `docker run --rm -p 8080:8080 $(APP_NAME):local ...`'
|
||||
|
||||
shell: ## Start shell into container with node
|
||||
$(DOCKER_BIN) run --rm -ti -v "$(shell pwd):/src:rw" -w "/src" --user "$(shell id -u):$(shell id -g)" node:12.16.2-alpine sh
|
93
README.md
Normal file
93
README.md
Normal file
@ -0,0 +1,93 @@
|
||||
<p align="center">
|
||||
<img src="https://hsto.org/webt/rg/ys/c3/rgysc33oc7jiufdzmwrkohpmef8.png" width="94" alt="" />
|
||||
</p>
|
||||
|
||||
# Static error pages in a Docker container
|
||||
|
||||
[![Build Status][badge_build_status]][link_build_status]
|
||||
[![License][badge_license]][link_license]
|
||||
|
||||
This repository contains a very simple generator for server error pages _(like `404: Not found`)_ and ready docker image with web server for error pages serving.
|
||||
|
||||
Generator ([`bin/generator.js`](./bin/generator.js)) allows you:
|
||||
|
||||
- Use different templates (section `templates` in configuration file)
|
||||
- Generate pages with arbitrary content according to a specific template
|
||||
|
||||
Can be used for [Traefik error pages customization](https://docs.traefik.io/middlewares/errorpages/).
|
||||
|
||||
### Usage
|
||||
|
||||
Just execute (installed `nodejs` is required):
|
||||
|
||||
```bash
|
||||
$ bin/generator.js -c ./configuration.json -o ./out
|
||||
```
|
||||
|
||||
And watch into `./out` directory:
|
||||
|
||||
```text
|
||||
./out
|
||||
└── ghost
|
||||
├── 400.html
|
||||
├── 401.html
|
||||
├── 403.html
|
||||
├── 404.html
|
||||
├── ...
|
||||
└── 505.html
|
||||
```
|
||||
|
||||
Default configuration can be found in [`configuration.json`](./configuration.json) file.
|
||||
|
||||
### Docker
|
||||
|
||||
Start image (`nginx` inside):
|
||||
|
||||
```bash
|
||||
$ docker run --rm -p "8080:8080" tarampampam/error-pages:1.0.0
|
||||
```
|
||||
|
||||
And open in your browser `http://127.0.0.1:8080/ghost/400.html`. Additionally, you can set "default" pages theme by passing `TEMPLATE_NAME` environment variable (eg.: `-e "TEMPLATE_NAME=ghost"`) - in this case all error pages will be accessible in root directory (eg.: `http://127.0.0.1:8080/400.html`).
|
||||
|
||||
Also you can use generated error pages in your own docker images:
|
||||
|
||||
```dockerfile
|
||||
FROM nginx:1.18-alpine
|
||||
|
||||
COPY --from=tarampampam/error-pages:1.0.0 /opt/html/ghost /usr/share/nginx/html/error-pages
|
||||
```
|
||||
|
||||
> [`error_page` for `nginx` configuration](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page)
|
||||
|
||||
## Changes log
|
||||
|
||||
[![Release date][badge_release_date]][link_releases]
|
||||
[![Commits since latest release][badge_commits_since_release]][link_commits]
|
||||
|
||||
Changes log can be [found here][link_changes_log].
|
||||
|
||||
## Support
|
||||
|
||||
[![Issues][badge_issues]][link_issues]
|
||||
[![Issues][badge_pulls]][link_pulls]
|
||||
|
||||
If you will find any package errors, please, [make an issue][link_create_issue] in current repository.
|
||||
|
||||
## License
|
||||
|
||||
This is open-sourced software licensed under the [MIT License][link_license].
|
||||
|
||||
[badge_build_status]:https://img.shields.io/github/workflow/status/tarampampam/error-pages-docker/tests/master
|
||||
[badge_release_date]:https://img.shields.io/github/release-date/tarampampam/error-pages-docker.svg?style=flat-square&maxAge=180
|
||||
[badge_commits_since_release]:https://img.shields.io/github/commits-since/tarampampam/error-pages-docker/latest.svg?style=flat-square&maxAge=180
|
||||
[badge_issues]:https://img.shields.io/github/issues/tarampampam/error-pages-docker.svg?style=flat-square&maxAge=180
|
||||
[badge_pulls]:https://img.shields.io/github/issues-pr/tarampampam/error-pages-docker.svg?style=flat-square&maxAge=180
|
||||
[badge_license]:https://img.shields.io/github/license/tarampampam/error-pages-docker.svg?longCache=true
|
||||
[link_releases]:https://github.com/tarampampam/error-pages-docker/releases
|
||||
[link_commits]:https://github.com/tarampampam/error-pages-docker/commits
|
||||
[link_changes_log]:https://github.com/tarampampam/error-pages-docker/blob/master/CHANGELOG.md
|
||||
[link_issues]:https://github.com/tarampampam/error-pages-docker/issues
|
||||
[link_pulls]:https://github.com/tarampampam/error-pages-docker/pulls
|
||||
[link_build_status]:https://travis-ci.org/tarampampam/error-pages-docker
|
||||
[link_create_issue]:https://github.com/tarampampam/error-pages-docker/issues/new
|
||||
[link_license]:https://github.com/tarampampam/error-pages-docker/blob/master/LICENSE
|
69
bin/generator.js
Executable file
69
bin/generator.js
Executable file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const yargs = require('yargs');
|
||||
|
||||
const options = yargs
|
||||
.usage('Usage: -c <config.json> -d <output-directory>')
|
||||
.option("c", {alias: "config", describe: "config file path", type: "string", demandOption: true})
|
||||
.option("o", {alias: "out", describe: "output directory path", type: "string", demandOption: true})
|
||||
.argv;
|
||||
|
||||
const configFile = options.config;
|
||||
const outDir = options.out;
|
||||
|
||||
try {
|
||||
// Make sure that config file exists
|
||||
if (! fs.existsSync(configFile)) {
|
||||
throw new Error(`Config file "${configFile}" was not found`);
|
||||
}
|
||||
|
||||
// Create output directory (if needed)
|
||||
if (!fs.existsSync(outDir)){
|
||||
fs.mkdirSync(outDir);
|
||||
}
|
||||
|
||||
// Read JSON config file and parse into object
|
||||
const configContent = JSON.parse(fs.readFileSync(configFile));
|
||||
|
||||
// Loop over all defined templates in configuration file
|
||||
configContent.templates.forEach((templateConfig) => {
|
||||
// Make sure that template layout file exists
|
||||
if (! fs.existsSync(templateConfig.path)) {
|
||||
throw new Error(`Template "${templateConfig.name}" was not found in "${templateConfig.path}"`);
|
||||
}
|
||||
|
||||
// Read layout content into memory prepare output directory for template
|
||||
const layoutContent = String(fs.readFileSync(templateConfig.path));
|
||||
const templateOutDir = path.join(outDir, templateConfig.name);
|
||||
|
||||
if (!fs.existsSync(templateOutDir)){
|
||||
fs.mkdirSync(templateOutDir);
|
||||
}
|
||||
|
||||
console.info(`Use template "${templateConfig.name}" located in "${templateConfig.path}"`);
|
||||
|
||||
// Loop over all pages
|
||||
configContent.pages.forEach((pageConfig) => {
|
||||
console.info(`Page with code ${pageConfig.code} generation...`);
|
||||
|
||||
// Make replaces
|
||||
let result = layoutContent
|
||||
.replace(/{{\s?code\s?}}/g, pageConfig.code)
|
||||
.replace(/{{\s?message\s?}}/g, pageConfig.message)
|
||||
.replace(/{{\s?description\s?}}/g, pageConfig.description);
|
||||
|
||||
// And write into result file
|
||||
fs.writeFileSync(path.join(templateOutDir, `${pageConfig.code}.${configContent.output.file_extension}`), result, {
|
||||
encoding: "utf8",
|
||||
flag: "w+",
|
||||
mode: 0o644
|
||||
})
|
||||
});
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
process.exit(1);
|
||||
}
|
108
configuration.json
Normal file
108
configuration.json
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"templates": [
|
||||
{
|
||||
"name": "ghost",
|
||||
"path": "./templates/ghost.html"
|
||||
}
|
||||
],
|
||||
"output": {
|
||||
"file_extension": "html"
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"code": 400,
|
||||
"message": "Bad Request",
|
||||
"description": "The server did not understand the request"
|
||||
},
|
||||
{
|
||||
"code": 401,
|
||||
"message": "Unauthorized",
|
||||
"description": "The requested page needs a username and a password"
|
||||
},
|
||||
{
|
||||
"code": 403,
|
||||
"message": "Forbidden",
|
||||
"description": "Access is forbidden to the requested page"
|
||||
},
|
||||
{
|
||||
"code": 404,
|
||||
"message": "Not Found",
|
||||
"description": "The server can not find the requested page"
|
||||
},
|
||||
{
|
||||
"code": 405,
|
||||
"message": "Method Not Allowed",
|
||||
"description": "The method specified in the request is not allowed"
|
||||
},
|
||||
{
|
||||
"code": 407,
|
||||
"message": "Proxy Authentication Required",
|
||||
"description": "You must authenticate with a proxy server before this request can be served"
|
||||
},
|
||||
{
|
||||
"code": 408,
|
||||
"message": "Request Timeout",
|
||||
"description": "The request took longer than the server was prepared to wait"
|
||||
},
|
||||
{
|
||||
"code": 409,
|
||||
"message": "Conflict",
|
||||
"description": "The request could not be completed because of a conflict"
|
||||
},
|
||||
{
|
||||
"code": 410,
|
||||
"message": "Gone",
|
||||
"description": "The requested page is no longer available"
|
||||
},
|
||||
{
|
||||
"code": 411,
|
||||
"message": "Length Required",
|
||||
"description": "The \"Content-Length\" is not defined. The server will not accept the request without it"
|
||||
},
|
||||
{
|
||||
"code": 412,
|
||||
"message": "Precondition Failed",
|
||||
"description": "The pre condition given in the request evaluated to false by the server"
|
||||
},
|
||||
{
|
||||
"code": 413,
|
||||
"message": "Payload Too Large",
|
||||
"description": "The server will not accept the request, because the request entity is too large"
|
||||
},
|
||||
{
|
||||
"code": 416,
|
||||
"message": "Requested Range Not Satisfiable",
|
||||
"description": "The requested byte range is not available and is out of bounds"
|
||||
},
|
||||
{
|
||||
"code": 429,
|
||||
"message": "Too Many Requests",
|
||||
"description": "Too many requests in a given amount of time"
|
||||
},
|
||||
{
|
||||
"code": 500,
|
||||
"message": "Internal Server Error",
|
||||
"description": "The server met an unexpected condition"
|
||||
},
|
||||
{
|
||||
"code": 502,
|
||||
"message": "Bad Gateway",
|
||||
"description": "The server received an invalid response from the upstream server"
|
||||
},
|
||||
{
|
||||
"code": 503,
|
||||
"message": "Service Unavailable",
|
||||
"description": "The server is temporarily overloading or down"
|
||||
},
|
||||
{
|
||||
"code": 504,
|
||||
"message": "Gateway Timeout",
|
||||
"description": "The gateway has timed out"
|
||||
},
|
||||
{
|
||||
"code": 505,
|
||||
"message": "HTTP Version Not Supported",
|
||||
"description": "The server does not support the \"http protocol\" version"
|
||||
}
|
||||
]
|
||||
}
|
16
docker/docker-entrypoint.sh
Executable file
16
docker/docker-entrypoint.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
TEMPLATE_NAME=${TEMPLATE_NAME:-} # string|empty
|
||||
|
||||
if [ -n "$TEMPLATE_NAME" ]; then
|
||||
echo "$0: set pages for template '$TEMPLATE_NAME' as default (make accessible in root directory)";
|
||||
|
||||
if [ ! -d "/opt/html/$TEMPLATE_NAME" ]; then
|
||||
(>&2 echo "$0: template '$TEMPLATE_NAME' was not found!"); exit 1;
|
||||
fi;
|
||||
|
||||
ln -f -s "/opt/html/$TEMPLATE_NAME/"* /opt/html;
|
||||
fi;
|
||||
|
||||
exec "$@"
|
9
docker/nginx-server.conf
Normal file
9
docker/nginx-server.conf
Normal file
@ -0,0 +1,9 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
root /opt/html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
}
|
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "error-pages",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/tarampampam/error-pages-docker.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"yargs": "15.3"
|
||||
}
|
||||
}
|
0
static/favicon.ico
Normal file
0
static/favicon.ico
Normal file
22
static/index.html
Normal file
22
static/index.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<title>Error pages</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css" />
|
||||
<style type="text/css">
|
||||
html,body {background-color:#fff;font-family:'Montserrat',sans-serif;color:#1a1a1a;overflow:hidden}
|
||||
.wrap {top:50%;left:50%;width:350px;height:260px;margin-left:-175px;margin-top:-130px;position:absolute;text-align:center}
|
||||
.wrap h1 {font-size: 3em; margin-top: 0}
|
||||
.wrap p {font-size: 0.85em}
|
||||
.wrap p.small {font-size: 0.6em}
|
||||
</style>
|
||||
</head><body>
|
||||
<div class="wrap">
|
||||
<h1>Error pages</h1>
|
||||
<p class="small">
|
||||
For online documentation and support please refer to <a href="https://github.com/tarampampam/error-pages-docker">project repository</a>.
|
||||
</p>
|
||||
</div>
|
||||
</body></html>
|
2
static/robots.txt
Normal file
2
static/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /
|
42
templates/ghost.html
Normal file
42
templates/ghost.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<title>{{ code }}: {{ message }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" />
|
||||
<style>
|
||||
html,body {background-color:#1a1a1a;color:#fff;font-family:'Open Sans',sans-serif}
|
||||
.wrap {top:50%;left:50%;width:310px;height:260px;margin-left:-155px;margin-top:-110px;position:absolute;text-align:center}
|
||||
.ghost {animation:float 3s ease-out infinite}
|
||||
@keyframes float { 50% {transform:translate(0,20px)}}
|
||||
.shadowFrame {width:130px;margin: 10px auto 0 auto}
|
||||
.shadow {animation:shrink 3s ease-out infinite;transform-origin:center center}
|
||||
@keyframes shrink {0%{width:90%;margin:0 5%} 50% {width:60%;margin:0 18%} 100% {width:90%;margin:0 5%}}
|
||||
h3 {font-size:1.05em;text-transform: uppercase;margin:0.3em auto}
|
||||
.description {font-size:0.8em;color:#aaa}
|
||||
</style>
|
||||
</head><body>
|
||||
<div class="wrap">
|
||||
<svg class="ghost" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="127.433px" height="132.743px" viewBox="0 0 127.433 132.743" enable-background="new 0 0 127.433 132.743" xml:space="preserve">
|
||||
<path fill="#FFF6F4" d="M116.223,125.064c1.032-1.183,1.323-2.73,1.391-3.747V54.76c0,0-4.625-34.875-36.125-44.375 s-66,6.625-72.125,44l-0.781,63.219c0.062,4.197,1.105,6.177,1.808,7.006c1.94,1.811,5.408,3.465,10.099-0.6 c7.5-6.5,8.375-10,12.75-6.875s5.875,9.75,13.625,9.25s12.75-9,13.75-9.625s4.375-1.875,7,1.25s5.375,8.25,12.875,7.875 s12.625-8.375,12.625-8.375s2.25-3.875,7.25,0.375s7.625,9.75,14.375,8.125C114.739,126.01,115.412,125.902,116.223,125.064z"></path>
|
||||
<circle fill="#1a1a1a" cx="86.238" cy="57.885" r="6.667"></circle>
|
||||
<circle fill="#1a1a1a" cx="40.072" cy="57.885" r="6.667"></circle>
|
||||
<path fill="#1a1a1a" d="M71.916,62.782c0.05-1.108-0.809-2.046-1.917-2.095c-0.673-0.03-1.28,0.279-1.667,0.771 c-0.758,0.766-2.483,2.235-4.696,2.358c-1.696,0.094-3.438-0.625-5.191-2.137c-0.003-0.003-0.007-0.006-0.011-0.009l0.002,0.005 c-0.332-0.294-0.757-0.488-1.235-0.509c-1.108-0.049-2.046,0.809-2.095,1.917c-0.032,0.724,0.327,1.37,0.887,1.749 c-0.001,0-0.002-0.001-0.003-0.001c2.221,1.871,4.536,2.88,6.912,2.986c0.333,0.014,0.67,0.012,1.007-0.01 c3.163-0.191,5.572-1.942,6.888-3.166l0.452-0.453c0.021-0.019,0.04-0.041,0.06-0.061l0.034-0.034 c-0.007,0.007-0.015,0.014-0.021,0.02C71.666,63.771,71.892,63.307,71.916,62.782z"></path>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="18.614" cy="99.426" r="3.292"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="95.364" cy="28.676" r="3.291"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="24.739" cy="93.551" r="2.667"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="101.489" cy="33.051" r="2.666"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="18.738" cy="87.717" r="2.833"></circle>
|
||||
<path fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" d="M116.279,55.814c-0.021-0.286-2.323-28.744-30.221-41.012 c-7.806-3.433-15.777-5.173-23.691-5.173c-16.889,0-30.283,7.783-37.187,15.067c-9.229,9.736-13.84,26.712-14.191,30.259 l-0.748,62.332c0.149,2.133,1.389,6.167,5.019,6.167c1.891,0,4.074-1.083,6.672-3.311c4.96-4.251,7.424-6.295,9.226-6.295 c1.339,0,2.712,1.213,5.102,3.762c4.121,4.396,7.461,6.355,10.833,6.355c2.713,0,5.311-1.296,7.942-3.962 c3.104-3.145,5.701-5.239,8.285-5.239c2.116,0,4.441,1.421,7.317,4.473c2.638,2.8,5.674,4.219,9.022,4.219 c4.835,0,8.991-2.959,11.27-5.728l0.086-0.104c1.809-2.2,3.237-3.938,5.312-3.938c2.208,0,5.271,1.942,9.359,5.936 c0.54,0.743,3.552,4.674,6.86,4.674c1.37,0,2.559-0.65,3.531-1.932l0.203-0.268L116.279,55.814z M114.281,121.405 c-0.526,0.599-1.096,0.891-1.734,0.891c-2.053,0-4.51-2.82-5.283-3.907l-0.116-0.136c-4.638-4.541-7.975-6.566-10.82-6.566 c-3.021,0-4.884,2.267-6.857,4.667l-0.086,0.104c-1.896,2.307-5.582,4.999-9.725,4.999c-2.775,0-5.322-1.208-7.567-3.59 c-3.325-3.528-6.03-5.102-8.772-5.102c-3.278,0-6.251,2.332-9.708,5.835c-2.236,2.265-4.368,3.366-6.518,3.366 c-2.772,0-5.664-1.765-9.374-5.723c-2.488-2.654-4.29-4.395-6.561-4.395c-2.515,0-5.045,2.077-10.527,6.777 c-2.727,2.337-4.426,2.828-5.37,2.828c-2.662,0-3.017-4.225-3.021-4.225l0.745-62.163c0.332-3.321,4.767-19.625,13.647-28.995 c3.893-4.106,10.387-8.632,18.602-11.504c-0.458,0.503-0.744,1.165-0.744,1.898c0,1.565,1.269,2.833,2.833,2.833 c1.564,0,2.833-1.269,2.833-2.833c0-1.355-0.954-2.485-2.226-2.764c4.419-1.285,9.269-2.074,14.437-2.074 c7.636,0,15.336,1.684,22.887,5.004c26.766,11.771,29.011,39.047,29.027,39.251V121.405z"></path>
|
||||
</svg>
|
||||
<p class="shadowFrame">
|
||||
<svg version="1.1" class="shadow" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="61px" y="20px" width="122.436px" height="39.744px" viewBox="0 0 122.436 39.744" enable-background="new 0 0 122.436 39.744" xml:space="preserve">
|
||||
<ellipse fill="#262626" cx="61.128" cy="19.872" rx="49.25" ry="8.916"></ellipse>
|
||||
</svg>
|
||||
</p>
|
||||
<h3>Error {{ code }}</h3>
|
||||
<p class="description">{{ description }}</p>
|
||||
</div>
|
||||
</body></html>
|
181
yarn.lock
Normal file
181
yarn.lock
Normal file
@ -0,0 +1,181 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/color-name@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
ansi-regex@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-styles@^4.0.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
|
||||
integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
|
||||
dependencies:
|
||||
"@types/color-name" "^1.1.1"
|
||||
color-convert "^2.0.1"
|
||||
|
||||
camelcase@^5.0.0:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
cliui@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
|
||||
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^6.2.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
decamelize@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
find-up@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
||||
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
|
||||
dependencies:
|
||||
locate-path "^5.0.0"
|
||||
path-exists "^4.0.0"
|
||||
|
||||
get-caller-file@^2.0.1:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||
|
||||
locate-path@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
|
||||
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
|
||||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
p-limit@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
|
||||
dependencies:
|
||||
p-try "^2.0.0"
|
||||
|
||||
p-locate@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
|
||||
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
|
||||
dependencies:
|
||||
p-limit "^2.2.0"
|
||||
|
||||
p-try@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
require-main-filename@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||
|
||||
set-blocking@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
|
||||
integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
strip-ansi@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
which-module@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||
|
||||
wrap-ansi@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
||||
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
||||
|
||||
yargs-parser@^18.1.1:
|
||||
version "18.1.3"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
|
||||
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
|
||||
dependencies:
|
||||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs@15.3:
|
||||
version "15.3.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b"
|
||||
integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==
|
||||
dependencies:
|
||||
cliui "^6.0.0"
|
||||
decamelize "^1.2.0"
|
||||
find-up "^4.1.0"
|
||||
get-caller-file "^2.0.1"
|
||||
require-directory "^2.1.1"
|
||||
require-main-filename "^2.0.0"
|
||||
set-blocking "^2.0.0"
|
||||
string-width "^4.2.0"
|
||||
which-module "^2.0.0"
|
||||
y18n "^4.0.0"
|
||||
yargs-parser "^18.1.1"
|
Loading…
Reference in New Issue
Block a user