diff --git a/.dockerignore b/.dockerignore
index 9f0b60f1..d1f98f1b 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,3 +1,4 @@
*
!docker/*
+!docker_config.json
!filebrowser
\ No newline at end of file
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index a277421a..64b79919 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -24,7 +24,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
- go-version: 1.18.3
+ go-version: 1.20.6
- run: make lint-backend
lint-commits:
runs-on: ubuntu-latest
@@ -57,7 +57,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
- go-version: 1.18.3
+ go-version: 1.20.6
- run: make test-backend
test:
runs-on: ubuntu-latest
diff --git a/.goreleaser.yml b/.goreleaser.yml
index a697179f..9ca03ac4 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -57,6 +57,7 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-amd64"
extra_files:
- docker_config.json
+ - healthcheck.sh
-
dockerfile: Dockerfile
use: buildx
@@ -75,6 +76,7 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-arm64"
extra_files:
- docker_config.json
+ - healthcheck.sh
-
dockerfile: Dockerfile
use: buildx
@@ -94,6 +96,7 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-armv6"
extra_files:
- docker_config.json
+ - healthcheck.sh
-
dockerfile: Dockerfile
use: buildx
@@ -113,6 +116,7 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-armv7"
extra_files:
- docker_config.json
+ - healthcheck.sh
## s6 based docker images
-
dockerfile: Dockerfile.s6
@@ -150,82 +154,35 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-arm64-s6"
extra_files:
- docker/root
- -
- dockerfile: Dockerfile.s6.armhf
- use: buildx
- build_flag_templates:
- - "--pull"
- - "--label=org.opencontainers.image.created={{.Date}}"
- - "--label=org.opencontainers.image.name={{.ProjectName}}"
- - "--label=org.opencontainers.image.revision={{.FullCommit}}"
- - "--label=org.opencontainers.image.version={{.Version}}"
- - "--label=org.opencontainers.image.source={{.GitURL}}"
- - "--platform=linux/arm/v6"
- goos: linux
- goarch: arm
- goarm: '6'
- image_templates:
- - "filebrowser/filebrowser:{{ .Tag }}-armv6-s6"
- - "filebrowser/filebrowser:v{{ .Major }}-armv6-s6"
- extra_files:
- - docker/root
- -
- dockerfile: Dockerfile.s6.armhf
- use: buildx
- build_flag_templates:
- - "--pull"
- - "--label=org.opencontainers.image.created={{.Date}}"
- - "--label=org.opencontainers.image.name={{.ProjectName}}"
- - "--label=org.opencontainers.image.revision={{.FullCommit}}"
- - "--label=org.opencontainers.image.version={{.Version}}"
- - "--label=org.opencontainers.image.source={{.GitURL}}"
- - "--platform=linux/arm/v7"
- goos: linux
- goarch: arm
- goarm: '7'
- image_templates:
- - "filebrowser/filebrowser:{{ .Tag }}-armv7-s6"
- - "filebrowser/filebrowser:v{{ .Major }}-armv7-s6"
- extra_files:
- - docker/root
docker_manifests:
- name_template: "filebrowser/filebrowser:latest"
image_templates:
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
- - "filebrowser/filebrowser:{{ .Tag }}-armv6"
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
- name_template: "filebrowser/filebrowser:{{ .Tag }}"
image_templates:
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
- - "filebrowser/filebrowser:{{ .Tag }}-armv6"
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
- name_template: "filebrowser/filebrowser:v{{ .Major }}"
image_templates:
- "filebrowser/filebrowser:v{{ .Major }}-amd64"
- "filebrowser/filebrowser:v{{ .Major }}-arm64"
- - "filebrowser/filebrowser:v{{ .Major }}-armv6"
- "filebrowser/filebrowser:v{{ .Major }}-armv7"
## s6 image manifests
- name_template: "filebrowser/filebrowser:s6"
image_templates:
- "filebrowser/filebrowser:{{ .Tag }}-amd64-s6"
- "filebrowser/filebrowser:{{ .Tag }}-arm64-s6"
- - "filebrowser/filebrowser:{{ .Tag }}-armv6-s6"
- - "filebrowser/filebrowser:{{ .Tag }}-armv7-s6"
- name_template: "filebrowser/filebrowser:{{ .Tag }}-s6"
image_templates:
- "filebrowser/filebrowser:{{ .Tag }}-amd64-s6"
- "filebrowser/filebrowser:{{ .Tag }}-arm64-s6"
- - "filebrowser/filebrowser:{{ .Tag }}-armv6-s6"
- - "filebrowser/filebrowser:{{ .Tag }}-armv7-s6"
- name_template: "filebrowser/filebrowser:v{{ .Major }}-s6"
image_templates:
- "filebrowser/filebrowser:v{{ .Major }}-amd64-s6"
- "filebrowser/filebrowser:v{{ .Major }}-arm64-s6"
- - "filebrowser/filebrowser:v{{ .Major }}-armv6-s6"
- - "filebrowser/filebrowser:v{{ .Major }}-armv7-s6"
brews:
- name: filebrowser
tap:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca897439..3bb2d07e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,58 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+### [2.24.1](https://github.com/filebrowser/filebrowser/compare/v2.24.0...v2.24.1) (2023-07-31)
+
+
+### Bug Fixes
+
+* add directory creation code to partial upload handler ([#2575](https://github.com/filebrowser/filebrowser/issues/2575)) ([#2580](https://github.com/filebrowser/filebrowser/issues/2580)) ([912f27a](https://github.com/filebrowser/filebrowser/commit/912f27a9e3286ee4bf2a27b366a1d35b3b55799c))
+* resolved CSS rendering issue in Chrome browser ([#2582](https://github.com/filebrowser/filebrowser/issues/2582)) ([2a4a46c](https://github.com/filebrowser/filebrowser/commit/2a4a46c61a5d5376bea65b28d0eb6a7ec2fdf4e5))
+
+
+### Build
+
+* **backend:** upgrade golangci-lint to v1.53.3 ([efd41cc](https://github.com/filebrowser/filebrowser/commit/efd41cc4c147b8d2d5e61fb2642df8d934f49362))
+
+## [2.24.0](https://github.com/filebrowser/filebrowser/compare/v2.23.0...v2.24.0) (2023-07-29)
+
+
+### Features
+
+* add a healthcheck script that works with a dynamic port ([#2510](https://github.com/filebrowser/filebrowser/issues/2510)) ([ff4375c](https://github.com/filebrowser/filebrowser/commit/ff4375cf6ce849459889f892dd91304703c52dcd))
+* add a new setting that disables the display of the disk usage ([#2136](https://github.com/filebrowser/filebrowser/issues/2136)) ([428c1c6](https://github.com/filebrowser/filebrowser/commit/428c1c606d1b858ed0eb58b7c31f570bc6a9b792))
+* add Hungarian translation ([#2232](https://github.com/filebrowser/filebrowser/issues/2232)) ([11e9202](https://github.com/filebrowser/filebrowser/commit/11e92021607e12efff9fb2d5c8728483eee31199))
+* add option to copy download links from shares ([#2442](https://github.com/filebrowser/filebrowser/issues/2442)) ([a4ef02a](https://github.com/filebrowser/filebrowser/commit/a4ef02a47b53742a0ac1f639563b0c67116619c8))
+* integrate tus.io for resumable and chunked uploads ([#2145](https://github.com/filebrowser/filebrowser/issues/2145)) ([7b35815](https://github.com/filebrowser/filebrowser/commit/7b35815754690540f76e3ffe114eedb47cfd5c7e))
+
+
+### Bug Fixes
+
+* added an early return on non-existent items ([#2571](https://github.com/filebrowser/filebrowser/issues/2571)) ([2744f7d](https://github.com/filebrowser/filebrowser/commit/2744f7d5b9106c7c2eec69010e550e0939c23d80))
+* build on FreeBSD and non-Linux platforms ([#2332](https://github.com/filebrowser/filebrowser/issues/2332)) ([60d1e2d](https://github.com/filebrowser/filebrowser/commit/60d1e2d2913cce591fbee97337bd58310480269f))
+* error while using fallback of dir move ([#2349](https://github.com/filebrowser/filebrowser/issues/2349)) ([853ec90](https://github.com/filebrowser/filebrowser/commit/853ec906efbdee9013c5d34ed1d9b8fee88a6b29))
+* filter ANSI color for shell ([#2529](https://github.com/filebrowser/filebrowser/issues/2529)) ([9bcfa90](https://github.com/filebrowser/filebrowser/commit/9bcfa900f904fe683c8d9085947f57932bfe22a0))
+* goreleaser docker build ([051104b](https://github.com/filebrowser/filebrowser/commit/051104bfa061720d4402c612e61bb0fc80a946bf))
+* solve broken Docker build with alpine image ([#2486](https://github.com/filebrowser/filebrowser/issues/2486)) ([b8ee340](https://github.com/filebrowser/filebrowser/commit/b8ee3404ee480ef1fd439543ab6d46f318ff3647))
+* video preview click next or prev button subtitles not update ([#2423](https://github.com/filebrowser/filebrowser/issues/2423)) ([6744cd4](https://github.com/filebrowser/filebrowser/commit/6744cd47cef87e3a76a2190bdf123b6c2197fe6f))
+* xss vulnerability in /api/raw ([#2570](https://github.com/filebrowser/filebrowser/issues/2570)) ([#2572](https://github.com/filebrowser/filebrowser/issues/2572)) ([b508ac3](https://github.com/filebrowser/filebrowser/commit/b508ac3d4f7f0f75d6b49c99bdc661a6d2173f30))
+
+
+### Refactorings
+
+* replace username old focus logic with the autofocus attribute ([#2223](https://github.com/filebrowser/filebrowser/issues/2223)) ([2b2c108](https://github.com/filebrowser/filebrowser/commit/2b2c1085fb50ad68612ad438e527fd316d8aafee))
+
+
+### Build
+
+* **backend:** bump go version to 1.20.1 ([fa95299](https://github.com/filebrowser/filebrowser/commit/fa95299df4aa7e4c54d872e786a91ded5bdb01c1))
+* **backend:** bump go version to 1.20.6 ([9bf6b85](https://github.com/filebrowser/filebrowser/commit/9bf6b856e5411e635ba9102ff53dfe927183848e))
+* **deps-dev:** bump word-wrap from 1.2.3 to 1.2.4 in /frontend ([#2556](https://github.com/filebrowser/filebrowser/issues/2556)) ([bb34862](https://github.com/filebrowser/filebrowser/commit/bb3486286c0da112ad97456ad258ddcdfe17c154))
+* **deps:** bump minimatch from 3.0.4 to 3.1.2 in /tools ([#2561](https://github.com/filebrowser/filebrowser/issues/2561)) ([a664ba1](https://github.com/filebrowser/filebrowser/commit/a664ba1f9df45c7f6d03492c85466c5aa07c740e))
+* **deps:** bump semver from 5.7.1 to 5.7.2 in /tools ([#2546](https://github.com/filebrowser/filebrowser/issues/2546)) ([c2f1423](https://github.com/filebrowser/filebrowser/commit/c2f1423c02e4736f4c243c3164dc671879e065f3))
+* remove armv6-s6 docker target ([66dfbb3](https://github.com/filebrowser/filebrowser/commit/66dfbb303cf792b7b01650d0125d948ab8d81ddd))
+* remove armv7-s6 docker target ([4d77ce0](https://github.com/filebrowser/filebrowser/commit/4d77ce0955644551f891af3e4098c37e9cc37e40))
+
## [2.23.0](https://github.com/filebrowser/filebrowser/compare/v2.22.4...v2.23.0) (2022-11-05)
diff --git a/Dockerfile b/Dockerfile
index ab826705..40a91a06 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,10 +1,14 @@
FROM alpine:latest
RUN apk --update add ca-certificates \
mailcap \
- curl
+ curl \
+ jq
+
+COPY healthcheck.sh /healthcheck.sh
+RUN chmod +x /healthcheck.sh # Make the script executable
HEALTHCHECK --start-period=2s --interval=5s --timeout=3s \
- CMD curl -f http://localhost/health || exit 1
+ CMD /healthcheck.sh || exit 1
VOLUME /srv
EXPOSE 80
diff --git a/Dockerfile.s6 b/Dockerfile.s6
index 3208b057..233feb22 100644
--- a/Dockerfile.s6
+++ b/Dockerfile.s6
@@ -1,4 +1,4 @@
-FROM ghcr.io/linuxserver/baseimage-alpine:3.14
+FROM ghcr.io/linuxserver/baseimage-alpine:3.17
RUN apk --update add ca-certificates \
mailcap \
diff --git a/Dockerfile.s6.aarch64 b/Dockerfile.s6.aarch64
index 84319607..d7f3dcee 100644
--- a/Dockerfile.s6.aarch64
+++ b/Dockerfile.s6.aarch64
@@ -1,4 +1,4 @@
-FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.14
+FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.17
RUN apk --update add ca-certificates \
mailcap \
diff --git a/Dockerfile.s6.armhf b/Dockerfile.s6.armhf
index 5aa9af16..17bd1def 100644
--- a/Dockerfile.s6.armhf
+++ b/Dockerfile.s6.armhf
@@ -1,4 +1,4 @@
-FROM ghcr.io/linuxserver/baseimage-alpine:arm32v7-3.14
+FROM ghcr.io/linuxserver/baseimage-alpine:arm32v7-3.17
RUN apk --update add ca-certificates \
mailcap \
diff --git a/cmd/config.go b/cmd/config.go
index 59f9d352..383e93d7 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -46,6 +46,7 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.String("branding.color", "", "set the theme color")
flags.String("branding.files", "", "path to directory with images and custom styles")
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
+ flags.Bool("branding.disableUsedPercentage", true, "disable used disk percentage graph")
}
//nolint:gocyclo
@@ -148,6 +149,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Branding.DisableExternal)
+ fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage)
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color)
fmt.Fprintln(w, "\nServer:")
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
diff --git a/cmd/config_init.go b/cmd/config_init.go
index aeda8905..dd49aee4 100644
--- a/cmd/config_init.go
+++ b/cmd/config_init.go
@@ -36,9 +36,10 @@ override the options.`,
AuthLogoutURL: mustGetString(flags, "auth.logoutUrl"),
Defaults: defaults,
Branding: settings.Branding{
- Name: mustGetString(flags, "branding.name"),
- DisableExternal: mustGetBool(flags, "branding.disableExternal"),
- Files: mustGetString(flags, "branding.files"),
+ Name: mustGetString(flags, "branding.name"),
+ DisableExternal: mustGetBool(flags, "branding.disableExternal"),
+ DisableUsedPercentage: mustGetBool(flags, "branding.disableUsedPercentage"),
+ Files: mustGetString(flags, "branding.files"),
},
}
diff --git a/cmd/config_set.go b/cmd/config_set.go
index d6c8f415..e2e49c44 100644
--- a/cmd/config_set.go
+++ b/cmd/config_set.go
@@ -59,6 +59,8 @@ you want to change. Other options will remain unchanged.`,
set.Branding.Color = mustGetString(flags, flag.Name)
case "branding.disableExternal":
set.Branding.DisableExternal = mustGetBool(flags, flag.Name)
+ // case "branding.disableUsedPercentage":
+ // set.Branding.DisableUsedPercentage = mustGetBool(flags, flag.Name)
case "branding.files":
set.Branding.Files = mustGetString(flags, flag.Name)
}
diff --git a/cmd/docs.go b/cmd/docs.go
index 9ebb9573..ff104b1e 100644
--- a/cmd/docs.go
+++ b/cmd/docs.go
@@ -98,12 +98,12 @@ func generateMarkdown(cmd *cobra.Command, w io.Writer) {
buf.WriteString(long + "\n\n")
if cmd.Runnable() {
- buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine()))
+ _, _ = fmt.Fprintf(buf, "```\n%s\n```\n\n", cmd.UseLine())
}
if len(cmd.Example) > 0 {
buf.WriteString("## Examples\n\n")
- buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
+ _, _ = fmt.Fprintf(buf, "```\n%s\n```\n\n", cmd.Example)
}
printOptions(buf, cmd)
diff --git a/cmd/root.go b/cmd/root.go
index a5bf7328..aa7d705f 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -182,6 +182,7 @@ user created with the credentials from options "username" and "password".`,
defer listener.Close()
log.Println("Listening on", listener.Addr().String())
+ //nolint: gosec
if err := http.Serve(listener, handler); err != nil {
log.Fatal(err)
}
@@ -338,9 +339,13 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
},
AuthMethod: "",
Branding: settings.Branding{},
- Commands: nil,
- Shell: nil,
- Rules: nil,
+ Tus: settings.Tus{
+ ChunkSize: settings.DefaultTusChunkSize,
+ RetryCount: settings.DefaultTusRetryCount,
+ },
+ Commands: nil,
+ Shell: nil,
+ Rules: nil,
}
var err error
diff --git a/cmd/users.go b/cmd/users.go
index b47e8f4f..752b8990 100644
--- a/cmd/users.go
+++ b/cmd/users.go
@@ -53,7 +53,7 @@ func printUsers(usrs []*users.User) {
}
func parseUsernameOrID(arg string) (username string, id uint) {
- id64, err := strconv.ParseUint(arg, 10, 64) //nolint:gomnd
+ id64, err := strconv.ParseUint(arg, 10, 64)
if err != nil {
return arg, 0
}
diff --git a/common.mk b/common.mk
index 84c6175b..206fc750 100644
--- a/common.mk
+++ b/common.mk
@@ -1,4 +1,4 @@
-SHELL := /bin/bash
+SHELL := /usr/bin/env bash
DATE ?= $(shell date +%FT%T%z)
BASE_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
@@ -25,4 +25,4 @@ RESET := $(shell tput -Txterm sgr0)
define global_option
printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n" $(1) $(2)
-endef
\ No newline at end of file
+endef
diff --git a/files/file.go b/files/file.go
index c92f730b..673a26e3 100644
--- a/files/file.go
+++ b/files/file.go
@@ -23,6 +23,9 @@ import (
"github.com/filebrowser/filebrowser/v2/rules"
)
+const PermFile = 0664
+const PermDir = 0755
+
// FileInfo describes a file.
type FileInfo struct {
*Listing
@@ -201,8 +204,9 @@ func (i *FileInfo) RealPath() string {
return i.Path
}
+// TODO: use constants
+//
//nolint:goconst
-//TODO: use constants
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
if IsNamedPipe(i.Mode) {
i.Type = "blob"
diff --git a/files/listing.go b/files/listing.go
index c5a85bdd..8cc735e7 100644
--- a/files/listing.go
+++ b/files/listing.go
@@ -16,6 +16,7 @@ type Listing struct {
}
// ApplySort applies the sort order using .Order and .Sort
+//
//nolint:goconst
func (l Listing) ApplySort() {
// Check '.Order' to know how to sort
diff --git a/fileutils/file.go b/fileutils/file.go
index 1c055c50..677ae47c 100644
--- a/fileutils/file.go
+++ b/fileutils/file.go
@@ -9,7 +9,7 @@ import (
"path"
"path/filepath"
- "github.com/mholt/archiver"
+ "github.com/mholt/archiver/v3"
"github.com/spf13/afero"
)
@@ -21,18 +21,16 @@ func MoveFile(fs afero.Fs, src, dst string) error {
return nil
}
- info, err := fs.Stat(src)
- if err == nil && info.IsDir() {
+ if info, err := fs.Stat(src); err == nil && info.IsDir() {
return CopyFolder(fs, src, dst)
}
// fallback
- err = CopyFile(fs, src, dst)
- if err != nil {
+ if err := CopyFile(fs, src, dst); err != nil {
_ = fs.Remove(dst)
return err
}
- if err := fs.Remove(src); err != nil {
+ if err := fs.RemoveAll(src); err != nil {
return err
}
return nil
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index a694218e..da4f6744 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -21,6 +21,7 @@
"noty": "^3.2.0-beta",
"pretty-bytes": "^6.0.0",
"qrcode.vue": "^1.7.0",
+ "tus-js-client": "^3.1.0",
"utif": "^3.1.0",
"vue": "^2.6.10",
"vue-async-computed": "^3.9.0",
@@ -3315,10 +3316,9 @@
}
},
"node_modules/buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
- "dev": true
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"node_modules/buffer-indexof": {
"version": "1.1.1",
@@ -4088,6 +4088,15 @@
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
"dev": true
},
+ "node_modules/combine-errors": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/combine-errors/-/combine-errors-3.0.3.tgz",
+ "integrity": "sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==",
+ "dependencies": {
+ "custom-error-instance": "2.1.1",
+ "lodash.uniqby": "4.5.0"
+ }
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -5042,6 +5051,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/custom-error-instance": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz",
+ "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
+ },
"node_modules/cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
@@ -7065,8 +7079,7 @@
"node_modules/graceful-fs": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
- "dev": true
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"node_modules/gzip-size": {
"version": "5.1.1",
@@ -8847,6 +8860,46 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
+ "node_modules/lodash._baseiteratee": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz",
+ "integrity": "sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==",
+ "dependencies": {
+ "lodash._stringtopath": "~4.8.0"
+ }
+ },
+ "node_modules/lodash._basetostring": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz",
+ "integrity": "sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw=="
+ },
+ "node_modules/lodash._baseuniq": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz",
+ "integrity": "sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==",
+ "dependencies": {
+ "lodash._createset": "~4.0.0",
+ "lodash._root": "~3.0.0"
+ }
+ },
+ "node_modules/lodash._createset": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz",
+ "integrity": "sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA=="
+ },
+ "node_modules/lodash._root": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
+ "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ=="
+ },
+ "node_modules/lodash._stringtopath": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz",
+ "integrity": "sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==",
+ "dependencies": {
+ "lodash._basetostring": "~4.12.0"
+ }
+ },
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@@ -8899,6 +8952,15 @@
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
"dev": true
},
+ "node_modules/lodash.uniqby": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz",
+ "integrity": "sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==",
+ "dependencies": {
+ "lodash._baseiteratee": "~4.7.0",
+ "lodash._baseuniq": "~4.6.0"
+ }
+ },
"node_modules/log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@@ -11181,6 +11243,16 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true
},
+ "node_modules/proper-lockfile": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
+ "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "retry": "^0.12.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
@@ -11333,8 +11405,7 @@
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "dev": true
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"node_modules/randombytes": {
"version": "2.1.0",
@@ -11681,8 +11752,7 @@
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"node_modules/resolve": {
"version": "1.20.0",
@@ -11751,7 +11821,6 @@
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
- "dev": true,
"engines": {
"node": ">= 4"
}
@@ -12132,8 +12201,7 @@
"node_modules/signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
- "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
- "dev": true
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"node_modules/simple-swizzle": {
"version": "0.2.2",
@@ -13382,6 +13450,36 @@
"node": "*"
}
},
+ "node_modules/tus-js-client": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.0.tgz",
+ "integrity": "sha512-Hfpc8ho4C9Lhs/OflPUA/nHUHZJUrKD5upoPBq7dYJJ9DQhWocsjJU2RZYfN16Y5n19j9dFDszwCvVZ5sfcogw==",
+ "dependencies": {
+ "buffer-from": "^1.1.2",
+ "combine-errors": "^3.0.3",
+ "is-stream": "^2.0.0",
+ "js-base64": "^3.7.2",
+ "lodash.throttle": "^4.1.1",
+ "proper-lockfile": "^4.1.2",
+ "url-parse": "^1.5.7"
+ }
+ },
+ "node_modules/tus-js-client/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tus-js-client/node_modules/js-base64": {
+ "version": "3.7.5",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz",
+ "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA=="
+ },
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
@@ -13709,7 +13807,6 @@
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "dev": true,
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -15049,9 +15146,9 @@
"dev": true
},
"node_modules/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+ "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -18142,10 +18239,9 @@
}
},
"buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
- "dev": true
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"buffer-indexof": {
"version": "1.1.1",
@@ -18771,6 +18867,15 @@
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
"dev": true
},
+ "combine-errors": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/combine-errors/-/combine-errors-3.0.3.tgz",
+ "integrity": "sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==",
+ "requires": {
+ "custom-error-instance": "2.1.1",
+ "lodash.uniqby": "4.5.0"
+ }
+ },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -19531,6 +19636,11 @@
}
}
},
+ "custom-error-instance": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz",
+ "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
+ },
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
@@ -21146,8 +21256,7 @@
"graceful-fs": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
- "dev": true
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"gzip-size": {
"version": "5.1.1",
@@ -22521,6 +22630,46 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
+ "lodash._baseiteratee": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz",
+ "integrity": "sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==",
+ "requires": {
+ "lodash._stringtopath": "~4.8.0"
+ }
+ },
+ "lodash._basetostring": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz",
+ "integrity": "sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw=="
+ },
+ "lodash._baseuniq": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz",
+ "integrity": "sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==",
+ "requires": {
+ "lodash._createset": "~4.0.0",
+ "lodash._root": "~3.0.0"
+ }
+ },
+ "lodash._createset": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz",
+ "integrity": "sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA=="
+ },
+ "lodash._root": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
+ "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ=="
+ },
+ "lodash._stringtopath": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz",
+ "integrity": "sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==",
+ "requires": {
+ "lodash._basetostring": "~4.12.0"
+ }
+ },
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@@ -22573,6 +22722,15 @@
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
"dev": true
},
+ "lodash.uniqby": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz",
+ "integrity": "sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==",
+ "requires": {
+ "lodash._baseiteratee": "~4.7.0",
+ "lodash._baseuniq": "~4.6.0"
+ }
+ },
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@@ -24460,6 +24618,16 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true
},
+ "proper-lockfile": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
+ "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==",
+ "requires": {
+ "graceful-fs": "^4.2.4",
+ "retry": "^0.12.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
"proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
@@ -24592,8 +24760,7 @@
"querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "dev": true
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"randombytes": {
"version": "2.1.0",
@@ -24879,8 +25046,7 @@
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resolve": {
"version": "1.20.0",
@@ -24932,8 +25098,7 @@
"retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
- "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
- "dev": true
+ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
},
"rgb-regex": {
"version": "1.0.1",
@@ -25264,8 +25429,7 @@
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
- "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
- "dev": true
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"simple-swizzle": {
"version": "0.2.2",
@@ -26306,6 +26470,32 @@
"safe-buffer": "^5.0.1"
}
},
+ "tus-js-client": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.0.tgz",
+ "integrity": "sha512-Hfpc8ho4C9Lhs/OflPUA/nHUHZJUrKD5upoPBq7dYJJ9DQhWocsjJU2RZYfN16Y5n19j9dFDszwCvVZ5sfcogw==",
+ "requires": {
+ "buffer-from": "^1.1.2",
+ "combine-errors": "^3.0.3",
+ "is-stream": "^2.0.0",
+ "js-base64": "^3.7.2",
+ "lodash.throttle": "^4.1.1",
+ "proper-lockfile": "^4.1.2",
+ "url-parse": "^1.5.7"
+ },
+ "dependencies": {
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+ },
+ "js-base64": {
+ "version": "3.7.5",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz",
+ "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA=="
+ }
+ }
+ },
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
@@ -26575,7 +26765,6 @@
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "dev": true,
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -27647,9 +27836,9 @@
"dev": true
},
"word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+ "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
"dev": true
},
"worker-farm": {
diff --git a/frontend/package.json b/frontend/package.json
index 92eca16e..03412163 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -23,6 +23,7 @@
"noty": "^3.2.0-beta",
"pretty-bytes": "^6.0.0",
"qrcode.vue": "^1.7.0",
+ "tus-js-client": "^3.1.0",
"utif": "^3.1.0",
"vue": "^2.6.10",
"vue-async-computed": "^3.9.0",
diff --git a/frontend/src/api/files.js b/frontend/src/api/files.js
index 8fed246f..226cf458 100644
--- a/frontend/src/api/files.js
+++ b/frontend/src/api/files.js
@@ -1,6 +1,7 @@
import { createURL, fetchURL, removePrefix } from "./utils";
import { baseURL } from "@/utils/constants";
import store from "@/store";
+import { upload as postTus, useTus } from "./tus";
export async function fetch(url) {
url = removePrefix(url);
@@ -78,6 +79,21 @@ export function download(format, ...files) {
}
export async function post(url, content = "", overwrite = false, onupload) {
+ // Use the pre-existing API if:
+ const useResourcesApi =
+ // a folder is being created
+ url.endsWith("/") ||
+ // We're not using http(s)
+ (content instanceof Blob &&
+ !["http:", "https:"].includes(window.location.protocol)) ||
+ // Tus is disabled / not applicable
+ !(await useTus(content));
+ return useResourcesApi
+ ? postResources(url, content, overwrite, onupload)
+ : postTus(url, content, overwrite, onupload);
+}
+
+async function postResources(url, content = "", overwrite = false, onupload) {
url = removePrefix(url);
let bufferContent;
diff --git a/frontend/src/api/tus.js b/frontend/src/api/tus.js
new file mode 100644
index 00000000..bda4f40c
--- /dev/null
+++ b/frontend/src/api/tus.js
@@ -0,0 +1,90 @@
+import * as tus from "tus-js-client";
+import { baseURL, tusEndpoint, tusSettings } from "@/utils/constants";
+import store from "@/store";
+import { removePrefix } from "@/api/utils";
+import { fetchURL } from "./utils";
+
+const RETRY_BASE_DELAY = 1000;
+const RETRY_MAX_DELAY = 20000;
+
+export async function upload(
+ filePath,
+ content = "",
+ overwrite = false,
+ onupload
+) {
+ if (!tusSettings) {
+ // Shouldn't happen as we check for tus support before calling this function
+ throw new Error("Tus.io settings are not defined");
+ }
+
+ filePath = removePrefix(filePath);
+ let resourcePath = `${tusEndpoint}${filePath}?override=${overwrite}`;
+
+ await createUpload(resourcePath);
+
+ return new Promise((resolve, reject) => {
+ let upload = new tus.Upload(content, {
+ uploadUrl: `${baseURL}${resourcePath}`,
+ chunkSize: tusSettings.chunkSize,
+ retryDelays: computeRetryDelays(tusSettings),
+ parallelUploads: 1,
+ storeFingerprintForResuming: false,
+ headers: {
+ "X-Auth": store.state.jwt,
+ },
+ onError: function (error) {
+ reject("Upload failed: " + error);
+ },
+ onProgress: function (bytesUploaded) {
+ // Emulate ProgressEvent.loaded which is used by calling functions
+ // loaded is specified in bytes (https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/loaded)
+ if (typeof onupload === "function") {
+ onupload({ loaded: bytesUploaded });
+ }
+ },
+ onSuccess: function () {
+ resolve();
+ },
+ });
+ upload.start();
+ });
+}
+
+async function createUpload(resourcePath) {
+ let headResp = await fetchURL(resourcePath, {
+ method: "POST",
+ });
+ if (headResp.status !== 201) {
+ throw new Error(
+ `Failed to create an upload: ${headResp.status} ${headResp.statusText}`
+ );
+ }
+}
+
+function computeRetryDelays(tusSettings) {
+ if (!tusSettings.retryCount || tusSettings.retryCount < 1) {
+ // Disable retries altogether
+ return null;
+ }
+ // The tus client expects our retries as an array with computed backoffs
+ // E.g.: [0, 3000, 5000, 10000, 20000]
+ const retryDelays = [];
+ let delay = 0;
+
+ for (let i = 0; i < tusSettings.retryCount; i++) {
+ retryDelays.push(Math.min(delay, RETRY_MAX_DELAY));
+ delay =
+ delay === 0 ? RETRY_BASE_DELAY : Math.min(delay * 2, RETRY_MAX_DELAY);
+ }
+
+ return retryDelays;
+}
+
+export async function useTus(content) {
+ return isTusSupported() && content instanceof Blob;
+}
+
+function isTusSupported() {
+ return tus.isSupported === true;
+}
diff --git a/frontend/src/api/utils.js b/frontend/src/api/utils.js
index 87d6a243..7883c4ce 100644
--- a/frontend/src/api/utils.js
+++ b/frontend/src/api/utils.js
@@ -8,7 +8,6 @@ export async function fetchURL(url, opts, auth = true) {
opts.headers = opts.headers || {};
let { headers, ...rest } = opts;
-
let res;
try {
res = await fetch(`${baseURL}${url}`, {
diff --git a/frontend/src/components/Shell.vue b/frontend/src/components/Shell.vue
index 47c3d67c..dd5bf319 100644
--- a/frontend/src/components/Shell.vue
+++ b/frontend/src/components/Shell.vue
@@ -113,7 +113,10 @@ export default {
this.scroll();
},
() => {
- results.text = results.text.trimEnd();
+ results.text = results.text
+ // eslint-disable-next-line no-control-regex
+ .replace(/\u001b\[[0-9;]+m/g, "") // Filter ANSI color for now
+ .trimEnd();
this.canInput = true;
this.$refs.input.focus();
this.scroll();
diff --git a/frontend/src/components/Sidebar.vue b/frontend/src/components/Sidebar.vue
index 7ca6bc67..d8ad1f3b 100644
--- a/frontend/src/components/Sidebar.vue
+++ b/frontend/src/components/Sidebar.vue
@@ -110,6 +110,18 @@
+
+
+
+ {{ usage.used }} of {{ usage.total }} used
+
+
File Browser
@@ -140,16 +152,21 @@ import {
tmpDir,
trashDir,
quotaExists,
+ disableUsedPercentage,
noAuth,
authMethod,
authLogoutURL,
loginPage,
} from "@/utils/constants";
+import { files as api } from "@/api";
+import ProgressBar from "vue-simple-progress";
+import prettyBytes from "pretty-bytes";
export default {
name: "sidebar",
components: {
Quota,
+ ProgressBar,
},
computed: {
...mapState(["user"]),
@@ -166,8 +183,37 @@ export default {
noAuth: () => noAuth,
authMethod: () => authMethod,
authLogoutURL: () => authLogoutURL,
+ disableUsedPercentage: () => disableUsedPercentage,
canLogout: () => !noAuth && loginPage,
},
+ asyncComputed: {
+ usage: {
+ async get() {
+ let path = this.$route.path.endsWith("/")
+ ? this.$route.path
+ : this.$route.path + "/";
+ let usageStats = { used: 0, total: 0, usedPercentage: 0 };
+ if (this.disableUsedPercentage) {
+ return usageStats;
+ }
+ try {
+ let usage = await api.usage(path);
+ usageStats = {
+ used: prettyBytes(usage.used, { binary: true }),
+ total: prettyBytes(usage.total, { binary: true }),
+ usedPercentage: Math.round((usage.used / usage.total) * 100),
+ };
+ } catch (error) {
+ this.$showError(error);
+ }
+ return usageStats;
+ },
+ default: { used: "0 B", total: "0 B", usedPercentage: 0 },
+ shouldUpdate() {
+ return this.$router.currentRoute.path.includes("/files/");
+ },
+ },
+ },
methods: {
toRoot() {
this.$router.push({ path: "/files/" }, () => {});
diff --git a/frontend/src/components/prompts/Replace.vue b/frontend/src/components/prompts/Replace.vue
index 82ede1d6..a525bbbc 100644
--- a/frontend/src/components/prompts/Replace.vue
+++ b/frontend/src/components/prompts/Replace.vue
@@ -17,6 +17,14 @@
>
{{ $t("buttons.cancel") }}
+
+
+
+ |
|