forked from extern/homer
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
a4c1f6a37d | |||
76d30be8e3 | |||
240e3f0e87 | |||
33f75a798a | |||
a2dfffab68 |
8
.github/release.yml
vendored
8
.github/release.yml
vendored
@ -1,8 +0,0 @@
|
|||||||
changelog:
|
|
||||||
exclude:
|
|
||||||
authors:
|
|
||||||
- dependabot
|
|
||||||
categories:
|
|
||||||
- title: Main changes
|
|
||||||
labels:
|
|
||||||
- "*"
|
|
44
.github/workflows/dockerhub.yml
vendored
44
.github/workflows/dockerhub.yml
vendored
@ -1,44 +0,0 @@
|
|||||||
# Build & publish docker images
|
|
||||||
name: Dockerhub
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags: [v*]
|
|
||||||
branches: [ main ]
|
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
dockerhub:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
-
|
|
||||||
name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v2
|
|
||||||
-
|
|
||||||
name: Set up Docker Buildx
|
|
||||||
id: buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
-
|
|
||||||
name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
-
|
|
||||||
name: Set tag name
|
|
||||||
run: |
|
|
||||||
if [[ ${{ github.ref_type }} == "tag" ]]; then
|
|
||||||
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
|
|
||||||
else
|
|
||||||
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
name: Build and push
|
|
||||||
uses: docker/build-push-action@v3
|
|
||||||
with:
|
|
||||||
push: true
|
|
||||||
tags: b4bz/homer:${{env.IMAGE_TAG}}
|
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
|
2
.github/workflows/integration.yml
vendored
2
.github/workflows/integration.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
|||||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
|
24
.github/workflows/release.yml
vendored
24
.github/workflows/release.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
|||||||
name: Upload Release Asset
|
name: Upload Release Asset
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
- name: Build project
|
- name: Build project
|
||||||
run: |
|
run: |
|
||||||
yarn install
|
yarn install
|
||||||
@ -20,9 +20,21 @@ jobs:
|
|||||||
run: zip -r ../homer.zip ./*
|
run: zip -r ../homer.zip ./*
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
tag_name: ${{ github.ref }}
|
||||||
generate_release_notes: true
|
release_name: Release ${{ github.ref }}
|
||||||
files: |
|
draft: false
|
||||||
homer.zip
|
prerelease: false
|
||||||
|
- name: Upload Release Asset
|
||||||
|
id: upload-release-asset
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./homer.zip
|
||||||
|
asset_name: homer.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
|
24
Dockerfile
24
Dockerfile
@ -10,30 +10,24 @@ COPY . .
|
|||||||
RUN yarn build
|
RUN yarn build
|
||||||
|
|
||||||
# production stage
|
# production stage
|
||||||
FROM alpine:3.16
|
FROM alpine:3.15
|
||||||
|
|
||||||
ENV GID 1000
|
ENV USER darkhttpd
|
||||||
ENV UID 1000
|
ENV GROUP darkhttpd
|
||||||
|
ENV GID 911
|
||||||
|
ENV UID 911
|
||||||
ENV PORT 8080
|
ENV PORT 8080
|
||||||
ENV SUBFOLDER "/_"
|
|
||||||
ENV INIT_ASSETS 1
|
|
||||||
|
|
||||||
RUN addgroup -S lighttpd -g ${GID} && adduser -D -S -u ${UID} lighttpd lighttpd && \
|
RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \
|
||||||
apk add -U --no-cache lighttpd
|
apk add -U --no-cache su-exec darkhttpd
|
||||||
|
|
||||||
WORKDIR /www
|
COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/
|
||||||
|
COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets
|
||||||
COPY lighttpd.conf /lighttpd.conf
|
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
COPY --from=build-stage --chown=${UID}:${GID} /app/dist /www/
|
|
||||||
COPY --from=build-stage --chown=${UID}:${GID} /app/dist/assets /www/default-assets
|
|
||||||
|
|
||||||
USER ${UID}:${GID}
|
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||||
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1
|
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1
|
||||||
|
|
||||||
EXPOSE ${PORT}
|
EXPOSE ${PORT}
|
||||||
VOLUME /www/assets
|
VOLUME /www/assets
|
||||||
|
|
||||||
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
|
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
|
||||||
|
43
Dockerfile.arm32v7
Normal file
43
Dockerfile.arm32v7
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# build stage
|
||||||
|
FROM node:lts-alpine as build-stage
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
# Multi arch build support
|
||||||
|
FROM alpine as qemu
|
||||||
|
|
||||||
|
ARG QEMU_VERSION="v4.2.0-7"
|
||||||
|
|
||||||
|
RUN wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VERSION}/qemu-arm-static && chmod +x qemu-arm-static
|
||||||
|
|
||||||
|
# production stage
|
||||||
|
FROM arm32v7/alpine:3.11
|
||||||
|
|
||||||
|
COPY --from=qemu qemu-arm-static /usr/bin/
|
||||||
|
|
||||||
|
ENV USER darkhttpd
|
||||||
|
ENV GROUP darkhttpd
|
||||||
|
ENV GID 911
|
||||||
|
ENV UID 911
|
||||||
|
ENV PORT 8080
|
||||||
|
|
||||||
|
RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \
|
||||||
|
apk add -U --no-cache darkhttpd su-exec && \
|
||||||
|
rm /usr/bin/qemu-arm-static
|
||||||
|
|
||||||
|
COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/
|
||||||
|
COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1
|
||||||
|
|
||||||
|
EXPOSE ${PORT}
|
||||||
|
VOLUME /www/assets
|
||||||
|
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
|
43
Dockerfile.arm64v8
Normal file
43
Dockerfile.arm64v8
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# build stage
|
||||||
|
FROM node:lts-alpine as build-stage
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
# Multi arch build support
|
||||||
|
FROM alpine as qemu
|
||||||
|
|
||||||
|
ARG QEMU_VERSION="v4.2.0-7"
|
||||||
|
|
||||||
|
RUN wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VERSION}/qemu-aarch64-static && chmod +x qemu-aarch64-static
|
||||||
|
|
||||||
|
# production stage
|
||||||
|
FROM arm64v8/alpine:3.11
|
||||||
|
|
||||||
|
COPY --from=qemu qemu-aarch64-static /usr/bin/
|
||||||
|
|
||||||
|
ENV USER darkhttpd
|
||||||
|
ENV GROUP darkhttpd
|
||||||
|
ENV GID 911
|
||||||
|
ENV UID 911
|
||||||
|
ENV PORT 8080
|
||||||
|
|
||||||
|
RUN addgroup -S ${GROUP} -g ${GID} && adduser -D -S -u ${UID} ${USER} ${GROUP} && \
|
||||||
|
apk add -U --no-cache darkhttpd su-exec && \
|
||||||
|
rm /usr/bin/qemu-aarch64-static
|
||||||
|
|
||||||
|
COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist /www/
|
||||||
|
COPY --from=build-stage --chown=${USER}:${GROUP} /app/dist/assets /www/default-assets
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:${PORT}/ || exit 1
|
||||||
|
|
||||||
|
EXPOSE ${PORT}
|
||||||
|
VOLUME /www/assets
|
||||||
|
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
|
25
README.md
25
README.md
@ -71,6 +71,8 @@ See [documentation](docs/configuration.md) for information about the configurati
|
|||||||
|
|
||||||
### Using docker
|
### Using docker
|
||||||
|
|
||||||
|
To launch container:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-p 8080:8080 \
|
-p 8080:8080 \
|
||||||
@ -79,19 +81,12 @@ docker run -d \
|
|||||||
b4bz/homer:latest
|
b4bz/homer:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Environment variables:
|
Default assets will be automatically installed in the `/www/assets` directory. Use `UID` and/or `GID` env var to change the assets owner (`docker run -e "UID=1000" -e "GID=1000" [...]`).
|
||||||
|
|
||||||
* **`INIT_ASSETS`** (default: `1`)
|
|
||||||
Install example configuration file & assets (favicons, ...) to help you get started.
|
|
||||||
|
|
||||||
* **`SUBFOLDER`** (default: `null`)
|
|
||||||
If you would like to host Homer in a subfolder, (ex: *http://my-domain/**homer***), set this to the subfolder path (ex `/homer`).
|
|
||||||
|
|
||||||
|
|
||||||
### Using docker-compose
|
### Using docker-compose
|
||||||
|
|
||||||
The `docker-compose.yml` file must be edited to match your needs.
|
The `docker-compose.yml` file must be edited to match your needs.
|
||||||
You probably want to set the port mapping and volume binding (equivalent to `-p` and `-v` arguments):
|
Set the port and volume (equivalent to `-p` and `-v` arguments):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
volumes:
|
volumes:
|
||||||
@ -100,13 +95,21 @@ ports:
|
|||||||
- 8080:8080
|
- 8080:8080
|
||||||
```
|
```
|
||||||
|
|
||||||
Then launch the container:
|
To launch container:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd /path/to/docker-compose.yml/
|
cd /path/to/docker-compose.yml
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Default assets will be automatically installed in the `/www/assets` directory. Use `UID` and/or `GID` env var to change the assets owner, also in `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- UID=1000
|
||||||
|
- GID=1000
|
||||||
|
```
|
||||||
|
|
||||||
### Using the release tarball (prebuilt, ready to use)
|
### Using the release tarball (prebuilt, ready to use)
|
||||||
|
|
||||||
Download and extract the latest release (`homer.zip`) from the [release page](https://github.com/bastienwirtz/homer/releases), rename the `assets/config.yml.dist` file to `assets/config.yml`, and put it behind a web server.
|
Download and extract the latest release (`homer.zip`) from the [release page](https://github.com/bastienwirtz/homer/releases), rename the `assets/config.yml.dist` file to `assets/config.yml`, and put it behind a web server.
|
||||||
|
@ -10,6 +10,7 @@ services:
|
|||||||
- /your/local/assets/:/www/assets
|
- /your/local/assets/:/www/assets
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
user: 1000:1000 # default
|
#environment:
|
||||||
environment:
|
# - UID=1000
|
||||||
- INIT_ASSETS=1 # default
|
# - GID=1000
|
||||||
|
restart: unless-stopped
|
||||||
|
@ -25,8 +25,7 @@ header: true # Set to false to hide the header
|
|||||||
footer: '<p>Created with <span class="has-text-danger">❤️</span> with <a href="https://bulma.io/">bulma</a>, <a href="https://vuejs.org/">vuejs</a> & <a href="https://fontawesome.com/">font awesome</a> // Fork me on <a href="https://github.com/bastienwirtz/homer"><i class="fab fa-github-alt"></i></a></p>' # set false if you want to hide it.
|
footer: '<p>Created with <span class="has-text-danger">❤️</span> with <a href="https://bulma.io/">bulma</a>, <a href="https://vuejs.org/">vuejs</a> & <a href="https://fontawesome.com/">font awesome</a> // Fork me on <a href="https://github.com/bastienwirtz/homer"><i class="fab fa-github-alt"></i></a></p>' # set false if you want to hide it.
|
||||||
|
|
||||||
columns: "3" # "auto" or number (must be a factor of 12: 1, 2, 3, 4, 6, 12)
|
columns: "3" # "auto" or number (must be a factor of 12: 1, 2, 3, 4, 6, 12)
|
||||||
connectivityCheck: true # whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example).
|
connectivityCheck: true # whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example)
|
||||||
# You should set it to true when using an authentication proxy, it also reloads the page when a redirection is detected when checking connectivity.
|
|
||||||
|
|
||||||
# Optional: Proxy / hosting option
|
# Optional: Proxy / hosting option
|
||||||
proxy:
|
proxy:
|
||||||
@ -128,7 +127,6 @@ services:
|
|||||||
# icon: "fab fa-jenkins"
|
# icon: "fab fa-jenkins"
|
||||||
subtitle: "Bookmark example"
|
subtitle: "Bookmark example"
|
||||||
tag: "app"
|
tag: "app"
|
||||||
keywords: "self hosted reddit" # optional keyword used for searching purpose
|
|
||||||
url: "https://www.reddit.com/r/selfhosted/"
|
url: "https://www.reddit.com/r/selfhosted/"
|
||||||
target: "_blank" # optional html tag target attribute
|
target: "_blank" # optional html tag target attribute
|
||||||
- name: "Another one"
|
- name: "Another one"
|
||||||
|
@ -16,9 +16,7 @@ within Homer:
|
|||||||
+ [Prometheus](#prometheus)
|
+ [Prometheus](#prometheus)
|
||||||
+ [AdGuard Home](#adguard-home)
|
+ [AdGuard Home](#adguard-home)
|
||||||
+ [Portainer](#portainer)
|
+ [Portainer](#portainer)
|
||||||
+ [Emby / Jellyfin](#emby--jellyfin)
|
+ [Emby](#emby)
|
||||||
+ [Uptime Kuma](#uptime-kuma)
|
|
||||||
+ [Tautulli](#tautulli)
|
|
||||||
|
|
||||||
If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
|
If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
|
||||||
|
|
||||||
@ -169,7 +167,7 @@ See https://docs.portainer.io/v/ce-2.11/user/account-settings#access-tokens
|
|||||||
# - "local"
|
# - "local"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Emby / Jellyfin
|
## Emby
|
||||||
|
|
||||||
You need to set the type to Emby, provide an api key and choose which stats to show if the subtitle is disabled.
|
You need to set the type to Emby, provide an api key and choose which stats to show if the subtitle is disabled.
|
||||||
|
|
||||||
@ -181,45 +179,3 @@ You need to set the type to Emby, provide an api key and choose which stats to s
|
|||||||
apikey: "MY-SUPER-SECRET-API-KEY"
|
apikey: "MY-SUPER-SECRET-API-KEY"
|
||||||
libraryType: "music" #Choose which stats to show. Can be one of: music, series or movies.
|
libraryType: "music" #Choose which stats to show. Can be one of: music, series or movies.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Uptime Kuma
|
|
||||||
|
|
||||||
Using the Uptime Kuma service you can display info about your instance uptime right on your Homer dashboard.
|
|
||||||
|
|
||||||
The following configuration is available for the UptimeKuma service. Needs v1.13.1 or later because of the change in APIs due to [multiple status pages support](https://github.com/louislam/uptime-kuma/releases/tag/1.13.1).
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: "Uptime Kuma"
|
|
||||||
logo: "assets/tools/sample.png"
|
|
||||||
# subtitle: "A fancy self-hosted monitoring tool" # optional, if no subtitle is defined, Uptime Kuma incidents, if any, will be shown
|
|
||||||
url: "http://192.168.0.151:3001"
|
|
||||||
slug: "myCustomDashboard" # Defaults to "default" if not provided.
|
|
||||||
type: "UptimeKuma"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tautulli
|
|
||||||
|
|
||||||
The Tautulli service can allow you to show the number of currently active
|
|
||||||
streams on you Plex instance. An API key is required, and can be obtained from
|
|
||||||
the "Web Interface" section of settings on the Tautulli web UI.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: "Tautulli"
|
|
||||||
logo: "assets/tools/sample.png"
|
|
||||||
url: "http://192.168.0.151:8181"
|
|
||||||
type: "Tautulli"
|
|
||||||
apikey: "MY-SUPER-SECRET-API-KEY"
|
|
||||||
```
|
|
||||||
|
|
||||||
Because the service type and link don't necessarily have to match, you could
|
|
||||||
even make the service type Tautulli on your Plex card and provide a separate
|
|
||||||
endpoint pointing to Tautulli!
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: "Plex"
|
|
||||||
logo: "assets/tools/sample.png"
|
|
||||||
url: "http://192.168.0.151:32400/web" # Plex
|
|
||||||
endpoint: "http://192.168.0.151:8181" # Tautulli
|
|
||||||
type: "Tautulli"
|
|
||||||
apikey: "MY-SUPER-SECRET-API-KEY"
|
|
||||||
```
|
|
||||||
|
@ -17,9 +17,3 @@ To resolve this, you can either:
|
|||||||
* Host all your target service under the same domain & port.
|
* Host all your target service under the same domain & port.
|
||||||
* Modify the target server configuration so that the response of the server included following header- `Access-Control-Allow-Origin: *` (<https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests>). It might be an option in the targeted service, otherwise depending on how the service is hosted, the proxy or web server can seamlessly add it.
|
* Modify the target server configuration so that the response of the server included following header- `Access-Control-Allow-Origin: *` (<https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests>). It might be an option in the targeted service, otherwise depending on how the service is hosted, the proxy or web server can seamlessly add it.
|
||||||
* Use a cors proxy server like [`cors-container`](https://github.com/imjacobclark/cors-container), [`cors-anywhere`](https://github.com/Rob--W/cors-anywhere) or many others.
|
* Use a cors proxy server like [`cors-container`](https://github.com/imjacobclark/cors-container), [`cors-anywhere`](https://github.com/Rob--W/cors-anywhere) or many others.
|
||||||
|
|
||||||
## I am using an authentication proxy and homer says I am offline
|
|
||||||
|
|
||||||
This should be a configuration issue.
|
|
||||||
* Make sure the option `connectivityCheck` is set to `true` in configuration.
|
|
||||||
* Check your proxy configuration, the expected behavior is to redirect user using a 302 to the login page when user is not authenticated.
|
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
PERMISSION_ERROR="Check assets directory permissions & docker user or skip default assets install by setting the INIT_ASSETS env var to 0"
|
# Ensure default assets are present.
|
||||||
|
while true; do echo n; done | cp -Ri /www/default-assets/* /www/assets/ &> /dev/null
|
||||||
|
|
||||||
# Default assets & exemple configuration installation if possible.
|
# Ensure compatibility with previous version (config.yml was in the root directory)
|
||||||
if [[ "${INIT_ASSETS}" == "1" ]] && [[ ! -f "/www/config.yml" ]]; then
|
if [ -f "/www/config.yml" ]; then
|
||||||
echo "No configuration found, installing default config & assets"
|
yes n | cp -i /www/config.yml /www/assets/ &> /dev/null
|
||||||
if [[ ! -w "/www/assets/" ]]; then echo "Assets directory not writable. $PERMISSION_ERROR" && exit 1; fi
|
|
||||||
|
|
||||||
while true; do echo n; done | cp -Ri /www/default-assets/* /www/assets/ &> /dev/null
|
|
||||||
if [[ $? -ne 0 ]]; then echo "Fail to copy default assets. $PERMISSION_ERROR" && exit 1; fi
|
|
||||||
|
|
||||||
yes n | cp -i /www/default-assets/config.yml.dist /www/assets/config.yml &> /dev/null
|
|
||||||
if [[ $? -ne 0 ]]; then echo "Fail to copy default config file. $PERMISSION_ERROR" && exit 1; fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Starting webserver"
|
# Install default config if no one is available.
|
||||||
lighttpd -D -f /lighttpd.conf
|
yes n | cp -i /www/default-assets/config.yml.dist /www/assets/config.yml &> /dev/null
|
||||||
|
|
||||||
|
chown -R $UID:$GID /www/assets
|
||||||
|
exec su-exec $UID:$GID darkhttpd /www/ --no-listing --port "$PORT"
|
||||||
|
8
hooks/post_push
Normal file
8
hooks/post_push
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
IFS='-' read -r TAG string <<< "$DOCKER_TAG"
|
||||||
|
|
||||||
|
docker manifest create b4bz/homer:$TAG b4bz/homer:$TAG-amd64 b4bz/homer:$TAG-arm32v7 b4bz/homer:$TAG-arm64v8
|
||||||
|
docker manifest annotate b4bz/homer:$TAG b4bz/homer:$TAG-arm32v7 --os linux --arch arm
|
||||||
|
docker manifest annotate b4bz/homer:$TAG b4bz/homer:$TAG-arm64v8 --os linux --arch arm64 --variant v8
|
||||||
|
docker manifest push --purge b4bz/homer:$TAG
|
8
hooks/pre_build
Normal file
8
hooks/pre_build
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Update to docker-ee 18.x for manifests
|
||||||
|
apt-get -y update
|
||||||
|
apt-get -y --only-upgrade install docker-ee
|
||||||
|
# Register qemu-*-static for all supported processors except the
|
||||||
|
# current one, but also remove all registered binfmt_misc before
|
||||||
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
@ -1,10 +0,0 @@
|
|||||||
include "/etc/lighttpd/mime-types.conf"
|
|
||||||
|
|
||||||
server.port = env.PORT
|
|
||||||
server.modules = ( "mod_alias" )
|
|
||||||
server.username = "lighttpd"
|
|
||||||
server.groupname = "lighttpd"
|
|
||||||
server.document-root = "/www"
|
|
||||||
alias.url = ( env.SUBFOLDER => "/www" )
|
|
||||||
server.indexfiles = ("index.html")
|
|
||||||
server.follow-symlink = "enable"
|
|
14
package.json
14
package.json
@ -7,19 +7,19 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"bulma": "^0.9.4",
|
"bulma": "^0.9.3",
|
||||||
"core-js": "^3.22.7",
|
"core-js": "^3.21.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"lodash.merge": "^4.6.2",
|
"lodash.merge": "^4.6.2",
|
||||||
"register-service-worker": "^1.7.2",
|
"register-service-worker": "^1.7.2",
|
||||||
"vue": "^2.6.14"
|
"vue": "^2.6.14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "~4.5.17",
|
"@vue/cli-plugin-babel": "~4.5.15",
|
||||||
"@vue/cli-plugin-eslint": "~4.5.17",
|
"@vue/cli-plugin-eslint": "~4.5.15",
|
||||||
"@vue/cli-plugin-pwa": "~4.5.17",
|
"@vue/cli-plugin-pwa": "~4.5.15",
|
||||||
"@vue/cli-service": "~4.5.17",
|
"@vue/cli-service": "~4.5.15",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/eslint-config-prettier": "^6.0.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
|
@ -75,7 +75,6 @@ services:
|
|||||||
logo: "assets/tools/sample.png"
|
logo: "assets/tools/sample.png"
|
||||||
subtitle: "Bookmark example"
|
subtitle: "Bookmark example"
|
||||||
tag: "app"
|
tag: "app"
|
||||||
keywords: "self hosted reddit"
|
|
||||||
url: "https://www.reddit.com/r/selfhosted/"
|
url: "https://www.reddit.com/r/selfhosted/"
|
||||||
target: "_blank" # optional html a tag target attribute
|
target: "_blank" # optional html a tag target attribute
|
||||||
- name: "Another one"
|
- name: "Another one"
|
||||||
|
39
src/App.vue
39
src/App.vue
@ -18,10 +18,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<i v-if="config.icon" :class="config.icon"></i>
|
<i v-if="config.icon" :class="config.icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="dashboard-title">
|
||||||
class="dashboard-title"
|
|
||||||
:class="{ 'no-logo': !config.icon || !config.logo }"
|
|
||||||
>
|
|
||||||
<span class="headline">{{ config.subtitle }}</span>
|
<span class="headline">{{ config.subtitle }}</span>
|
||||||
<h1>{{ config.title }}</h1>
|
<h1>{{ config.title }}</h1>
|
||||||
</div>
|
</div>
|
||||||
@ -64,7 +61,7 @@
|
|||||||
@network-status-update="offline = $event"
|
@network-status-update="offline = $event"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<GetStarted v-if="configurationNeeded" />
|
<GetStarted v-if="loaded && !services" />
|
||||||
|
|
||||||
<div v-if="!offline">
|
<div v-if="!offline">
|
||||||
<!-- Optional messages -->
|
<!-- Optional messages -->
|
||||||
@ -72,12 +69,8 @@
|
|||||||
|
|
||||||
<!-- Horizontal layout -->
|
<!-- Horizontal layout -->
|
||||||
<div v-if="!vlayout || filter" class="columns is-multiline">
|
<div v-if="!vlayout || filter" class="columns is-multiline">
|
||||||
<template v-for="(group, groupIndex) in services">
|
<template v-for="group in services">
|
||||||
<h2
|
<h2 v-if="group.name" class="column is-full group-title">
|
||||||
v-if="group.name"
|
|
||||||
class="column is-full group-title"
|
|
||||||
:key="`header-${groupIndex}`"
|
|
||||||
>
|
|
||||||
<i v-if="group.icon" :class="['fa-fw', group.icon]"></i>
|
<i v-if="group.icon" :class="['fa-fw', group.icon]"></i>
|
||||||
<div v-else-if="group.logo" class="group-logo media-left">
|
<div v-else-if="group.logo" class="group-logo media-left">
|
||||||
<figure class="image is-48x48">
|
<figure class="image is-48x48">
|
||||||
@ -88,9 +81,10 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<Service
|
<Service
|
||||||
v-for="(item, index) in group.items"
|
v-for="(item, index) in group.items"
|
||||||
:key="`service-${groupIndex}-${index}`"
|
:key="index"
|
||||||
:item="item"
|
:item="item"
|
||||||
:proxy="config.proxy"
|
:proxy="config.proxy"
|
||||||
|
:forwarder="config.forwarder"
|
||||||
:class="['column', `is-${12 / config.columns}`]"
|
:class="['column', `is-${12 / config.columns}`]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@ -103,8 +97,8 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:class="['column', `is-${12 / config.columns}`]"
|
:class="['column', `is-${12 / config.columns}`]"
|
||||||
v-for="(group, groupIndex) in services"
|
v-for="group in services"
|
||||||
:key="groupIndex"
|
:key="group.name"
|
||||||
>
|
>
|
||||||
<h2 v-if="group.name" class="group-title">
|
<h2 v-if="group.name" class="group-title">
|
||||||
<i v-if="group.icon" :class="['fa-fw', group.icon]"></i>
|
<i v-if="group.icon" :class="['fa-fw', group.icon]"></i>
|
||||||
@ -120,6 +114,7 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
:item="item"
|
:item="item"
|
||||||
:proxy="config.proxy"
|
:proxy="config.proxy"
|
||||||
|
:forwarder="config.forwarder"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -171,7 +166,6 @@ export default {
|
|||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
loaded: false,
|
loaded: false,
|
||||||
configNotFound: false,
|
|
||||||
config: null,
|
config: null,
|
||||||
services: null,
|
services: null,
|
||||||
offline: false,
|
offline: false,
|
||||||
@ -181,11 +175,6 @@ export default {
|
|||||||
showMenu: false,
|
showMenu: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
configurationNeeded: function () {
|
|
||||||
return (this.loaded && !this.services) || this.configNotFound;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created: async function () {
|
created: async function () {
|
||||||
this.buildDashboard();
|
this.buildDashboard();
|
||||||
window.onhashchange = this.buildDashboard;
|
window.onhashchange = this.buildDashboard;
|
||||||
@ -231,9 +220,10 @@ export default {
|
|||||||
},
|
},
|
||||||
getConfig: function (path = "assets/config.yml") {
|
getConfig: function (path = "assets/config.yml") {
|
||||||
return fetch(path).then((response) => {
|
return fetch(path).then((response) => {
|
||||||
if (response.status == 404 || response.redirected) {
|
if (response.redirected) {
|
||||||
this.configNotFound = true;
|
// This allows to work with authentication proxies.
|
||||||
return {};
|
window.location.href = response.url;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@ -258,8 +248,7 @@ export default {
|
|||||||
return (
|
return (
|
||||||
item.name.toLowerCase().includes(this.filter) ||
|
item.name.toLowerCase().includes(this.filter) ||
|
||||||
(item.subtitle && item.subtitle.toLowerCase().includes(this.filter)) ||
|
(item.subtitle && item.subtitle.toLowerCase().includes(this.filter)) ||
|
||||||
(item.tag && item.tag.toLowerCase().includes(this.filter)) ||
|
(item.tag && item.tag.toLowerCase().includes(this.filter))
|
||||||
(item.keywords && item.keywords.toLowerCase().includes(this.filter))
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
navigateToFirstService: function (target) {
|
navigateToFirstService: function (target) {
|
||||||
|
@ -104,10 +104,6 @@ body {
|
|||||||
|
|
||||||
.dashboard-title {
|
.dashboard-title {
|
||||||
padding: 6px 0 0 80px;
|
padding: 6px 0 0 80px;
|
||||||
|
|
||||||
&.no-logo {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.first-line {
|
.first-line {
|
||||||
@ -167,7 +163,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#main-section {
|
#main-section {
|
||||||
padding: 0 0 2.5rem 0;
|
margin-bottom: 2rem;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
@ -289,7 +286,7 @@ body {
|
|||||||
|
|
||||||
.no-footer {
|
.no-footer {
|
||||||
#main-section {
|
#main-section {
|
||||||
padding-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
|
@ -53,3 +53,4 @@ services: []
|
|||||||
|
|
||||||
|
|
||||||
proxy: ~
|
proxy: ~
|
||||||
|
forwarder: ~
|
||||||
|
@ -17,9 +17,6 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (/t=\d+/.test(window.location.href)) {
|
|
||||||
window.history.replaceState({}, document.title, window.location.pathname);
|
|
||||||
}
|
|
||||||
let that = this;
|
let that = this;
|
||||||
this.checkOffline();
|
this.checkOffline();
|
||||||
|
|
||||||
@ -32,44 +29,15 @@ export default {
|
|||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
window.addEventListener(
|
|
||||||
"online",
|
|
||||||
function () {
|
|
||||||
that.checkOffline();
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
window.addEventListener(
|
|
||||||
"offline",
|
|
||||||
function () {
|
|
||||||
this.offline = true;
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkOffline: function () {
|
checkOffline: function () {
|
||||||
if (!navigator.onLine) {
|
|
||||||
this.offline = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// extra check to make sure we're not offline
|
|
||||||
let that = this;
|
let that = this;
|
||||||
const aliveCheckUrl = window.location.href + "?t=" + new Date().valueOf();
|
return fetch(window.location.href + "?alive", {
|
||||||
return fetch(aliveCheckUrl, {
|
|
||||||
method: "HEAD",
|
method: "HEAD",
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
redirect: "manual",
|
|
||||||
})
|
})
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
// opaqueredirect means request has been redirected, to auth provider probably
|
|
||||||
if (
|
|
||||||
(response.type === "opaqueredirect" && !response.ok) ||
|
|
||||||
[401, 403].indexOf(response.status) != -1
|
|
||||||
) {
|
|
||||||
window.location.href = aliveCheckUrl;
|
|
||||||
}
|
|
||||||
that.offline = !response.ok;
|
that.offline = !response.ok;
|
||||||
})
|
})
|
||||||
.catch(function () {
|
.catch(function () {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
class="button is-primary mt-5 has-text-weight-bold"
|
class="button is-primary mt-5 has-text-weight-bold"
|
||||||
href="https://github.com/bastienwirtz/homer/blob/main/docs/configuration.md#configuration"
|
href="https://github.com/bastienwirtz/homer/blob/main/README.md#getting-started"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Get started
|
Get started
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<component v-bind:is="component" :item="item" :proxy="proxy"></component>
|
<component
|
||||||
|
v-bind:is="component"
|
||||||
|
:item="item"
|
||||||
|
:proxy="proxy"
|
||||||
|
:forwarder="forwarder"
|
||||||
|
></component>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -10,6 +15,7 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
item: Object,
|
item: Object,
|
||||||
proxy: Object,
|
proxy: Object,
|
||||||
|
forwarder: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
component() {
|
component() {
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Generic :item="item">
|
|
||||||
<template #indicator>
|
|
||||||
<div class="notifs">
|
|
||||||
<strong
|
|
||||||
v-if="streams > 0"
|
|
||||||
class="notif playing"
|
|
||||||
:title="`${streams} active stream${streams > 1 ? 's' : ''}`"
|
|
||||||
>
|
|
||||||
{{ streams }}
|
|
||||||
</strong>
|
|
||||||
<i
|
|
||||||
v-if="error"
|
|
||||||
class="notif error fa-solid fa-triangle-exclamation"
|
|
||||||
title="Unable to fetch current status"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Generic>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import service from "@/mixins/service.js";
|
|
||||||
import Generic from "./Generic.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Tautulli",
|
|
||||||
mixins: [service],
|
|
||||||
props: {
|
|
||||||
item: Object,
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Generic,
|
|
||||||
},
|
|
||||||
data: () => ({
|
|
||||||
stats: null,
|
|
||||||
error: false,
|
|
||||||
}),
|
|
||||||
computed: {
|
|
||||||
streams: function () {
|
|
||||||
if (!this.stats) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return this.stats.stream_count;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.fetchStatus();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchStatus: async function () {
|
|
||||||
try {
|
|
||||||
const response = await this.fetch(
|
|
||||||
`/api/v2?apikey=${this.item.apikey}&cmd=get_activity`
|
|
||||||
);
|
|
||||||
this.error = false;
|
|
||||||
this.stats = response.response.data;
|
|
||||||
} catch (e) {
|
|
||||||
this.error = true;
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.notifs {
|
|
||||||
position: absolute;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
top: 0.3em;
|
|
||||||
right: 0.5em;
|
|
||||||
|
|
||||||
.notif {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.2em 0.35em;
|
|
||||||
border-radius: 0.25em;
|
|
||||||
position: relative;
|
|
||||||
margin-left: 0.3em;
|
|
||||||
font-size: 0.8em;
|
|
||||||
|
|
||||||
&.playing {
|
|
||||||
background-color: #28a9a3;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.error {
|
|
||||||
border-radius: 50%;
|
|
||||||
aspect-ratio: 1;
|
|
||||||
background-color: #e51111;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,154 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Generic :item="item">
|
|
||||||
<template #content>
|
|
||||||
<p class="title is-4">{{ item.name }}</p>
|
|
||||||
<p class="subtitle is-6">
|
|
||||||
<template v-if="item.subtitle">
|
|
||||||
{{ item.subtitle }}
|
|
||||||
</template>
|
|
||||||
<template v-else-if="status">
|
|
||||||
{{ statusMessage }}
|
|
||||||
</template>
|
|
||||||
</p>
|
|
||||||
</template>
|
|
||||||
<template #indicator>
|
|
||||||
<div v-if="status" class="status" :class="status">
|
|
||||||
{{ uptime }}%
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Generic>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import service from "@/mixins/service.js";
|
|
||||||
import Generic from "./Generic.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "UptimeKuma",
|
|
||||||
mixins: [service],
|
|
||||||
props: {
|
|
||||||
item: Object,
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Generic,
|
|
||||||
},
|
|
||||||
data: () => ({
|
|
||||||
incident: null,
|
|
||||||
heartbeat: null,
|
|
||||||
}),
|
|
||||||
computed: {
|
|
||||||
dashboard: function () {
|
|
||||||
return this.item.slug ? this.item.slug : "default";
|
|
||||||
},
|
|
||||||
status: function () {
|
|
||||||
if (!this.incident) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return this.incident.incident == null ? this.pageStatus : "bad";
|
|
||||||
},
|
|
||||||
lastHeartBeatList: function () {
|
|
||||||
let result = {};
|
|
||||||
|
|
||||||
for (let id in this.heartbeat.heartbeatList) {
|
|
||||||
let index = this.heartbeat.heartbeatList[id].length - 1;
|
|
||||||
result[id] = this.heartbeat.heartbeatList[id][index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
pageStatus: function () {
|
|
||||||
if (!this.heartbeat) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (Object.keys(this.heartbeat.heartbeatList).length === 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
let result = "good";
|
|
||||||
let hasUp = false;
|
|
||||||
for (let id in this.lastHeartBeatList) {
|
|
||||||
let beat = this.lastHeartBeatList[id];
|
|
||||||
if (beat.status == 1) {
|
|
||||||
hasUp = true;
|
|
||||||
} else {
|
|
||||||
result = "warn";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasUp) {
|
|
||||||
result = "bad";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
statusMessage: function () {
|
|
||||||
if (!this.incident) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (this.incident.incident) {
|
|
||||||
return this.incident.incident.title;
|
|
||||||
}
|
|
||||||
return this.pageStatus == "warn"
|
|
||||||
? "Partially Degraded Service"
|
|
||||||
: "All Systems Operational";
|
|
||||||
},
|
|
||||||
uptime: function () {
|
|
||||||
if (!this.heartbeat) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const data = Object.values(this.heartbeat.uptimeList);
|
|
||||||
const percent = data.reduce((a, b) => a + b, 0) / data.length || 0;
|
|
||||||
return (percent * 100).toFixed(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.item.url = `${this.item.url}/status/${this.dashboard}`;
|
|
||||||
this.fetchStatus();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchStatus: function () {
|
|
||||||
this.fetch(`/api/status-page/${this.dashboard}?cachebust=${Date.now()}`)
|
|
||||||
.catch((e) => console.error(e))
|
|
||||||
.then((resp) => (this.incident = resp));
|
|
||||||
|
|
||||||
this.fetch(
|
|
||||||
`/api/status-page/heartbeat/${this.dashboard}?cachebust=${Date.now()}`
|
|
||||||
)
|
|
||||||
.catch((e) => console.error(e))
|
|
||||||
.then((resp) => (this.heartbeat = resp));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.status {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--text-title);
|
|
||||||
|
|
||||||
&.good:before {
|
|
||||||
background-color: #94e185;
|
|
||||||
border-color: #78d965;
|
|
||||||
box-shadow: 0 0 5px 1px #94e185;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.warn:before {
|
|
||||||
background-color: #f8a306;
|
|
||||||
border-color: #e1b35e;
|
|
||||||
box-shadow: 0 0 5px 1px #f8a306;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bad:before {
|
|
||||||
background-color: #c9404d;
|
|
||||||
border-color: #c42c3b;
|
|
||||||
box-shadow: 0 0 5px 1px #c9404d;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: " ";
|
|
||||||
display: inline-block;
|
|
||||||
width: 7px;
|
|
||||||
height: 7px;
|
|
||||||
margin-right: 10px;
|
|
||||||
border: 1px solid #000;
|
|
||||||
border-radius: 7px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,6 +1,9 @@
|
|||||||
|
const merge = require("lodash.merge");
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
proxy: Object,
|
proxy: Object,
|
||||||
|
forwarder: Object,
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
// custom service often consume info from an API using the item link (url) as a base url,
|
// custom service often consume info from an API using the item link (url) as a base url,
|
||||||
@ -25,18 +28,28 @@ export default {
|
|||||||
this.item.useCredentials === true ? "include" : "omit";
|
this.item.useCredentials === true ? "include" : "omit";
|
||||||
}
|
}
|
||||||
|
|
||||||
options = Object.assign(options, init);
|
if (this.forwarder?.apikey) {
|
||||||
|
options.headers = {
|
||||||
|
"X-Homer-Forwarder-Api-Key": this.forwarder.apikey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (path.startsWith("/")) {
|
if (path.startsWith("/")) {
|
||||||
path = path.slice(1);
|
path = path.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = this.endpoint;
|
let url = path ? `${this.endpoint}/${path}` : this.endpoint;
|
||||||
|
|
||||||
if (path) {
|
if (this.forwarder?.url) {
|
||||||
url = `${this.endpoint}/${path}`;
|
options.headers = {
|
||||||
|
...(options.headers || {}),
|
||||||
|
"X-Homer-Forwarder-Url": url,
|
||||||
|
};
|
||||||
|
url = this.forwarder.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options = merge(options, init);
|
||||||
|
|
||||||
return fetch(url, options).then((response) => {
|
return fetch(url, options).then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("Not 2xx response");
|
throw new Error("Not 2xx response");
|
||||||
|
@ -26,7 +26,4 @@ module.exports = {
|
|||||||
msTileImage: "assets/icons/icon-any.png",
|
msTileImage: "assets/icons/icon-any.png",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
devServer: {
|
|
||||||
disableHostCheck: true,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
162
yarn.lock
162
yarn.lock
@ -2,15 +2,6 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@achrinza/node-ipc@9.2.2":
|
|
||||||
version "9.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@achrinza/node-ipc/-/node-ipc-9.2.2.tgz#ae1b5d3d6a9362034eea60c8d946b93893c2e4ec"
|
|
||||||
integrity sha512-b90U39dx0cU6emsOvy5hxU4ApNXnE3+Tuo8XQZfiKTGelDwpMwBVgBP7QX6dGTcJgu/miyJuNJ/2naFBliNWEw==
|
|
||||||
dependencies:
|
|
||||||
"@node-ipc/js-queue" "2.0.3"
|
|
||||||
event-pubsub "4.3.0"
|
|
||||||
js-message "1.0.7"
|
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5":
|
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5":
|
||||||
version "7.14.5"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
|
||||||
@ -912,10 +903,10 @@
|
|||||||
"@babel/helper-validator-identifier" "^7.14.5"
|
"@babel/helper-validator-identifier" "^7.14.5"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@fortawesome/fontawesome-free@^6.1.1":
|
"@fortawesome/fontawesome-free@^5.15.4":
|
||||||
version "6.1.1"
|
version "5.15.4"
|
||||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1"
|
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5"
|
||||||
integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg==
|
integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==
|
||||||
|
|
||||||
"@hapi/address@2.x.x":
|
"@hapi/address@2.x.x":
|
||||||
version "2.1.4"
|
version "2.1.4"
|
||||||
@ -966,13 +957,6 @@
|
|||||||
call-me-maybe "^1.0.1"
|
call-me-maybe "^1.0.1"
|
||||||
glob-to-regexp "^0.3.0"
|
glob-to-regexp "^0.3.0"
|
||||||
|
|
||||||
"@node-ipc/js-queue@2.0.3":
|
|
||||||
version "2.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@node-ipc/js-queue/-/js-queue-2.0.3.tgz#ac7fe33d766fa53e233ef8fedaf3443a01c5a4cd"
|
|
||||||
integrity sha512-fL1wpr8hhD5gT2dA1qifeVaoDFlQR5es8tFuKqjHX+kdOtdNHnxkVZbtIrR2rxnMFvehkjaZRNV2H/gPXlb0hw==
|
|
||||||
dependencies:
|
|
||||||
easy-stack "1.0.1"
|
|
||||||
|
|
||||||
"@nodelib/fs.stat@^1.1.2":
|
"@nodelib/fs.stat@^1.1.2":
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
||||||
@ -1189,10 +1173,10 @@
|
|||||||
lodash.kebabcase "^4.1.1"
|
lodash.kebabcase "^4.1.1"
|
||||||
svg-tags "^1.0.0"
|
svg-tags "^1.0.0"
|
||||||
|
|
||||||
"@vue/babel-preset-app@^4.5.17":
|
"@vue/babel-preset-app@^4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-4.5.17.tgz#09c64eedfe868bfa3121fc12a59138518f830bde"
|
resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-4.5.15.tgz#f6bc08f8f674e98a260004234cde18b966d72eb0"
|
||||||
integrity sha512-iFv9J3F5VKUPcbx+TqW5qhGmAVyXQxPRpKpPOuTLFIVTzg+iwJnrqVbL4kJU5ECGDxPESW2oCVgxv9bTlDPu7w==
|
integrity sha512-J+YttzvwRfV1BPczf8r3qCevznYk+jh531agVF+5EYlHF4Sgh/cGXTz9qkkiux3LQgvhEGXgmCteg1n38WuuKg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.11.0"
|
"@babel/core" "^7.11.0"
|
||||||
"@babel/helper-compilation-targets" "^7.9.6"
|
"@babel/helper-compilation-targets" "^7.9.6"
|
||||||
@ -1274,61 +1258,61 @@
|
|||||||
"@vue/babel-plugin-transform-vue-jsx" "^1.2.1"
|
"@vue/babel-plugin-transform-vue-jsx" "^1.2.1"
|
||||||
camelcase "^5.0.0"
|
camelcase "^5.0.0"
|
||||||
|
|
||||||
"@vue/cli-overlay@^4.5.17":
|
"@vue/cli-overlay@^4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-4.5.17.tgz#4e0e24b7c3b71ff86de86f532821fd3abb48d10c"
|
resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-4.5.15.tgz#0700fd6bad39336d4189ba3ff7d25e638e818c9c"
|
||||||
integrity sha512-QKKp66VbMg+X8Qh0wgXSwgxLfxY7EIkZkV6bZ6nFqBx8xtaJQVDbTL+4zcUPPA6nygbIcQ6gvTinNEqIqX6FUQ==
|
integrity sha512-0zI0kANAVmjFO2LWGUIzdGPMeE3+9k+KeRDXsUqB30YfRF7abjfiiRPq5BU9pOzlJbVdpRkisschBrvdJqDuDg==
|
||||||
|
|
||||||
"@vue/cli-plugin-babel@~4.5.17":
|
"@vue/cli-plugin-babel@~4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.17.tgz#8c468e32ef6546f843201770a294bf599689e004"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.15.tgz#ae4fb2ed54255fe3d84df381dab68509641179ed"
|
||||||
integrity sha512-6kZuc3PdoUvGAnndUq6+GqjIXn3bqdTR8lOcAb1BH2b4N7IKGlmzcipALGS23HLVMAvDgNuUS7vf0unin9j2cg==
|
integrity sha512-hBLrwYfFkHldEe34op/YNgPhpOWI5n5DB2Qt9I/1Epeif4M4iFaayrgjvOR9AVM6WbD3Yx7WCFszYpWrQZpBzQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.11.0"
|
"@babel/core" "^7.11.0"
|
||||||
"@vue/babel-preset-app" "^4.5.17"
|
"@vue/babel-preset-app" "^4.5.15"
|
||||||
"@vue/cli-shared-utils" "^4.5.17"
|
"@vue/cli-shared-utils" "^4.5.15"
|
||||||
babel-loader "^8.1.0"
|
babel-loader "^8.1.0"
|
||||||
cache-loader "^4.1.0"
|
cache-loader "^4.1.0"
|
||||||
thread-loader "^2.1.3"
|
thread-loader "^2.1.3"
|
||||||
webpack "^4.0.0"
|
webpack "^4.0.0"
|
||||||
|
|
||||||
"@vue/cli-plugin-eslint@~4.5.17":
|
"@vue/cli-plugin-eslint@~4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.5.17.tgz#7667bf87bdfdb39faeb3baed58657622354a17bc"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.5.15.tgz#5781824a941f34c26336a67b1f6584a06c6a24ff"
|
||||||
integrity sha512-bVNDP+SuWcuJrBMc+JLaKvlxx25XKIlZBa+zzFnxhHZlwPZ7CeBD3e2wnsygJyPoKgDZcZwDgmEz1BZzMEjsNw==
|
integrity sha512-/2Fl6wY/5bz3HD035oSnFRMsKNxDxU396KqBdpCQdwdvqk4mm6JAbXqihpcBRTNPeTO6w+LwGe6FE56PVbJdbg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/cli-shared-utils" "^4.5.17"
|
"@vue/cli-shared-utils" "^4.5.15"
|
||||||
eslint-loader "^2.2.1"
|
eslint-loader "^2.2.1"
|
||||||
globby "^9.2.0"
|
globby "^9.2.0"
|
||||||
inquirer "^7.1.0"
|
inquirer "^7.1.0"
|
||||||
webpack "^4.0.0"
|
webpack "^4.0.0"
|
||||||
yorkie "^2.0.0"
|
yorkie "^2.0.0"
|
||||||
|
|
||||||
"@vue/cli-plugin-pwa@~4.5.17":
|
"@vue/cli-plugin-pwa@~4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-pwa/-/cli-plugin-pwa-4.5.17.tgz#73b2f9dd1203de46761a9843e972966e2717fe87"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-pwa/-/cli-plugin-pwa-4.5.15.tgz#eb800c418d96b496deec9d063a1798fe6e9c2db8"
|
||||||
integrity sha512-IaODWmj5eQjv97ne0CTOgPZA8QmVS7zYX64C+SivWPw0uevJAhNUdDHgyrUODP7fEfyufKliStLMQJTowohGNQ==
|
integrity sha512-yQzsspaIkjeQyN6btF8ATgbJFU023q1HC8uUpmiBa4QE9EyBlR8fSrKFhcJ0EmT6KnU7PMwlnOJ/OqjguFnufA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/cli-shared-utils" "^4.5.17"
|
"@vue/cli-shared-utils" "^4.5.15"
|
||||||
webpack "^4.0.0"
|
webpack "^4.0.0"
|
||||||
workbox-webpack-plugin "^4.3.1"
|
workbox-webpack-plugin "^4.3.1"
|
||||||
|
|
||||||
"@vue/cli-plugin-router@^4.5.17":
|
"@vue/cli-plugin-router@^4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-router/-/cli-plugin-router-4.5.17.tgz#9de189a7a8740817cde2a4e57aade14552ff68c3"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-router/-/cli-plugin-router-4.5.15.tgz#1e75c8c89df42c694f143b9f1028de3cf5d61e1e"
|
||||||
integrity sha512-9r9CSwqv2+39XHQPDZJ0uaTtTP7oe0Gx17m7kBhHG3FA7R7AOSk2aVzhHZmDRhzlOxjx9kQSvrOSMfUG0kV4dQ==
|
integrity sha512-q7Y6kP9b3k55Ca2j59xJ7XPA6x+iSRB+N4ac0ZbcL1TbInVQ4j5wCzyE+uqid40hLy4fUdlpl4X9fHJEwuVxPA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/cli-shared-utils" "^4.5.17"
|
"@vue/cli-shared-utils" "^4.5.15"
|
||||||
|
|
||||||
"@vue/cli-plugin-vuex@^4.5.17":
|
"@vue/cli-plugin-vuex@^4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.17.tgz#eb6f597c775f3c847bf5a638ad65a0d03c11dcbf"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.15.tgz#466c1f02777d02fef53a9bb49a36cc3a3bcfec4e"
|
||||||
integrity sha512-ck/ju2T2dmPKLWK/5QctNJs9SCb+eSZbbmr8neFkMc7GlbXw6qLWw5v3Vpd4KevdQA8QuQOA1pjUmzpCiU/mYQ==
|
integrity sha512-fqap+4HN+w+InDxlA3hZTOGE0tzBTgXhKLoDydhywqgmhQ1D9JA6Feh94ze6tG8DsWX58/ujYUqA8jAz17FJtg==
|
||||||
|
|
||||||
"@vue/cli-service@~4.5.17":
|
"@vue/cli-service@~4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-4.5.17.tgz#6f796056363b70b69065d95815ac170b7772d0c6"
|
resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-4.5.15.tgz#0e9a186d51550027d0e68e95042077eb4d115b45"
|
||||||
integrity sha512-MqfkRYIcIUACe3nYlzNrYstJTWRXHlIqh6JCkbWbdnXWN+IfaVdlG8zw5Q0DVcSdGvkevUW7zB4UhtZB4uyAcA==
|
integrity sha512-sFWnLYVCn4zRfu45IcsIE9eXM0YpDV3S11vlM2/DVbIPAGoYo5ySpSof6aHcIvkeGsIsrHFpPHzNvDZ/efs7jA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@intervolga/optimize-cssnano-plugin" "^1.0.5"
|
"@intervolga/optimize-cssnano-plugin" "^1.0.5"
|
||||||
"@soda/friendly-errors-webpack-plugin" "^1.7.1"
|
"@soda/friendly-errors-webpack-plugin" "^1.7.1"
|
||||||
@ -1336,10 +1320,10 @@
|
|||||||
"@types/minimist" "^1.2.0"
|
"@types/minimist" "^1.2.0"
|
||||||
"@types/webpack" "^4.0.0"
|
"@types/webpack" "^4.0.0"
|
||||||
"@types/webpack-dev-server" "^3.11.0"
|
"@types/webpack-dev-server" "^3.11.0"
|
||||||
"@vue/cli-overlay" "^4.5.17"
|
"@vue/cli-overlay" "^4.5.15"
|
||||||
"@vue/cli-plugin-router" "^4.5.17"
|
"@vue/cli-plugin-router" "^4.5.15"
|
||||||
"@vue/cli-plugin-vuex" "^4.5.17"
|
"@vue/cli-plugin-vuex" "^4.5.15"
|
||||||
"@vue/cli-shared-utils" "^4.5.17"
|
"@vue/cli-shared-utils" "^4.5.15"
|
||||||
"@vue/component-compiler-utils" "^3.1.2"
|
"@vue/component-compiler-utils" "^3.1.2"
|
||||||
"@vue/preload-webpack-plugin" "^1.1.0"
|
"@vue/preload-webpack-plugin" "^1.1.0"
|
||||||
"@vue/web-component-wrapper" "^1.2.0"
|
"@vue/web-component-wrapper" "^1.2.0"
|
||||||
@ -1388,17 +1372,17 @@
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vue-loader-v16 "npm:vue-loader@^16.1.0"
|
vue-loader-v16 "npm:vue-loader@^16.1.0"
|
||||||
|
|
||||||
"@vue/cli-shared-utils@^4.5.17":
|
"@vue/cli-shared-utils@^4.5.15":
|
||||||
version "4.5.17"
|
version "4.5.15"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-4.5.17.tgz#bb4aac8b816036cf5c0adf3af3cc1cb9c425501e"
|
resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-4.5.15.tgz#dba3858165dbe3465755f256a4890e69084532d6"
|
||||||
integrity sha512-VoFNdxvTW4vZu3ne+j1Mf7mU99J2SAoRVn9XPrsouTUUJablglM8DASk7Ixhsh6ymyL/W9EADQFR6Pgj8Ujjuw==
|
integrity sha512-SKaej9hHzzjKSOw1NlFmc6BSE0vcqUQMQiv1cxQ2DhVyy4QxZXBmzmiLBUBe+hYZZs1neXW7n//udeN9bCAY+Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@achrinza/node-ipc" "9.2.2"
|
|
||||||
"@hapi/joi" "^15.0.1"
|
"@hapi/joi" "^15.0.1"
|
||||||
chalk "^2.4.2"
|
chalk "^2.4.2"
|
||||||
execa "^1.0.0"
|
execa "^1.0.0"
|
||||||
launch-editor "^2.2.1"
|
launch-editor "^2.2.1"
|
||||||
lru-cache "^5.1.1"
|
lru-cache "^5.1.1"
|
||||||
|
node-ipc "^9.1.1"
|
||||||
open "^6.3.0"
|
open "^6.3.0"
|
||||||
ora "^3.4.0"
|
ora "^3.4.0"
|
||||||
read-pkg "^5.1.1"
|
read-pkg "^5.1.1"
|
||||||
@ -1839,9 +1823,9 @@ async-limiter@~1.0.0:
|
|||||||
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
||||||
|
|
||||||
async@^2.6.2:
|
async@^2.6.2:
|
||||||
version "2.6.4"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
|
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
|
||||||
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
|
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.14"
|
lodash "^4.17.14"
|
||||||
|
|
||||||
@ -2226,10 +2210,10 @@ builtin-status-codes@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
||||||
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
|
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
|
||||||
|
|
||||||
bulma@^0.9.4:
|
bulma@^0.9.3:
|
||||||
version "0.9.4"
|
version "0.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.4.tgz#0ca8aeb1847a34264768dba26a064c8be72674a1"
|
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.3.tgz#ddccb7436ebe3e21bf47afe01d3c43a296b70243"
|
||||||
integrity sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==
|
integrity sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==
|
||||||
|
|
||||||
bytes@3.0.0:
|
bytes@3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
@ -2789,10 +2773,10 @@ core-js@^2.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-js@^3.22.7:
|
core-js@^3.21.1:
|
||||||
version "3.22.7"
|
version "3.21.1"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.7.tgz#8d6c37f630f6139b8732d10f2c114c3f1d00024f"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94"
|
||||||
integrity sha512-Jt8SReuDKVNZnZEzyEQT5eK6T2RRCXkfTq7Lo09kpm+fHjgGewSbNjV+Wt4yZMhPDdzz2x1ulI5z/w4nxpBseg==
|
integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==
|
||||||
|
|
||||||
core-js@^3.6.5:
|
core-js@^3.6.5:
|
||||||
version "3.15.2"
|
version "3.15.2"
|
||||||
@ -3355,7 +3339,7 @@ duplexify@^3.4.2, duplexify@^3.6.0:
|
|||||||
readable-stream "^2.0.0"
|
readable-stream "^2.0.0"
|
||||||
stream-shift "^1.0.0"
|
stream-shift "^1.0.0"
|
||||||
|
|
||||||
easy-stack@1.0.1:
|
easy-stack@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066"
|
resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066"
|
||||||
integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==
|
integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==
|
||||||
@ -3678,9 +3662,9 @@ events@^3.0.0:
|
|||||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||||
|
|
||||||
eventsource@^1.0.7:
|
eventsource@^1.0.7:
|
||||||
version "1.1.1"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.1.tgz#4544a35a57d7120fba4fa4c86cb4023b2c09df2f"
|
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf"
|
||||||
integrity sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA==
|
integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==
|
||||||
dependencies:
|
dependencies:
|
||||||
original "^1.0.0"
|
original "^1.0.0"
|
||||||
|
|
||||||
@ -5082,6 +5066,13 @@ js-message@1.0.7:
|
|||||||
resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47"
|
resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47"
|
||||||
integrity sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==
|
integrity sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==
|
||||||
|
|
||||||
|
js-queue@2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/js-queue/-/js-queue-2.0.2.tgz#0be590338f903b36c73d33c31883a821412cd482"
|
||||||
|
integrity sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==
|
||||||
|
dependencies:
|
||||||
|
easy-stack "^1.0.1"
|
||||||
|
|
||||||
js-tokens@^4.0.0:
|
js-tokens@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||||
@ -5754,6 +5745,15 @@ node-forge@^0.10.0:
|
|||||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||||
integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
|
integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
|
||||||
|
|
||||||
|
node-ipc@^9.1.1:
|
||||||
|
version "9.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.2.1.tgz#b32f66115f9d6ce841dc4ec2009d6a733f98bb6b"
|
||||||
|
integrity sha512-mJzaM6O3xHf9VT8BULvJSbdVbmHUKRNOH7zDDkCrA1/T+CVjq2WVIDfLt0azZRXpgArJtl3rtmEozrbXPZ9GaQ==
|
||||||
|
dependencies:
|
||||||
|
event-pubsub "4.3.0"
|
||||||
|
js-message "1.0.7"
|
||||||
|
js-queue "2.0.2"
|
||||||
|
|
||||||
node-libs-browser@^2.2.1:
|
node-libs-browser@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
||||||
|
Reference in New Issue
Block a user