mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
Compare commits
18 Commits
v1.0.1
...
v1.5.0-RC2
Author | SHA1 | Date | |
---|---|---|---|
294f76d56b | |||
3c07d04c71 | |||
515bd44e13 | |||
c6aa014458 | |||
a55ec08eef | |||
7957d16c0f | |||
80b2544f36 | |||
090767ba6b | |||
a040c913e7 | |||
5ab113ba1a | |||
ea46e9f738 | |||
aeb6018a57 | |||
158856bebd | |||
f140dd3ad8 | |||
699cccbdec | |||
abc317955f | |||
be0d3b9e1f | |||
29fdeef742 |
@ -1,3 +1,7 @@
|
|||||||
|
.dockerignore
|
||||||
|
.github
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
/generator/node_modules
|
||||||
|
/generator/*.log
|
||||||
/out
|
/out
|
||||||
/node_modules
|
|
||||||
*.log
|
|
||||||
|
52
.github/workflows/release.yml
vendored
52
.github/workflows/release.yml
vendored
@ -7,7 +7,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
demo:
|
demo:
|
||||||
name: Update demonstration, hosted on github pages
|
name: Update demonstration, hosted on github pages
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -15,10 +15,7 @@ jobs:
|
|||||||
- name: Setup NodeJS
|
- name: Setup NodeJS
|
||||||
uses: actions/setup-node@v1 # Action page: <https://github.com/actions/setup-node>
|
uses: actions/setup-node@v1 # Action page: <https://github.com/actions/setup-node>
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 15
|
||||||
|
|
||||||
- name: Generate version value
|
|
||||||
run: echo "::set-env name=PACKAGE_VERSION::${GITHUB_REF##*/v}"
|
|
||||||
|
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
@ -26,13 +23,11 @@ jobs:
|
|||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
working-directory: generator
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
|
||||||
- name: Generate pages
|
- name: Generate pages
|
||||||
run: ./bin/generator.js -c ./config.json -o ./out
|
run: ./generator/generator.js -i -c ./config.json -o ./out
|
||||||
|
|
||||||
- name: Copy static files
|
|
||||||
run: cp ./static/* ./out
|
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
@ -67,24 +62,35 @@ jobs:
|
|||||||
|
|
||||||
docker-image:
|
docker-image:
|
||||||
name: Build docker image
|
name: Build docker image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
|
|
||||||
- name: Generate image tag value
|
- name: Set up QEMU
|
||||||
run: echo "::set-env name=IMAGE_TAG::${GITHUB_REF##*/[vV]}" # `/refs/tags/v1.2.3` -> `1.2.3`
|
uses: docker/setup-qemu-action@v1 # Action page: <https://github.com/docker/setup-qemu-action>
|
||||||
|
|
||||||
- name: Make docker login
|
- name: Set up Docker Buildx
|
||||||
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_LOGIN }}" --password-stdin &> /dev/null
|
uses: docker/setup-buildx-action@v1 # Action page: <https://github.com/docker/setup-buildx-action>
|
||||||
|
|
||||||
|
- name: Docker login in default registry
|
||||||
|
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_LOGIN }}" --password-stdin
|
||||||
|
|
||||||
|
- name: Docker login in ghcr.io # Auth docs: <https://git.io/JLDaw>
|
||||||
|
run: echo "${{ secrets.GHCR_PASSWORD }}" | docker login ghcr.io -u tarampampam --password-stdin
|
||||||
|
|
||||||
|
- name: Generate builder values
|
||||||
|
id: values
|
||||||
|
run: echo "::set-output name=version::${GITHUB_REF##*/[vV]}" # `/refs/tags/v1.2.3` -> `1.2.3`
|
||||||
|
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: docker build --tag "tarampampam/error-pages:${IMAGE_TAG}" --tag "tarampampam/error-pages:latest" -f ./Dockerfile .
|
run: |
|
||||||
|
docker buildx build \
|
||||||
- name: Push version image
|
--platform "linux/amd64,linux/arm64/v8,linux/arm/v6,linux/arm/v7" \
|
||||||
run: docker push "tarampampam/error-pages:${IMAGE_TAG}"
|
--tag "tarampampam/error-pages:${{ steps.values.outputs.version }}" \
|
||||||
|
--tag "tarampampam/error-pages:latest" \
|
||||||
- name: Push latest image
|
--tag "ghcr.io/tarampampam/error-pages:${{ steps.values.outputs.version }}" \
|
||||||
run: docker push "tarampampam/error-pages:latest"
|
--tag "ghcr.io/tarampampam/error-pages:latest" \
|
||||||
|
--file ./Dockerfile \
|
||||||
|
--push \
|
||||||
|
.
|
||||||
|
46
.github/workflows/tests.yml
vendored
46
.github/workflows/tests.yml
vendored
@ -6,12 +6,28 @@ on:
|
|||||||
- master
|
- master
|
||||||
tags-ignore:
|
tags-ignore:
|
||||||
- '**'
|
- '**'
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
jobs: # Docs: <https://git.io/JvxXE>
|
jobs: # Docs: <https://git.io/JvxXE>
|
||||||
|
gitleaks:
|
||||||
|
name: Gitleaks
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Check for GitLeaks
|
||||||
|
uses: zricethezav/gitleaks-action@v1.5.0 # Action page: <https://github.com/zricethezav/gitleaks-action>
|
||||||
|
|
||||||
generate:
|
generate:
|
||||||
name: Try to run generator
|
name: Try to run generator
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -19,7 +35,7 @@ jobs: # Docs: <https://git.io/JvxXE>
|
|||||||
- name: Setup NodeJS
|
- name: Setup NodeJS
|
||||||
uses: actions/setup-node@v1 # Action page: <https://github.com/actions/setup-node>
|
uses: actions/setup-node@v1 # Action page: <https://github.com/actions/setup-node>
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 15
|
||||||
|
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
@ -27,17 +43,23 @@ jobs: # Docs: <https://git.io/JvxXE>
|
|||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
working-directory: generator
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
|
||||||
- name: Run generator
|
- name: Run generator
|
||||||
run: ./bin/generator.js -c ./config.json -o ./out
|
run: ./generator/generator.js -i -c ./config.json -o ./out
|
||||||
|
|
||||||
- name: Test file creation
|
- name: Test file creation
|
||||||
run: test -f ./out/ghost/404.html
|
run: |
|
||||||
|
test -f ./out/index.html
|
||||||
|
test -f ./out/ghost/404.html
|
||||||
|
test -f ./out/l7-dark/404.html
|
||||||
|
test -f ./out/l7-light/404.html
|
||||||
|
test -f ./out/shuffle/404.html
|
||||||
|
|
||||||
docker-build:
|
docker-build:
|
||||||
name: Build docker image
|
name: Build docker image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -45,11 +67,21 @@ jobs: # Docs: <https://git.io/JvxXE>
|
|||||||
- name: Build docker image
|
- name: Build docker image
|
||||||
run: docker build -f ./Dockerfile --tag image:local .
|
run: docker build -f ./Dockerfile --tag image:local .
|
||||||
|
|
||||||
|
- name: Scan image
|
||||||
|
uses: anchore/scan-action@v2 # action page: <https://github.com/anchore/scan-action>
|
||||||
|
with:
|
||||||
|
image: image:local
|
||||||
|
fail-build: true
|
||||||
|
severity-cutoff: medium # negligible, low, medium, high or critical
|
||||||
|
|
||||||
- name: Run docker image
|
- name: Run docker image
|
||||||
run: docker run --rm -d -p "8080:8080" -e "TEMPLATE_NAME=ghost" image:local
|
run: docker run --rm -d -p "8080:8080/tcp" -e "TEMPLATE_NAME=ghost" image:local
|
||||||
|
|
||||||
- name: Pause
|
- name: Pause
|
||||||
run: sleep 2
|
run: sleep 2
|
||||||
|
|
||||||
- name: Send HTTP request
|
- name: Verify 500.html error file exists in root
|
||||||
run: curl -sS --fail "http://127.0.0.1:8080/500.html"
|
run: curl -sS --fail "http://127.0.0.1:8080/500.html"
|
||||||
|
|
||||||
|
- name: Verify root request HTTP code
|
||||||
|
run: test $(curl --write-out %{http_code} --silent --output /dev/null http://127.0.0.1:8080/) -eq 404
|
||||||
|
9
.gitignore
vendored
9
.gitignore
vendored
@ -2,17 +2,8 @@
|
|||||||
/.vscode
|
/.vscode
|
||||||
/.idea
|
/.idea
|
||||||
|
|
||||||
## Vendors
|
|
||||||
/node_modules
|
|
||||||
|
|
||||||
## Lock files (use yarn only)
|
|
||||||
/package-lock.json
|
|
||||||
|
|
||||||
## Dist
|
## Dist
|
||||||
/out
|
/out
|
||||||
|
|
||||||
## Temp dirs & trash
|
## Temp dirs & trash
|
||||||
/npm-debug.log
|
|
||||||
/yarn-error.log
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env*
|
|
||||||
|
60
CHANGELOG.md
60
CHANGELOG.md
@ -4,6 +4,66 @@ 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].
|
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
|
||||||
|
|
||||||
|
## v1.5.0
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Repository files structure
|
||||||
|
- Nginx updated from `1.18` up to `1.19` in docker image
|
||||||
|
- Docker image now uses default `nginx` entrypoint scripts and command
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for `linux/arm64/v8`, `linux/arm/v6` and `linux/arm/v7` platforms for docker image
|
||||||
|
- Random template selecting (use `random` as a template name) for docker image
|
||||||
|
|
||||||
|
## v1.4.0
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Template `shuffle` [#4]
|
||||||
|
|
||||||
|
[#4]:https://github.com/tarampampam/error-pages/issues/4
|
||||||
|
|
||||||
|
## v1.3.1
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `can't create directory '/opt/html/nginx-error-pages'` error [#3]
|
||||||
|
|
||||||
|
[#3]:https://github.com/tarampampam/error-pages/issues/3
|
||||||
|
|
||||||
|
## v1.3.0
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `418` status code error page
|
||||||
|
- Set `server_tokens off;` in `nginx` server configuration
|
||||||
|
|
||||||
|
## v1.2.0
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- By default `nginx` in docker container returns 404 http code instead 200 when `/` requested
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Default value for `TEMPLATE_NAME` is `ghost` now
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Environment variable `DEFAULT_ERROR_CODE` support in docker image
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Templates `l7-light` and `l7-dark`
|
||||||
|
|
||||||
|
## v1.1.0
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Environment variable `DEFAULT_ERROR_CODE` support in docker image
|
||||||
|
|
||||||
## v1.0.1
|
## v1.0.1
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
49
Dockerfile
49
Dockerfile
@ -1,22 +1,45 @@
|
|||||||
# Image page: <https://hub.docker.com/_/node>
|
# Image page: <https://hub.docker.com/_/node>
|
||||||
FROM node:12.16.2-alpine as builder
|
FROM node:15.14-alpine as builder
|
||||||
|
|
||||||
|
# copy required sources into builder image
|
||||||
|
COPY ./generator /src/generator
|
||||||
|
COPY ./config.json /src
|
||||||
|
COPY ./templates /src/templates
|
||||||
|
COPY ./docker /src/docker
|
||||||
|
|
||||||
|
# install generator dependencies
|
||||||
|
WORKDIR /src/generator
|
||||||
|
RUN yarn install --frozen-lockfile --no-progress --non-interactive
|
||||||
|
|
||||||
|
# run generator
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
RUN ./generator/generator.js -c ./config.json -o ./out
|
||||||
|
|
||||||
COPY . .
|
# prepare rootfs for runtime
|
||||||
|
RUN mkdir /tmp/rootfs
|
||||||
|
WORKDIR /tmp/rootfs
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& yarn install --frozen-lockfile \
|
&& mkdir -p \
|
||||||
&& ./bin/generator.js -c ./config.json -o ./out
|
./docker-entrypoint.d \
|
||||||
|
./etc/nginx/conf.d \
|
||||||
|
./opt \
|
||||||
|
&& mv /src/out ./opt/html \
|
||||||
|
&& echo -e "User-agent: *\nDisallow: /\n" > ./opt/html/robots.txt \
|
||||||
|
&& touch ./opt/html/favicon.ico \
|
||||||
|
&& mv /src/docker/docker-entrypoint.d/* ./docker-entrypoint.d \
|
||||||
|
&& mv /src/docker/nginx-server.conf ./etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
# Image page: <https://hub.docker.com/_/nginx>
|
# Image page: <https://hub.docker.com/_/nginx>
|
||||||
FROM nginx:1.18-alpine
|
FROM --platform=${TARGETPLATFORM:-linux/amd64} nginx:1.19-alpine as runtime
|
||||||
|
|
||||||
COPY --from=builder --chown=nginx /src/docker/docker-entrypoint.sh /docker-entrypoint.sh
|
LABEL \
|
||||||
COPY --from=builder --chown=nginx /src/docker/nginx-server.conf /etc/nginx/conf.d/default.conf
|
# Docs: <https://github.com/opencontainers/image-spec/blob/master/annotations.md>
|
||||||
COPY --from=builder --chown=nginx /src/static /opt/html
|
org.opencontainers.image.title="error-pages" \
|
||||||
COPY --from=builder --chown=nginx /src/out /opt/html
|
org.opencontainers.image.description="Static server error pages in docker image" \
|
||||||
|
org.opencontainers.image.url="https://github.com/tarampampam/error-pages" \
|
||||||
|
org.opencontainers.image.source="https://github.com/tarampampam/error-pages" \
|
||||||
|
org.opencontainers.image.vendor="tarampampam" \
|
||||||
|
org.opencontainers.image.licenses="MIT"
|
||||||
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
# Import from builder
|
||||||
|
COPY --from=builder --chown=nginx /tmp/rootfs /
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
|
13
Makefile
13
Makefile
@ -4,9 +4,6 @@
|
|||||||
|
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
DOCKER_BIN = $(shell command -v docker 2> /dev/null)
|
|
||||||
DC_BIN = $(shell command -v docker-compose 2> /dev/null)
|
|
||||||
|
|
||||||
DC_RUN_ARGS = --rm --user "$(shell id -u):$(shell id -g)"
|
DC_RUN_ARGS = --rm --user "$(shell id -u):$(shell id -g)"
|
||||||
APP_NAME = $(notdir $(CURDIR))
|
APP_NAME = $(notdir $(CURDIR))
|
||||||
|
|
||||||
@ -18,15 +15,15 @@ help: ## Show this help
|
|||||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[32m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[32m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
install: ## Install all dependencies
|
install: ## Install all dependencies
|
||||||
$(DC_BIN) run $(DC_RUN_ARGS) app yarn install
|
docker-compose run $(DC_RUN_ARGS) -w "/src/generator" node yarn install --frozen-lockfile --no-progress --non-interactive
|
||||||
|
|
||||||
gen: ## Generate error pages
|
gen: ## Generate error pages
|
||||||
$(DC_BIN) run $(DC_RUN_ARGS) app nodejs ./bin/generator.js -c ./config.json -o ./out
|
docker-compose run $(DC_RUN_ARGS) node nodejs ./generator/generator.js -i -c ./config.json -o ./out
|
||||||
|
|
||||||
preview: ## Build docker image and start preview
|
preview: ## Build docker image and start preview
|
||||||
$(DOCKER_BIN) build -f ./Dockerfile -t $(APP_NAME):local .
|
docker build -f ./Dockerfile -t $(APP_NAME):local .
|
||||||
@printf "\n \e[30;42m %s \033[0m\n\n" 'Now open in your favorite browser <http://127.0.0.1:8081> and press CTRL+C for stopping'
|
@printf "\n \e[30;42m %s \033[0m\n\n" 'Now open in your favorite browser <http://127.0.0.1:8081> and press CTRL+C for stopping'
|
||||||
$(DOCKER_BIN) run --rm -i -p 8081:8080 $(APP_NAME):local
|
docker run --rm -i -p 8081:8080 -e "TEMPLATE_NAME=random" $(APP_NAME):local
|
||||||
|
|
||||||
shell: ## Start shell into container with node
|
shell: ## Start shell into container with node
|
||||||
$(DC_BIN) run $(DC_RUN_ARGS) app sh
|
docker-compose run $(DC_RUN_ARGS) node sh
|
||||||
|
142
README.md
142
README.md
@ -6,73 +6,57 @@
|
|||||||
|
|
||||||
[![Build Status][badge_build_status]][link_build_status]
|
[![Build Status][badge_build_status]][link_build_status]
|
||||||
[![Image size][badge_size_latest]][link_docker_hub]
|
[![Image size][badge_size_latest]][link_docker_hub]
|
||||||
|
[![Docker Pulls][badge_docker_pulls]][link_docker_hub]
|
||||||
[![License][badge_license]][link_license]
|
[![License][badge_license]][link_license]
|
||||||
|
|
||||||
This repository contains:
|
This repository contains:
|
||||||
|
|
||||||
- A very simple [generator](./bin/generator.js) _(`nodejs`)_ for HTTP error pages _(like `404: Not found`)_ with different templates supports
|
- A very simple [generator](generator/generator.js) _(`nodejs`)_ for HTTP error pages _(like `404: Not found`)_ with different templates supports
|
||||||
- Dockerfile for [docker image][link_docker_hub] with generated pages and `nginx` as web server
|
- Dockerfile for docker image ([docker hub][link_docker_hub], [ghcr.io][link_ghcr]) with generated pages and `nginx` as a web server
|
||||||
|
|
||||||
### Demo
|
**Can be used for [Traefik error pages customization](https://docs.traefik.io/middlewares/errorpages/)**.
|
||||||
|
|
||||||
Generated pages (from the latest release) always [accessible here][link_branch_gh_pages] _(sources)_ and on GitHub pages [here][link_gh_pages].
|
## Demo
|
||||||
|
|
||||||
## Development
|
Generated pages (from the latest release) always **[accessible here][link_gh_pages]** _(live preview)_.
|
||||||
|
|
||||||
> For project development we use `docker-ce` + `docker-compose`. Make sure you have them installed.
|
|
||||||
|
|
||||||
Install `nodejs` dependencies:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ make install
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to generate error pages on your machine _(after that look into output directory)_:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ make gen
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to preview the pages using the Docker image:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ make preview
|
|
||||||
```
|
|
||||||
|
|
||||||
Can be used for [Traefik error pages customization](https://docs.traefik.io/middlewares/errorpages/).
|
|
||||||
|
|
||||||
## Templates
|
## Templates
|
||||||
|
|
||||||
Name | Preview
|
Name | Preview
|
||||||
:------: | :-----:
|
:--------: | :-----:
|
||||||
`ghost` | 
|
`ghost` | 
|
||||||
|
`l7-light` | 
|
||||||
|
`l7-dark` | 
|
||||||
|
`shuffle` | 
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Generated error pages in our [docker image][link_docker_hub] permanently located in directory `/opt/html/%THEME_NAME%`.
|
Generated error pages in our [docker image][link_docker_hub] permanently located in directory `/opt/html/%TEMPLATE_NAME%`. `nginx` in a container listen for `8080` (`http`) port.
|
||||||
|
|
||||||
#### Supported environment variables
|
#### Supported environment variables
|
||||||
|
|
||||||
Name | Description
|
Name | Description
|
||||||
--------------- | -----------
|
--------------- | -----------
|
||||||
`TEMPLATE_NAME` | "default" pages template _(allows to use error pages without passing theme name in URL - `http://127.0.0.1/500.html` instead `http://127.0.0.1/ghost/500.html`)_
|
`TEMPLATE_NAME` | (`ghost` by default) "default" pages template _(allows to use error pages without passing theme name in URL - `http://127.0.0.1/500.html` instead `http://127.0.0.1/ghost/500.html`)_
|
||||||
|
|
||||||
### HTTP server for error pages serving only
|
### Ready docker image
|
||||||
|
|
||||||
Execute in your shell:
|
Execute in your shell:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker run --rm -p "8082:8080" tarampampam/error-pages
|
$ docker run --rm -p "8082:8080" tarampampam/error-pages:X.X.X
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Important notice: do **not** use the `latest` image tag _(this is bad practice)_. Use versioned tag (like `1.2.3`) instead.
|
||||||
|
|
||||||
And open in your browser `http://127.0.0.1:8082/ghost/400.html`.
|
And open in your browser `http://127.0.0.1:8082/ghost/400.html`.
|
||||||
|
|
||||||
### Custom error pages for [nginx][link_nginx]
|
### Custom error pages for your image with [nginx][link_nginx]
|
||||||
|
|
||||||
You can build your own docker image with `nginx` and our error pages:
|
You can build your own docker image with `nginx` and our error pages:
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
# File `./nginx.conf`
|
# File `nginx.conf`
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
@ -98,23 +82,100 @@ server {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
|
# File `Dockerfile`
|
||||||
|
|
||||||
FROM nginx:1.18-alpine
|
FROM nginx:1.18-alpine
|
||||||
|
|
||||||
COPY --chown=nginx \
|
COPY --chown=nginx \
|
||||||
./nginx.conf /etc/nginx/conf.d/default.conf
|
./nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
COPY --chown=nginx \
|
COPY --chown=nginx \
|
||||||
--from=tarampampam/error-pages:1.0.0 \
|
--from=tarampampam/error-pages:1.5.0 \
|
||||||
/opt/html/ghost /usr/share/nginx/errorpages/_error-pages
|
/opt/html/ghost /usr/share/nginx/errorpages/_error-pages
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ docker build --tag your-nginx:local -f ./Dockerfile .
|
||||||
|
```
|
||||||
|
|
||||||
> More info about `error_page` directive can be [found here](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page).
|
> More info about `error_page` directive can be [found here](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page).
|
||||||
|
|
||||||
### Custom error pages for [Traefik][link_traefik]
|
### Custom error pages for [Traefik][link_traefik]
|
||||||
|
|
||||||
Simple traefik service configuration for usage in [docker swarm][link_swarm] (**change with your needs**):
|
Simple traefik (tested on `v2.4.8`) service configuration for usage in [docker swarm][link_swarm] (**change with your needs**):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Work in progress
|
version: '3.4'
|
||||||
|
|
||||||
|
services:
|
||||||
|
error-pages:
|
||||||
|
image: tarampampam/error-pages:1.5.0
|
||||||
|
environment:
|
||||||
|
TEMPLATE_NAME: l7-dark
|
||||||
|
networks:
|
||||||
|
- traefik-public
|
||||||
|
deploy:
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == worker
|
||||||
|
labels:
|
||||||
|
traefik.enable: 'true'
|
||||||
|
traefik.docker.network: traefik-public
|
||||||
|
# use as "fallback" for any non-registered services (with priority below normal)
|
||||||
|
traefik.http.routers.error-pages-router.rule: HostRegexp(`{host:.+}`)
|
||||||
|
traefik.http.routers.error-pages-router.priority: 10
|
||||||
|
# should say that all of your services work on https
|
||||||
|
traefik.http.routers.error-pages-router.tls: 'true'
|
||||||
|
traefik.http.routers.error-pages-router.entrypoints: https
|
||||||
|
traefik.http.routers.error-pages-router.middlewares: error-pages-middleware@docker
|
||||||
|
traefik.http.services.error-pages-service.loadbalancer.server.port: 8080
|
||||||
|
# "errors" middleware settings
|
||||||
|
traefik.http.middlewares.error-pages-middleware.errors.status: 400-599
|
||||||
|
traefik.http.middlewares.error-pages-middleware.errors.service: error-pages-service@docker
|
||||||
|
traefik.http.middlewares.error-pages-middleware.errors.query: /{status}.html
|
||||||
|
|
||||||
|
any-another-http-service:
|
||||||
|
image: nginx:alpine
|
||||||
|
networks:
|
||||||
|
- traefik-public
|
||||||
|
deploy:
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == worker
|
||||||
|
labels:
|
||||||
|
traefik.enable: 'true'
|
||||||
|
traefik.docker.network: traefik-public
|
||||||
|
traefik.http.routers.another-service.rule: Host(`subdomain.example.com`)
|
||||||
|
traefik.http.routers.another-service.tls: 'true'
|
||||||
|
traefik.http.routers.another-service.entrypoints: https
|
||||||
|
# next line is important
|
||||||
|
traefik.http.routers.another-service.middlewares: error-pages-middleware@docker
|
||||||
|
traefik.http.services.another-service.loadbalancer.server.port: 80
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik-public:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
> For project development we use `docker-ce` + `docker-compose`. Make sure you have them installed.
|
||||||
|
|
||||||
|
Install "generator" dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to generate error pages on your machine _(after that look into the output directory)_:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make gen
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to preview the pages using the Docker image:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make preview
|
||||||
```
|
```
|
||||||
|
|
||||||
## Changes log
|
## Changes log
|
||||||
@ -142,6 +203,7 @@ This is open-sourced software licensed under the [MIT License][link_license].
|
|||||||
[badge_pulls]:https://img.shields.io/github/issues-pr/tarampampam/error-pages.svg?style=flat-square&maxAge=180
|
[badge_pulls]:https://img.shields.io/github/issues-pr/tarampampam/error-pages.svg?style=flat-square&maxAge=180
|
||||||
[badge_license]:https://img.shields.io/github/license/tarampampam/error-pages.svg?longCache=true
|
[badge_license]:https://img.shields.io/github/license/tarampampam/error-pages.svg?longCache=true
|
||||||
[badge_size_latest]:https://img.shields.io/docker/image-size/tarampampam/error-pages/latest?maxAge=30
|
[badge_size_latest]:https://img.shields.io/docker/image-size/tarampampam/error-pages/latest?maxAge=30
|
||||||
|
[badge_docker_pulls]:https://img.shields.io/docker/pulls/tarampampam/error-pages.svg
|
||||||
[link_releases]:https://github.com/tarampampam/error-pages/releases
|
[link_releases]:https://github.com/tarampampam/error-pages/releases
|
||||||
[link_commits]:https://github.com/tarampampam/error-pages/commits
|
[link_commits]:https://github.com/tarampampam/error-pages/commits
|
||||||
[link_changes_log]:https://github.com/tarampampam/error-pages/blob/master/CHANGELOG.md
|
[link_changes_log]:https://github.com/tarampampam/error-pages/blob/master/CHANGELOG.md
|
||||||
@ -151,8 +213,8 @@ This is open-sourced software licensed under the [MIT License][link_license].
|
|||||||
[link_create_issue]:https://github.com/tarampampam/error-pages/issues/new
|
[link_create_issue]:https://github.com/tarampampam/error-pages/issues/new
|
||||||
[link_license]:https://github.com/tarampampam/error-pages/blob/master/LICENSE
|
[link_license]:https://github.com/tarampampam/error-pages/blob/master/LICENSE
|
||||||
[link_docker_hub]:https://hub.docker.com/r/tarampampam/error-pages/
|
[link_docker_hub]:https://hub.docker.com/r/tarampampam/error-pages/
|
||||||
|
[link_ghcr]:https://github.com/users/tarampampam/packages/container/package/error-pages
|
||||||
[link_nginx]:http://nginx.org/
|
[link_nginx]:http://nginx.org/
|
||||||
[link_traefik]:https://docs.traefik.io/
|
[link_traefik]:https://docs.traefik.io/
|
||||||
[link_swarm]:https://docs.docker.com/engine/swarm/
|
[link_swarm]:https://docs.docker.com/engine/swarm/
|
||||||
[link_branch_gh_pages]:https://github.com/tarampampam/error-pages/tree/gh-pages
|
|
||||||
[link_gh_pages]:https://tarampampam.github.io/error-pages/
|
[link_gh_pages]:https://tarampampam.github.io/error-pages/
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
#!/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) => {
|
|
||||||
let outPath = path.join(templateOutDir, `${pageConfig.code}.${configContent.output.file_extension}`);
|
|
||||||
|
|
||||||
console.info(` [${templateConfig.name}:${pageConfig.code}] Output: ${outPath}`);
|
|
||||||
|
|
||||||
// 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(outPath, result, {
|
|
||||||
encoding: "utf8",
|
|
||||||
flag: "w+",
|
|
||||||
mode: 0o644
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
17
config.json
17
config.json
@ -3,6 +3,18 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost",
|
"name": "ghost",
|
||||||
"path": "./templates/ghost.html"
|
"path": "./templates/ghost.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "l7-light",
|
||||||
|
"path": "./templates/l7-light.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "l7-dark",
|
||||||
|
"path": "./templates/l7-dark.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "shuffle",
|
||||||
|
"path": "./templates/shuffle.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"output": {
|
"output": {
|
||||||
@ -74,6 +86,11 @@
|
|||||||
"message": "Requested Range Not Satisfiable",
|
"message": "Requested Range Not Satisfiable",
|
||||||
"description": "The requested byte range is not available and is out of bounds"
|
"description": "The requested byte range is not available and is out of bounds"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": 418,
|
||||||
|
"message": "I'm a teapot",
|
||||||
|
"description": "Attempt to brew coffee with a teapot is not supported"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": 429,
|
"code": 429,
|
||||||
"message": "Too Many Requests",
|
"message": "Too Many Requests",
|
||||||
|
@ -4,8 +4,8 @@ volumes:
|
|||||||
tmp-data:
|
tmp-data:
|
||||||
|
|
||||||
services:
|
services:
|
||||||
app:
|
node:
|
||||||
image: node:12.16.2-alpine # Image page: <https://hub.docker.com/_/node>
|
image: node:15.14-alpine # Image page: <https://hub.docker.com/_/node>
|
||||||
working_dir: /src
|
working_dir: /src
|
||||||
environment:
|
environment:
|
||||||
HOME: /tmp
|
HOME: /tmp
|
||||||
@ -14,4 +14,3 @@ services:
|
|||||||
- /etc/passwd:/etc/passwd:ro
|
- /etc/passwd:/etc/passwd:ro
|
||||||
- /etc/group:/etc/group:ro
|
- /etc/group:/etc/group:ro
|
||||||
- .:/src:cached
|
- .:/src:cached
|
||||||
- tmp-data:/tmp:cached
|
|
||||||
|
41
docker/docker-entrypoint.d/100-setup-error-pages.sh
Executable file
41
docker/docker-entrypoint.d/100-setup-error-pages.sh
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# allows to use random template
|
||||||
|
if [ ! -z "$TEMPLATE_NAME" ] && ([ "$TEMPLATE_NAME" = "random" ] || [ "$TEMPLATE_NAME" = "RANDOM" ]); then
|
||||||
|
# find all templates in directory (only template directories must be located in /opt/html)
|
||||||
|
allowed_templates=$(find /opt/html/* -maxdepth 1 -type d -exec basename {} \;);
|
||||||
|
|
||||||
|
# pick random template name
|
||||||
|
random_template_name=$(shuf -e -n1 $allowed_templates);
|
||||||
|
|
||||||
|
echo "$0: Use '$random_template_name' as randomly selected template";
|
||||||
|
|
||||||
|
TEMPLATE_NAME="$random_template_name"
|
||||||
|
fi;
|
||||||
|
|
||||||
|
TEMPLATE_NAME=${TEMPLATE_NAME:-ghost} # string|empty
|
||||||
|
|
||||||
|
echo "$0: Set pages for template '$TEMPLATE_NAME' as default (make accessible in root directory)";
|
||||||
|
|
||||||
|
# check for template existing
|
||||||
|
if [ ! -d "/opt/html/$TEMPLATE_NAME" ]; then
|
||||||
|
echo >&3 "$0: Template '$TEMPLATE_NAME' was not found!";
|
||||||
|
exit 1;
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# allows "direct access" to the error pages using URLs like "/500.html"
|
||||||
|
ln -f -s "/opt/html/$TEMPLATE_NAME/"* /opt/html;
|
||||||
|
|
||||||
|
# on `docker restart` next directory keep existing: <https://github.com/tarampampam/error-pages/issues/3>
|
||||||
|
if [ -d /opt/html/nginx-error-pages ]; then
|
||||||
|
rm -Rf /opt/html/nginx-error-pages;
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# next directory is required for easy nginx `error_page` usage
|
||||||
|
mkdir /opt/html/nginx-error-pages;
|
||||||
|
|
||||||
|
# use error pages from the template as "native" nginx error pages
|
||||||
|
ln -f -s "/opt/html/$TEMPLATE_NAME/"* /opt/html/nginx-error-pages;
|
||||||
|
|
||||||
|
exit 0
|
@ -1,16 +0,0 @@
|
|||||||
#!/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 "$@"
|
|
@ -2,8 +2,24 @@ server {
|
|||||||
listen 8080;
|
listen 8080;
|
||||||
server_name _;
|
server_name _;
|
||||||
|
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
index index.html index.htm;
|
||||||
|
root /opt/html;
|
||||||
|
|
||||||
|
error_page 400 /nginx-error-pages/400.html;
|
||||||
|
error_page 401 /nginx-error-pages/401.html;
|
||||||
|
error_page 403 /nginx-error-pages/403.html;
|
||||||
|
error_page 404 /nginx-error-pages/404.html;
|
||||||
|
error_page 500 /nginx-error-pages/500.html;
|
||||||
|
error_page 502 /nginx-error-pages/502.html;
|
||||||
|
|
||||||
|
location ^~ /nginx-error-pages/ {
|
||||||
|
internal;
|
||||||
|
root /opt/html;
|
||||||
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /opt/html;
|
try_files $uri =404;
|
||||||
index index.html index.htm;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
generator/.gitignore
vendored
Normal file
9
generator/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
## Vendors
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
## Lock files (use yarn only)
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
## Temp dirs & trash
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
130
generator/generator.js
Executable file
130
generator/generator.js
Executable file
@ -0,0 +1,130 @@
|
|||||||
|
#!/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})
|
||||||
|
.option("i", {alias: "index", describe: "generate index page", type: "boolean"})
|
||||||
|
.argv;
|
||||||
|
|
||||||
|
const configFile = options.config;
|
||||||
|
const outDir = options.out;
|
||||||
|
const generateIndexPage = options.index;
|
||||||
|
|
||||||
|
const generated = {};
|
||||||
|
|
||||||
|
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) => {
|
||||||
|
let outFileName = pageConfig.code + "." + configContent.output.file_extension,
|
||||||
|
outPath = path.join(templateOutDir, outFileName);
|
||||||
|
|
||||||
|
console.info(` [${templateConfig.name}:${pageConfig.code}] Output: ${outPath}`);
|
||||||
|
|
||||||
|
// 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(outPath, result, {
|
||||||
|
encoding: "utf8",
|
||||||
|
flag: "w+",
|
||||||
|
mode: 0o644
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!generated[templateConfig.name]) {
|
||||||
|
generated[templateConfig.name] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
generated[templateConfig.name].push({
|
||||||
|
code: pageConfig.code,
|
||||||
|
message: pageConfig.message,
|
||||||
|
description: pageConfig.description,
|
||||||
|
path: path.join(templateConfig.name, outFileName),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// Generate index page for the generated content
|
||||||
|
if (generateIndexPage === true) {
|
||||||
|
const indexPageFilePath = path.join(outDir, 'index.html');
|
||||||
|
|
||||||
|
let content = `<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||||
|
<title>Error pages list</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css"
|
||||||
|
integrity="sha512-P5MgMn1jBN01asBgU0z60Qk4QxiXo86+wlFahKrsQf37c9cro517WzVSPPV1tDKzhku2iJ2FVgL67wG03SGnNA=="
|
||||||
|
crossorigin="anonymous" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main role="main" class="container">\n`;
|
||||||
|
|
||||||
|
Object.keys(generated).forEach(function(templateName) {
|
||||||
|
content += `<h2 class="mt-5">Template name: <code>` + templateName + `</code></h2>\n<ul class="mb-5">\n`;
|
||||||
|
|
||||||
|
generated[templateName].forEach((properties) => {
|
||||||
|
content += ` <li><a href="${properties.path}"><span class="badge badge-light">${properties.code}</span>: ${properties.message}</a></li>\n`;
|
||||||
|
})
|
||||||
|
|
||||||
|
content += `</ul>\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
content += `</main>
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="container text-center text-muted mt-3 mb-3">
|
||||||
|
For online documentation and support please refer to the <a href="https://github.com/tarampampam/error-pages">project repository</a>.
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
|
||||||
|
fs.writeFileSync(indexPageFilePath, content, {
|
||||||
|
encoding: "utf8",
|
||||||
|
flag: "w+",
|
||||||
|
mode: 0o644
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
@ -5,6 +5,6 @@
|
|||||||
"url": "git://github.com/tarampampam/error-pages.git"
|
"url": "git://github.com/tarampampam/error-pages.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yargs": "15.3"
|
"yargs": "16.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
109
generator/yarn.lock
Normal file
109
generator/yarn.lock
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
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.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||||
|
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||||
|
dependencies:
|
||||||
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
|
cliui@^7.0.2:
|
||||||
|
version "7.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||||
|
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||||
|
dependencies:
|
||||||
|
string-width "^4.2.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
wrap-ansi "^7.0.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==
|
||||||
|
|
||||||
|
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==
|
||||||
|
|
||||||
|
escalade@^3.1.1:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||||
|
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||||
|
|
||||||
|
get-caller-file@^2.0.5:
|
||||||
|
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==
|
||||||
|
|
||||||
|
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=
|
||||||
|
|
||||||
|
string-width@^4.1.0, string-width@^4.2.0:
|
||||||
|
version "4.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
|
||||||
|
integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
|
||||||
|
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"
|
||||||
|
|
||||||
|
wrap-ansi@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.0.0"
|
||||||
|
string-width "^4.1.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
y18n@^5.0.5:
|
||||||
|
version "5.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||||
|
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||||
|
|
||||||
|
yargs-parser@^20.2.2:
|
||||||
|
version "20.2.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
||||||
|
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
||||||
|
|
||||||
|
yargs@16.2:
|
||||||
|
version "16.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||||
|
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||||
|
dependencies:
|
||||||
|
cliui "^7.0.2"
|
||||||
|
escalade "^3.1.1"
|
||||||
|
get-caller-file "^2.0.5"
|
||||||
|
require-directory "^2.1.1"
|
||||||
|
string-width "^4.2.0"
|
||||||
|
y18n "^5.0.5"
|
||||||
|
yargs-parser "^20.2.2"
|
@ -1,22 +0,0 @@
|
|||||||
<!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">project repository</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</body></html>
|
|
@ -1,2 +0,0 @@
|
|||||||
User-agent: *
|
|
||||||
Disallow: /
|
|
29
templates/l7-dark.html
Normal file
29
templates/l7-dark.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
|
<title>{{ message }}</title>
|
||||||
|
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
html,body {background-color: #222526;color:#fff;font-family:'Nunito',sans-serif;font-weight:100;height:100vh;margin:0}
|
||||||
|
.full-height {height:100vh}
|
||||||
|
.flex-center {align-items:center;display:flex;justify-content:center}
|
||||||
|
.position-ref {position:relative}
|
||||||
|
.code {border-right:2px solid;font-size:26px;padding:0 10px 0 15px;text-align:center}
|
||||||
|
.message {font-size:18px;text-align:center;padding:10px}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="flex-center position-ref full-height">
|
||||||
|
<div class="code">
|
||||||
|
{{ code }}
|
||||||
|
</div>
|
||||||
|
<div class="message">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
29
templates/l7-light.html
Normal file
29
templates/l7-light.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
|
<title>{{ message }}</title>
|
||||||
|
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
html,body {background-color:#fff;color:#636b6f;font-family:'Nunito',sans-serif;font-weight:100;height:100vh;margin:0}
|
||||||
|
.full-height {height:100vh}
|
||||||
|
.flex-center {align-items:center;display:flex;justify-content:center}
|
||||||
|
.position-ref {position:relative}
|
||||||
|
.code {border-right:2px solid;font-size:26px;padding:0 10px 0 15px;text-align:center}
|
||||||
|
.message {font-size:18px;text-align:center;padding:10px}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="flex-center position-ref full-height">
|
||||||
|
<div class="code">
|
||||||
|
{{ code }}
|
||||||
|
</div>
|
||||||
|
<div class="message">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
71
templates/shuffle.html
Normal file
71
templates/shuffle.html
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="robots" content="noindex, nofollow"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>{{ code }} - {{ message }}</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
background-color: #222;
|
||||||
|
color: #aaa;
|
||||||
|
font-family: 'Hack', monospace
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-height {
|
||||||
|
height: 100vh
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-center {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center
|
||||||
|
}
|
||||||
|
|
||||||
|
#error_text {
|
||||||
|
font-size: 2em
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="flex-center full-height">
|
||||||
|
<span id="error_text">{{ code }}: {{ message }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const $errorText = document.getElementById('error_text'),
|
||||||
|
text = $errorText.innerText,
|
||||||
|
characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=+<>,./?[{()}]!@#$%^&*~`\|'.split('');
|
||||||
|
let progress = 0;
|
||||||
|
|
||||||
|
const scrambleInterval = window.setInterval(function () {
|
||||||
|
let newText = text;
|
||||||
|
|
||||||
|
for (let i = 0; i < text.length; i++) {
|
||||||
|
if (i >= progress) {
|
||||||
|
newText = newText.substr(0, i) +
|
||||||
|
characters[Math.round(Math.random() * (characters.length - 1))] +
|
||||||
|
newText.substr(i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$errorText.innerText = newText;
|
||||||
|
}, 800 / 60);
|
||||||
|
|
||||||
|
window.setTimeout(function () {
|
||||||
|
let revealInterval = window.setInterval(function () {
|
||||||
|
if (progress < text.length) {
|
||||||
|
progress++;
|
||||||
|
} else {
|
||||||
|
window.clearInterval(revealInterval);
|
||||||
|
window.clearInterval(scrambleInterval);
|
||||||
|
}
|
||||||
|
}, 70);
|
||||||
|
}, 350);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
181
yarn.lock
181
yarn.lock
@ -1,181 +0,0 @@
|
|||||||
# 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"
|
|
Reference in New Issue
Block a user