mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
Source code refactored (#7)
This commit is contained in:
parent
c6aa014458
commit
515bd44e13
@ -1,3 +1,7 @@
|
|||||||
|
.dockerignore
|
||||||
|
.github
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
/generator/node_modules
|
||||||
|
/generator/*.log
|
||||||
/out
|
/out
|
||||||
/node_modules
|
|
||||||
*.log
|
|
||||||
|
42
.github/workflows/release.yml
vendored
42
.github/workflows/release.yml
vendored
@ -15,7 +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
|
||||||
|
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
@ -23,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
|
||||||
@ -68,21 +66,31 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1 # Action page: <https://github.com/docker/setup-qemu-action>
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
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
|
- name: Generate builder values
|
||||||
id: values
|
id: values
|
||||||
run: echo "::set-output name=version::${GITHUB_REF##*/[vV]}" # `/refs/tags/v1.2.3` -> `1.2.3`
|
run: echo "::set-output name=version::${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
|
- name: Build image
|
||||||
run: docker build --tag "tarampampam/error-pages:${{ steps.values.outputs.version }}" --tag "tarampampam/error-pages:latest" -f ./Dockerfile .
|
run: |
|
||||||
|
docker buildx build \
|
||||||
- name: Push version image
|
--platform "linux/amd64,linux/386,linux/arm64/v8,linux/arm/v6,linux/arm/v7" \
|
||||||
run: docker push "tarampampam/error-pages:${{ steps.values.outputs.version }}"
|
--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 \
|
||||||
|
.
|
||||||
|
37
.github/workflows/tests.yml
vendored
37
.github/workflows/tests.yml
vendored
@ -6,9 +6,25 @@ 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-20.04
|
runs-on: ubuntu-20.04
|
||||||
@ -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,13 +43,19 @@ 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
|
||||||
@ -45,8 +67,15 @@ 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
|
||||||
|
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*
|
|
||||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -4,6 +4,19 @@ 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].
|
||||||
|
|
||||||
|
## UNRELEASED
|
||||||
|
|
||||||
|
### 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/386`, `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
|
## v1.4.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
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 -e "TEMPLATE_NAME=l7-light" $(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
|
||||||
|
81
README.md
81
README.md
@ -11,45 +11,23 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
Can be used for [Traefik error pages customization](https://docs.traefik.io/middlewares/errorpages/).
|
**Can be used for [Traefik error pages customization](https://docs.traefik.io/middlewares/errorpages/)**.
|
||||||
|
|
||||||
### Demo
|
## Demo
|
||||||
|
|
||||||
Generated pages (from the latest release) always [accessible here][link_branch_gh_pages] _(sources)_ and on GitHub pages [here][link_gh_pages].
|
Generated pages (from the latest release) always [accessible here][link_branch_gh_pages] _(sources)_ and on GitHub pages **[here][link_gh_pages]** _(live preview)_.
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
> 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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Templates
|
## Templates
|
||||||
|
|
||||||
Name | Preview
|
Name | Preview
|
||||||
:--------: | :-----:
|
:--------: | :-----:
|
||||||
`ghost` | 
|
`ghost` | 
|
||||||
`l7-light` | 
|
`l7-light` | 
|
||||||
`l7-dark` | 
|
`l7-dark` | 
|
||||||
`shuffle` | 
|
`shuffle` | 
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -61,22 +39,24 @@ Name | Description
|
|||||||
--------------- | -----------
|
--------------- | -----------
|
||||||
`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`)_
|
`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:1.4.0
|
$ 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;
|
||||||
@ -102,27 +82,33 @@ 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.4.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 (tested on `v2.2.1`) 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
|
||||||
version: '3.4'
|
version: '3.4'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
error-pages:
|
error-pages:
|
||||||
image: tarampampam/error-pages:1.4.0
|
image: tarampampam/error-pages:1.5.0
|
||||||
environment:
|
environment:
|
||||||
TEMPLATE_NAME: l7-dark
|
TEMPLATE_NAME: l7-dark
|
||||||
networks:
|
networks:
|
||||||
@ -170,6 +156,28 @@ networks:
|
|||||||
external: true
|
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
|
||||||
|
|
||||||
[![Release date][badge_release_date]][link_releases]
|
[![Release date][badge_release_date]][link_releases]
|
||||||
@ -205,6 +213,7 @@ 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/
|
||||||
|
@ -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);
|
|
||||||
}
|
|
@ -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,25 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TEMPLATE_NAME=${TEMPLATE_NAME:-ghost} # 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;
|
|
||||||
|
|
||||||
# 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;
|
|
||||||
ln -f -s "/opt/html/$TEMPLATE_NAME/"* /opt/html/nginx-error-pages;
|
|
||||||
fi;
|
|
||||||
|
|
||||||
exec "$@"
|
|
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,2 +0,0 @@
|
|||||||
User-agent: *
|
|
||||||
Disallow: /
|
|
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"
|
|
Loading…
x
Reference in New Issue
Block a user