Add v16.8.0
This commit is contained in:
parent
c8bebd95ef
commit
9746248c10
@ -3,6 +3,8 @@
|
||||
/data/**
|
||||
/test/**
|
||||
Dockerfile*
|
||||
CHANGELOG.md
|
||||
README.md
|
||||
*.md
|
||||
.github/*
|
||||
.github_build/*
|
||||
|
||||
11
CHANGELOG.md
Normal file
11
CHANGELOG.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Core
|
||||
|
||||
#### Core v16.7.2 > v16.8.0
|
||||
|
||||
- Add purge_on_delete function
|
||||
- Mod updated dependencies
|
||||
- Mod updated API docs
|
||||
- Fix disabled session logging
|
||||
- Fix FFmpeg skills reload
|
||||
- Fix ignores processes with invalid references (thx Patron Ramakrishna Chillara)
|
||||
- Fix code scanning alerts
|
||||
@ -1,28 +1,14 @@
|
||||
ARG GOLANG_IMAGE=golang:1.18.2-alpine3.15
|
||||
ARG CORE_IMAGE=datarhei/base:alpine-core-latest
|
||||
|
||||
ARG FFMPEG_IMAGE=datarhei/base:alpine-ffmpeg-3.15-4.4.2
|
||||
ARG FFMPEG_IMAGE=datarhei/base:alpine-ffmpeg-latest
|
||||
|
||||
FROM $GOLANG_IMAGE as builder
|
||||
|
||||
COPY . /dist/core
|
||||
|
||||
RUN apk add \
|
||||
git \
|
||||
make && \
|
||||
cd /dist/core && \
|
||||
go version && \
|
||||
make release && \
|
||||
make import
|
||||
FROM $CORE_IMAGE as core
|
||||
|
||||
FROM $FFMPEG_IMAGE
|
||||
|
||||
COPY --from=builder /dist/core/core /core/bin/core
|
||||
COPY --from=builder /dist/core/import /core/bin/import
|
||||
COPY --from=builder /dist/core/mime.types /core/mime.types
|
||||
COPY --from=builder /dist/core/run.sh /core/bin/run.sh
|
||||
COPY --from=core /core /core
|
||||
|
||||
RUN ffmpeg -buildconf && \
|
||||
mkdir /core/config /core/data
|
||||
RUN ffmpeg -buildconf
|
||||
|
||||
ENV CORE_CONFIGFILE=/core/config/config.json
|
||||
ENV CORE_STORAGE_DISK_DIR=/core/data
|
||||
|
||||
18
Jenkinsfile
vendored
18
Jenkinsfile
vendored
@ -1,18 +0,0 @@
|
||||
pipeline {
|
||||
agent any
|
||||
triggers {
|
||||
cron('H 0 * * 6')
|
||||
}
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr: '5'))
|
||||
}
|
||||
stages {
|
||||
stage('Build AMD64') {
|
||||
steps {
|
||||
sh 'docker build -f Dockerfile -t docker-registry.marathon.l4lb.thisdcos.directory:5000/core:amd64 .'
|
||||
sh 'docker push docker-registry.marathon.l4lb.thisdcos.directory:5000/core:amd64'
|
||||
sh 'docker rmi docker-registry.marathon.l4lb.thisdcos.directory:5000/core:amd64'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2020 FOSS GmbH
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
9
Makefile
9
Makefile
@ -8,7 +8,7 @@ all: build
|
||||
|
||||
## build: Build core (default)
|
||||
build:
|
||||
go build -o core$(OSARCH)
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=${OSARCH} go build -o core${OSARCH}
|
||||
|
||||
## swagger: Update swagger API documentation (requires github.com/swaggo/swag)
|
||||
swagger:
|
||||
@ -34,6 +34,7 @@ fmt:
|
||||
update:
|
||||
go get -u
|
||||
@-$(MAKE) tidy
|
||||
@-$(MAKE) vendor
|
||||
|
||||
## tidy: Tidy up go.mod
|
||||
tidy:
|
||||
@ -53,7 +54,7 @@ lint:
|
||||
|
||||
## import: Build import binary
|
||||
import:
|
||||
cd app/import && go build -o ../../import -ldflags="-s -w"
|
||||
cd app/import && CGO_ENABLED=0 GOOS=linux GOARCH=${OSARCH} go build -o ../../import -ldflags="-s -w"
|
||||
|
||||
## coverage: Generate code coverage analysis
|
||||
coverage:
|
||||
@ -66,13 +67,13 @@ commit: vet fmt lint test build
|
||||
|
||||
## release: Build a release binary of core
|
||||
release:
|
||||
go build -o core -ldflags="-s -w -X github.com/datarhei/core/app.Commit=$(COMMIT) -X github.com/datarhei/core/app.Branch=$(BRANCH) -X github.com/datarhei/core/app.Build=$(BUILD)"
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=${OSARCH} go build -o core -ldflags="-s -w -X github.com/datarhei/core/app.Commit=$(COMMIT) -X github.com/datarhei/core/app.Branch=$(BRANCH) -X github.com/datarhei/core/app.Build=$(BUILD)"
|
||||
|
||||
## docker: Build standard Docker image
|
||||
docker:
|
||||
docker build -t core:$(SHORTCOMMIT) .
|
||||
|
||||
.PHONY: help build swagger test vet fmt vendor commit coverage lint release import
|
||||
.PHONY: help build swagger test vet fmt vendor commit coverage lint release import update
|
||||
|
||||
## help: Show all commands
|
||||
help: Makefile
|
||||
|
||||
45
README.md
45
README.md
@ -1,24 +1,24 @@
|
||||
# Core
|
||||
|
||||
The cloud-native a/v media processor.
|
||||
The cloud-native audio/video processing API.
|
||||
|
||||
datarhei Core is management for FFmpeg processes without development effort. It is a central interface for mapping AV processes, is responsible for design and management, and provides all necessary interfaces to access the video content. The included control for FFmpeg can keep all used functions reliable and executable without the need for software developers to take care of it. In addition, process and resource limitation for all FFmpeg processes protects the host system from application overload. The overall system gives access to current process values (CPU, RAM) and complete control of system resources and loads with statistical access to process data and current and historical logs.
|
||||
|
||||
## Features
|
||||
|
||||
- Unrestricted FFmpeg process management
|
||||
- Optimized for long-running tasks
|
||||
- In-Memory- and Disk-Filesystem for media assets
|
||||
- HTTP and RTMP services
|
||||
- Let's Encrypt for HTTPS and RTMPS
|
||||
- HLS/DASH Session tracking with bandwidth and current viewer limiters
|
||||
- Multiple resource limiters and monitoring
|
||||
- FFmpeg progress data
|
||||
- Metrics incl. Prometheus support
|
||||
- Logging and debugging for FFmpeg processes with history
|
||||
- Multiple auth. by JWT and Auth0
|
||||
- 100% JSON REST API (Swagger documented)
|
||||
- GraphQL for metrics, process, and progress data
|
||||
- Unrestricted FFmpeg process management
|
||||
- Optimized for long-running tasks
|
||||
- In-Memory- and Disk-Filesystem for media assets
|
||||
- HTTP and RTMP services
|
||||
- Let's Encrypt for HTTPS and RTMPS
|
||||
- HLS/DASH Session tracking with bandwidth and current viewer limiters
|
||||
- Multiple resource limiters and monitoring
|
||||
- FFmpeg progress data
|
||||
- Metrics incl. Prometheus support
|
||||
- Logging and debugging for FFmpeg processes with history
|
||||
- Multiple auth. by JWT and Auth0
|
||||
- 100% JSON REST API (Swagger documented)
|
||||
- GraphQL for metrics, process, and progress data
|
||||
|
||||
## Quick start
|
||||
|
||||
@ -355,7 +355,7 @@ input addresses or the output addresses. These patterns are regular expressions
|
||||
environment variables `CORE_FFMPEG_ACCESS_INPUT` and `CORE_FFMPEG_ACCESS_OUTPUT.` The expressions need to be space-separated, e.g.
|
||||
`HTTPS?:// RTSP:// RTMP://`. If one of the lists is empty, then no restriction on input, resp. The output will be applied.
|
||||
|
||||
Independently of the value of `CORE_FFMPEG_ACCESS_OUTPUT` there's a check that verifies that output can only be written to the specified `CORE_STORAGE_DISK_DIR` and works as follows: If the address has a protocol specifier other than `file:,` then no further checks will be applied. If the protocol is `file:` or no protocol specifier is given, the address is assumed to be a path that is checked against the path shown in `CORE_STORAGE_DISK_DIR.`
|
||||
Independently of the value of `CORE_FFMPEG_ACCESS_OUTPUT` there's a check that verifies that output can only be written to the specified `CORE_STORAGE_DISK_DIR` and works as follows: If the address has a protocol specifier other than `file:,` then no further checks will be applied. If the protocol is `file:` or no protocol specifier is given, the address is assumed to be a path that is checked against the path shown in `CORE_STORAGE_DISK_DIR.`
|
||||
|
||||
It will be rejected if the address is outside the `CORE_STORAGE_DISK_DIR` directory. Otherwise, the protocol `file:` will be prepended. If you give some expressions for `CORE_FFMPEG_ACCESS_OUTPUT,` you should also allow `file:.`
|
||||
|
||||
@ -495,9 +495,9 @@ http http://localhost:8080/api/v3/process "Authorization: Bearer eyJhbGciOiJIUzI
|
||||
|
||||
| Method | Path | Description |
|
||||
| ------ | --------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| GET | /api/v3/config | Retrieve the current config without the override values from the environment variables. |
|
||||
| GET | /api/v3/config/active | Retrieve the current config with the override values from the environment variables are taken into account. |
|
||||
| PUT | /api/v3/config | Store a new config. Only some values are respected, and the new config will only be used after a restart. |
|
||||
| GET | /api/v3/config | Retrieve the current config without the override values from the environment variables. |
|
||||
| GET | /api/v3/config/active | Retrieve the current config with the override values from the environment variables are taken into account. |
|
||||
| PUT | /api/v3/config | Store a new config. Only some values are respected, and the new config will only be used after a restart. |
|
||||
| GET | /api/v3/config/reload | Reload the config. The config will be re-read and validated from the store. It will cause a restart of all services. |
|
||||
|
||||
When retrieving the config via the API, critical values (such as passwords) will be disguised if not required otherwise.
|
||||
@ -531,7 +531,8 @@ With the process API call, you can manage different FFmpeg processes. A process
|
||||
"cleanup": [{
|
||||
"pattern": "(memfs|diskfs):...",
|
||||
"max_files: "number,
|
||||
"max_file_age_seconds": "number"
|
||||
"max_file_age_seconds": "number",
|
||||
"purge_on_delete: "(true|false)"
|
||||
}]
|
||||
},
|
||||
... list of outputs ...
|
||||
@ -556,7 +557,8 @@ permitted maximum age for the files matching that pattern. The pattern starts wi
|
||||
which filesystem this rule is designated to. Then a [glob pattern](https://pkg.go.dev/path/filepath#Match) follows to
|
||||
identify the files. If `max_files` is set to a number > 0, then the oldest files from the matching files will be deleted if
|
||||
the list of matching files is longer than that number. If `max_file_age_seconds` is set to a number > 0, then all files
|
||||
that are older than this number of seconds from the matching files will be deleted.
|
||||
that are older than this number of seconds from the matching files will be deleted. If `purge_on_delete` is set to `true`,
|
||||
then all matching files will be deleted when the process is deleted.
|
||||
|
||||
The API calls are
|
||||
|
||||
@ -975,5 +977,4 @@ Before committing changes, you should run `make commit` to ensure that the sourc
|
||||
|
||||
## License
|
||||
|
||||
See the [LICENSE](./LICENSE) file for licensing information.
|
||||
|
||||
datarhei/core is licensed under the Apache License 2.0
|
||||
|
||||
@ -29,8 +29,8 @@ func (v versionInfo) MinorString() string {
|
||||
// Version of the app
|
||||
var Version = versionInfo{
|
||||
Major: 16,
|
||||
Minor: 7,
|
||||
Patch: 2,
|
||||
Minor: 8,
|
||||
Patch: 0,
|
||||
}
|
||||
|
||||
// Commit is the git commit the app is build from. It should be filled in during compilation
|
||||
|
||||
680
docs/docs.go
680
docs/docs.go
@ -1,32 +1,23 @@
|
||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag at
|
||||
// 2022-03-31 16:22:16.716974 +0200 CEST m=+0.265947626
|
||||
|
||||
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag
|
||||
package docs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
"github.com/alecthomas/template"
|
||||
"github.com/swaggo/swag"
|
||||
)
|
||||
|
||||
var doc = `{
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{.Description}}",
|
||||
"description": "{{escape .Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"contact": {
|
||||
"name": "datarheiCORE Support",
|
||||
"name": "datarhei Core Support",
|
||||
"url": "https://www.datarhei.com",
|
||||
"email": "hello@datarhei.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "???",
|
||||
"url": "nothing"
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://github.com/datarhei/core/blob/main/LICENSE"
|
||||
},
|
||||
"version": "{{.Version}}"
|
||||
},
|
||||
@ -70,7 +61,9 @@ var doc = `{
|
||||
"summary": "Load GraphQL playground",
|
||||
"operationId": "graph-playground",
|
||||
"responses": {
|
||||
"200": {}
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -787,9 +780,7 @@ var doc = `{
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -830,17 +821,13 @@ var doc = `{
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -1247,9 +1234,7 @@ var doc = `{
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -1297,17 +1282,13 @@ var doc = `{
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -1849,12 +1830,6 @@ var doc = `{
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.SessionsSummary"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1886,12 +1861,6 @@ var doc = `{
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.SessionsActive"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2233,14 +2202,12 @@ var doc = `{
|
||||
"type": "string"
|
||||
},
|
||||
"input": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.AVstreamIO"
|
||||
},
|
||||
"looping": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.AVstreamIO"
|
||||
},
|
||||
"queue": {
|
||||
@ -2294,7 +2261,6 @@ var doc = `{
|
||||
"type": "integer"
|
||||
},
|
||||
"version": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.Version"
|
||||
}
|
||||
}
|
||||
@ -2319,17 +2285,467 @@ var doc = `{
|
||||
"api.Config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"client": {
|
||||
"config": {
|
||||
"$ref": "#/definitions/api.ConfigData"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"loaded_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"overrides": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ConfigData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"api": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"http": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth0": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/config.Auth0Tenant"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable_localhost": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"jwt": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"secret": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"read_only": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"db": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dir": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"force_gc": {
|
||||
"type": "integer"
|
||||
},
|
||||
"profiling": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ffmpeg": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"binary": {
|
||||
"type": "string"
|
||||
},
|
||||
"log": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"max_history": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_lines": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"max_processes": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auto": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"log": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"silent"
|
||||
]
|
||||
},
|
||||
"max_lines": {
|
||||
"type": "integer"
|
||||
},
|
||||
"topics": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"metrics": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enable_prometheus": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"interval_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
},
|
||||
"range_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"playout": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"min_port": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"router": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"blocked_prefixes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"routes": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ui_path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rtmp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"app": {
|
||||
"type": "string"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enable_tls": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sessions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ip_ignorelist": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"max_bitrate_mbit": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_sessions": {
|
||||
"type": "integer"
|
||||
},
|
||||
"persist": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"persist_interval_sec": {
|
||||
"type": "integer"
|
||||
},
|
||||
"session_timeout_sec": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cors": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"origins": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cache": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_file_size_mbytes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_size_mbytes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"ttl_seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dir": {
|
||||
"type": "string"
|
||||
},
|
||||
"max_size_mbytes": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"memory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"max_size_mbytes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"purge": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mimetypes_file": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"auto": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cert_file": {
|
||||
"type": "string"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key_file": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"update_check": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ConfigError": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@ -2376,22 +2792,16 @@ var doc = `{
|
||||
"query": {
|
||||
"type": "string"
|
||||
},
|
||||
"variables": {
|
||||
"type": "object"
|
||||
}
|
||||
"variables": {}
|
||||
}
|
||||
},
|
||||
"api.GraphResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "object"
|
||||
},
|
||||
"data": {},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
"items": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2433,9 +2843,6 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.Metadata": {
|
||||
"type": "object"
|
||||
},
|
||||
"api.MetricsQuery": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2448,7 +2855,7 @@ var doc = `{
|
||||
"$ref": "#/definitions/api.MetricsQueryMetric"
|
||||
}
|
||||
},
|
||||
"timeframe_sec": {
|
||||
"timerange_sec": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
@ -2470,11 +2877,17 @@ var doc = `{
|
||||
"api.MetricsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"interval_sec": {
|
||||
"type": "integer"
|
||||
},
|
||||
"metrics": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/api.MetricsResponseMetric"
|
||||
}
|
||||
},
|
||||
"timerange_sec": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2493,23 +2906,29 @@ var doc = `{
|
||||
"values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
"$ref": "#/definitions/api.MetricsResponseValue"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.MetricsResponseValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ts": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.PlayoutStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"aqueue": {
|
||||
"type": "integer"
|
||||
},
|
||||
"debug": {
|
||||
"type": "object"
|
||||
},
|
||||
"debug": {},
|
||||
"drop": {
|
||||
"type": "integer"
|
||||
},
|
||||
@ -2529,14 +2948,12 @@ var doc = `{
|
||||
"type": "string"
|
||||
},
|
||||
"input": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.PlayoutStatusIO"
|
||||
},
|
||||
"looping": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.PlayoutStatusIO"
|
||||
},
|
||||
"queue": {
|
||||
@ -2546,7 +2963,6 @@ var doc = `{
|
||||
"type": "integer"
|
||||
},
|
||||
"swap": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.PlayoutStatusSwap"
|
||||
},
|
||||
"url": {
|
||||
@ -2672,7 +3088,6 @@ var doc = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessConfig"
|
||||
},
|
||||
"created_at": {
|
||||
@ -2681,19 +3096,14 @@ var doc = `{
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
},
|
||||
"metadata": {},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
"report": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessReport"
|
||||
},
|
||||
"state": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessState"
|
||||
},
|
||||
"type": {
|
||||
@ -2704,10 +3114,8 @@ var doc = `{
|
||||
"api.ProcessConfig": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"input",
|
||||
"output",
|
||||
"type"
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"autostart": {
|
||||
@ -2723,7 +3131,6 @@ var doc = `{
|
||||
}
|
||||
},
|
||||
"limits": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessConfigLimits"
|
||||
},
|
||||
"options": {
|
||||
@ -2753,7 +3160,8 @@ var doc = `{
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ffmpeg"
|
||||
"ffmpeg",
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -2761,13 +3169,18 @@ var doc = `{
|
||||
"api.ProcessConfigIO": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"address",
|
||||
"id"
|
||||
"address"
|
||||
],
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"cleanup": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/api.ProcessConfigIOCleanup"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -2779,6 +3192,26 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ProcessConfigIOCleanup": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"pattern"
|
||||
],
|
||||
"properties": {
|
||||
"max_file_age_seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_files": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"purge_on_delete": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ProcessConfigLimits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2870,7 +3303,6 @@ var doc = `{
|
||||
"type": "string"
|
||||
},
|
||||
"progress": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.Progress"
|
||||
},
|
||||
"reconnect_seconds": {
|
||||
@ -2938,7 +3370,6 @@ var doc = `{
|
||||
},
|
||||
"avstream": {
|
||||
"description": "avstream",
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.AVstream"
|
||||
},
|
||||
"bitrate_kbit": {
|
||||
@ -3091,11 +3522,9 @@ var doc = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"active": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.SessionSummaryActive"
|
||||
},
|
||||
"summary": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.SessionSummarySummary"
|
||||
}
|
||||
}
|
||||
@ -3406,9 +3835,11 @@ var doc = `{
|
||||
"type": "boolean"
|
||||
},
|
||||
"interval_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
},
|
||||
"range_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
@ -3444,6 +3875,9 @@ var doc = `{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ui_path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3481,7 +3915,7 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"sessions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
@ -3608,6 +4042,9 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"update_check": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
@ -3919,49 +4356,18 @@ var doc = `{
|
||||
}
|
||||
}`
|
||||
|
||||
type swaggerInfo struct {
|
||||
Version string
|
||||
Host string
|
||||
BasePath string
|
||||
Schemes []string
|
||||
Title string
|
||||
Description string
|
||||
}
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = swaggerInfo{
|
||||
Version: "6.0",
|
||||
Host: "",
|
||||
BasePath: "/",
|
||||
Schemes: []string{},
|
||||
Title: "datarhei Core API",
|
||||
Description: "Expose REST API for the datarheiCORE",
|
||||
}
|
||||
|
||||
type s struct{}
|
||||
|
||||
func (s *s) ReadDoc() string {
|
||||
sInfo := SwaggerInfo
|
||||
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
|
||||
|
||||
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
||||
"marshal": func(v interface{}) string {
|
||||
a, _ := json.Marshal(v)
|
||||
return string(a)
|
||||
},
|
||||
}).Parse(doc)
|
||||
if err != nil {
|
||||
return doc
|
||||
}
|
||||
|
||||
var tpl bytes.Buffer
|
||||
if err := t.Execute(&tpl, sInfo); err != nil {
|
||||
return doc
|
||||
}
|
||||
|
||||
return tpl.String()
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "3.0",
|
||||
Host: "",
|
||||
BasePath: "/",
|
||||
Schemes: []string{},
|
||||
Title: "datarhei Core API",
|
||||
Description: "Expose REST API for the datarhei Core",
|
||||
InfoInstanceName: "swagger",
|
||||
SwaggerTemplate: docTemplate,
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(swag.Name, &s{})
|
||||
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||
}
|
||||
|
||||
@ -4,15 +4,15 @@
|
||||
"description": "Expose REST API for the datarhei Core",
|
||||
"title": "datarhei Core API",
|
||||
"contact": {
|
||||
"name": "datarhei.com",
|
||||
"name": "datarhei Core Support",
|
||||
"url": "https://www.datarhei.com",
|
||||
"email": "support@datarhei.com"
|
||||
"email": "hello@datarhei.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache License Version 2.0",
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://github.com/datarhei/core/blob/main/LICENSE"
|
||||
},
|
||||
"version": "6.0"
|
||||
"version": "3.0"
|
||||
},
|
||||
"basePath": "/",
|
||||
"paths": {
|
||||
@ -53,7 +53,9 @@
|
||||
"summary": "Load GraphQL playground",
|
||||
"operationId": "graph-playground",
|
||||
"responses": {
|
||||
"200": {}
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -770,9 +772,7 @@
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -813,17 +813,13 @@
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -1230,9 +1226,7 @@
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -1280,17 +1274,13 @@
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
}
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
@ -1832,12 +1822,6 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.SessionsSummary"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1869,12 +1853,6 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.SessionsActive"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2216,14 +2194,12 @@
|
||||
"type": "string"
|
||||
},
|
||||
"input": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.AVstreamIO"
|
||||
},
|
||||
"looping": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.AVstreamIO"
|
||||
},
|
||||
"queue": {
|
||||
@ -2277,7 +2253,6 @@
|
||||
"type": "integer"
|
||||
},
|
||||
"version": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.Version"
|
||||
}
|
||||
}
|
||||
@ -2302,17 +2277,467 @@
|
||||
"api.Config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"client": {
|
||||
"config": {
|
||||
"$ref": "#/definitions/api.ConfigData"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"loaded_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"overrides": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ConfigData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"api": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"http": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth0": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/config.Auth0Tenant"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable_localhost": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"jwt": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"secret": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"read_only": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"db": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dir": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"force_gc": {
|
||||
"type": "integer"
|
||||
},
|
||||
"profiling": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ffmpeg": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"block": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"binary": {
|
||||
"type": "string"
|
||||
},
|
||||
"log": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"max_history": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_lines": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"max_processes": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auto": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"log": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"silent"
|
||||
]
|
||||
},
|
||||
"max_lines": {
|
||||
"type": "integer"
|
||||
},
|
||||
"topics": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"metrics": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enable_prometheus": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"interval_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
},
|
||||
"range_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"playout": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"min_port": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"router": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"blocked_prefixes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"routes": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ui_path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rtmp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"app": {
|
||||
"type": "string"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enable_tls": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sessions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ip_ignorelist": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"max_bitrate_mbit": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_sessions": {
|
||||
"type": "integer"
|
||||
},
|
||||
"persist": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"persist_interval_sec": {
|
||||
"type": "integer"
|
||||
},
|
||||
"session_timeout_sec": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cors": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"origins": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"disk": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cache": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_file_size_mbytes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_size_mbytes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"ttl_seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dir": {
|
||||
"type": "string"
|
||||
},
|
||||
"max_size_mbytes": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"memory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"max_size_mbytes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"purge": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mimetypes_file": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"auto": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cert_file": {
|
||||
"type": "string"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key_file": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"update_check": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ConfigError": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@ -2359,22 +2784,16 @@
|
||||
"query": {
|
||||
"type": "string"
|
||||
},
|
||||
"variables": {
|
||||
"type": "object"
|
||||
}
|
||||
"variables": {}
|
||||
}
|
||||
},
|
||||
"api.GraphResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "object"
|
||||
},
|
||||
"data": {},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
"items": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2416,9 +2835,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.Metadata": {
|
||||
"type": "object"
|
||||
},
|
||||
"api.MetricsQuery": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2431,7 +2847,7 @@
|
||||
"$ref": "#/definitions/api.MetricsQueryMetric"
|
||||
}
|
||||
},
|
||||
"timeframe_sec": {
|
||||
"timerange_sec": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
@ -2453,11 +2869,17 @@
|
||||
"api.MetricsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"interval_sec": {
|
||||
"type": "integer"
|
||||
},
|
||||
"metrics": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/api.MetricsResponseMetric"
|
||||
}
|
||||
},
|
||||
"timerange_sec": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2476,23 +2898,29 @@
|
||||
"values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
"$ref": "#/definitions/api.MetricsResponseValue"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.MetricsResponseValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ts": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.PlayoutStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"aqueue": {
|
||||
"type": "integer"
|
||||
},
|
||||
"debug": {
|
||||
"type": "object"
|
||||
},
|
||||
"debug": {},
|
||||
"drop": {
|
||||
"type": "integer"
|
||||
},
|
||||
@ -2512,14 +2940,12 @@
|
||||
"type": "string"
|
||||
},
|
||||
"input": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.PlayoutStatusIO"
|
||||
},
|
||||
"looping": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.PlayoutStatusIO"
|
||||
},
|
||||
"queue": {
|
||||
@ -2529,7 +2955,6 @@
|
||||
"type": "integer"
|
||||
},
|
||||
"swap": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.PlayoutStatusSwap"
|
||||
},
|
||||
"url": {
|
||||
@ -2655,7 +3080,6 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessConfig"
|
||||
},
|
||||
"created_at": {
|
||||
@ -2664,19 +3088,14 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.Metadata"
|
||||
},
|
||||
"metadata": {},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
"report": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessReport"
|
||||
},
|
||||
"state": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessState"
|
||||
},
|
||||
"type": {
|
||||
@ -2687,10 +3106,8 @@
|
||||
"api.ProcessConfig": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"input",
|
||||
"output",
|
||||
"type"
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"autostart": {
|
||||
@ -2706,7 +3123,6 @@
|
||||
}
|
||||
},
|
||||
"limits": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.ProcessConfigLimits"
|
||||
},
|
||||
"options": {
|
||||
@ -2736,7 +3152,8 @@
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ffmpeg"
|
||||
"ffmpeg",
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -2744,13 +3161,18 @@
|
||||
"api.ProcessConfigIO": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"address",
|
||||
"id"
|
||||
"address"
|
||||
],
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"cleanup": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/api.ProcessConfigIOCleanup"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -2762,6 +3184,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ProcessConfigIOCleanup": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"pattern"
|
||||
],
|
||||
"properties": {
|
||||
"max_file_age_seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_files": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"purge_on_delete": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.ProcessConfigLimits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2853,7 +3295,6 @@
|
||||
"type": "string"
|
||||
},
|
||||
"progress": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.Progress"
|
||||
},
|
||||
"reconnect_seconds": {
|
||||
@ -2921,7 +3362,6 @@
|
||||
},
|
||||
"avstream": {
|
||||
"description": "avstream",
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.AVstream"
|
||||
},
|
||||
"bitrate_kbit": {
|
||||
@ -3074,11 +3514,9 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"active": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.SessionSummaryActive"
|
||||
},
|
||||
"summary": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/api.SessionSummarySummary"
|
||||
}
|
||||
}
|
||||
@ -3389,9 +3827,11 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"interval_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
},
|
||||
"range_sec": {
|
||||
"description": "seconds",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
@ -3427,6 +3867,9 @@
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ui_path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3464,7 +3907,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"sessions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
@ -3591,6 +4034,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"update_check": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
@ -3900,4 +4346,4 @@
|
||||
"type": "basic"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,12 +16,10 @@ definitions:
|
||||
type: string
|
||||
input:
|
||||
$ref: '#/definitions/api.AVstreamIO'
|
||||
type: object
|
||||
looping:
|
||||
type: boolean
|
||||
output:
|
||||
$ref: '#/definitions/api.AVstreamIO'
|
||||
type: object
|
||||
queue:
|
||||
type: integer
|
||||
type: object
|
||||
@ -57,7 +55,6 @@ definitions:
|
||||
type: integer
|
||||
version:
|
||||
$ref: '#/definitions/api.Version'
|
||||
type: object
|
||||
type: object
|
||||
api.Command:
|
||||
properties:
|
||||
@ -73,13 +70,305 @@ definitions:
|
||||
type: object
|
||||
api.Config:
|
||||
properties:
|
||||
client:
|
||||
config:
|
||||
$ref: '#/definitions/api.ConfigData'
|
||||
created_at:
|
||||
type: string
|
||||
token:
|
||||
loaded_at:
|
||||
type: string
|
||||
url:
|
||||
overrides:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
api.ConfigData:
|
||||
properties:
|
||||
address:
|
||||
type: string
|
||||
api:
|
||||
properties:
|
||||
access:
|
||||
properties:
|
||||
http:
|
||||
properties:
|
||||
allow:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
block:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
https:
|
||||
properties:
|
||||
allow:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
block:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
auth:
|
||||
properties:
|
||||
auth0:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
tenants:
|
||||
items:
|
||||
$ref: '#/definitions/config.Auth0Tenant'
|
||||
type: array
|
||||
type: object
|
||||
disable_localhost:
|
||||
type: boolean
|
||||
enable:
|
||||
type: boolean
|
||||
jwt:
|
||||
properties:
|
||||
secret:
|
||||
type: string
|
||||
type: object
|
||||
password:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
read_only:
|
||||
type: boolean
|
||||
type: object
|
||||
created_at:
|
||||
type: string
|
||||
db:
|
||||
properties:
|
||||
dir:
|
||||
type: string
|
||||
type: object
|
||||
debug:
|
||||
properties:
|
||||
force_gc:
|
||||
type: integer
|
||||
profiling:
|
||||
type: boolean
|
||||
type: object
|
||||
ffmpeg:
|
||||
properties:
|
||||
access:
|
||||
properties:
|
||||
input:
|
||||
properties:
|
||||
allow:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
block:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
output:
|
||||
properties:
|
||||
allow:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
block:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
binary:
|
||||
type: string
|
||||
log:
|
||||
properties:
|
||||
max_history:
|
||||
type: integer
|
||||
max_lines:
|
||||
type: integer
|
||||
type: object
|
||||
max_processes:
|
||||
type: integer
|
||||
type: object
|
||||
host:
|
||||
properties:
|
||||
auto:
|
||||
type: boolean
|
||||
name:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
id:
|
||||
type: string
|
||||
log:
|
||||
properties:
|
||||
level:
|
||||
enum:
|
||||
- debug
|
||||
- info
|
||||
- warn
|
||||
- error
|
||||
- silent
|
||||
type: string
|
||||
max_lines:
|
||||
type: integer
|
||||
topics:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
metrics:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
enable_prometheus:
|
||||
type: boolean
|
||||
interval_sec:
|
||||
description: seconds
|
||||
type: integer
|
||||
range_sec:
|
||||
description: seconds
|
||||
type: integer
|
||||
type: object
|
||||
name:
|
||||
type: string
|
||||
playout:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
max_port:
|
||||
type: integer
|
||||
min_port:
|
||||
type: integer
|
||||
type: object
|
||||
router:
|
||||
properties:
|
||||
blocked_prefixes:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
routes:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
ui_path:
|
||||
type: string
|
||||
type: object
|
||||
rtmp:
|
||||
properties:
|
||||
address:
|
||||
type: string
|
||||
app:
|
||||
type: string
|
||||
enable:
|
||||
type: boolean
|
||||
enable_tls:
|
||||
type: boolean
|
||||
token:
|
||||
type: string
|
||||
type: object
|
||||
service:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
token:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
type: object
|
||||
sessions:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
ip_ignorelist:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
max_bitrate_mbit:
|
||||
type: integer
|
||||
max_sessions:
|
||||
type: integer
|
||||
persist:
|
||||
type: boolean
|
||||
persist_interval_sec:
|
||||
type: integer
|
||||
session_timeout_sec:
|
||||
type: integer
|
||||
type: object
|
||||
storage:
|
||||
properties:
|
||||
cors:
|
||||
properties:
|
||||
origins:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
disk:
|
||||
properties:
|
||||
cache:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
max_file_size_mbytes:
|
||||
type: integer
|
||||
max_size_mbytes:
|
||||
type: integer
|
||||
ttl_seconds:
|
||||
type: integer
|
||||
types:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
dir:
|
||||
type: string
|
||||
max_size_mbytes:
|
||||
type: integer
|
||||
type: object
|
||||
memory:
|
||||
properties:
|
||||
auth:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
password:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
max_size_mbytes:
|
||||
type: integer
|
||||
purge:
|
||||
type: boolean
|
||||
type: object
|
||||
mimetypes_file:
|
||||
type: string
|
||||
type: object
|
||||
tls:
|
||||
properties:
|
||||
address:
|
||||
type: string
|
||||
auto:
|
||||
type: boolean
|
||||
cert_file:
|
||||
type: string
|
||||
enable:
|
||||
type: boolean
|
||||
key_file:
|
||||
type: string
|
||||
type: object
|
||||
update_check:
|
||||
type: boolean
|
||||
version:
|
||||
type: integer
|
||||
type: object
|
||||
api.ConfigError:
|
||||
additionalProperties:
|
||||
items:
|
||||
@ -110,16 +399,13 @@ definitions:
|
||||
properties:
|
||||
query:
|
||||
type: string
|
||||
variables:
|
||||
type: object
|
||||
variables: {}
|
||||
type: object
|
||||
api.GraphResponse:
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
data: {}
|
||||
errors:
|
||||
items:
|
||||
type: object
|
||||
items: {}
|
||||
type: array
|
||||
type: object
|
||||
api.JWT:
|
||||
@ -147,8 +433,6 @@ definitions:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
api.Metadata:
|
||||
type: object
|
||||
api.MetricsQuery:
|
||||
properties:
|
||||
interval_sec:
|
||||
@ -157,7 +441,7 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/api.MetricsQueryMetric'
|
||||
type: array
|
||||
timeframe_sec:
|
||||
timerange_sec:
|
||||
type: integer
|
||||
type: object
|
||||
api.MetricsQueryMetric:
|
||||
@ -171,10 +455,14 @@ definitions:
|
||||
type: object
|
||||
api.MetricsResponse:
|
||||
properties:
|
||||
interval_sec:
|
||||
type: integer
|
||||
metrics:
|
||||
items:
|
||||
$ref: '#/definitions/api.MetricsResponseMetric'
|
||||
type: array
|
||||
timerange_sec:
|
||||
type: integer
|
||||
type: object
|
||||
api.MetricsResponseMetric:
|
||||
properties:
|
||||
@ -186,17 +474,21 @@ definitions:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
items:
|
||||
type: number
|
||||
type: array
|
||||
$ref: '#/definitions/api.MetricsResponseValue'
|
||||
type: array
|
||||
type: object
|
||||
api.MetricsResponseValue:
|
||||
properties:
|
||||
ts:
|
||||
type: string
|
||||
value:
|
||||
type: number
|
||||
type: object
|
||||
api.PlayoutStatus:
|
||||
properties:
|
||||
aqueue:
|
||||
type: integer
|
||||
debug:
|
||||
type: object
|
||||
debug: {}
|
||||
drop:
|
||||
type: integer
|
||||
dup:
|
||||
@ -211,19 +503,16 @@ definitions:
|
||||
type: string
|
||||
input:
|
||||
$ref: '#/definitions/api.PlayoutStatusIO'
|
||||
type: object
|
||||
looping:
|
||||
type: boolean
|
||||
output:
|
||||
$ref: '#/definitions/api.PlayoutStatusIO'
|
||||
type: object
|
||||
queue:
|
||||
type: integer
|
||||
stream:
|
||||
type: integer
|
||||
swap:
|
||||
$ref: '#/definitions/api.PlayoutStatusSwap'
|
||||
type: object
|
||||
url:
|
||||
type: string
|
||||
type: object
|
||||
@ -307,22 +596,17 @@ definitions:
|
||||
properties:
|
||||
config:
|
||||
$ref: '#/definitions/api.ProcessConfig'
|
||||
type: object
|
||||
created_at:
|
||||
type: integer
|
||||
id:
|
||||
type: string
|
||||
metadata:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
type: object
|
||||
metadata: {}
|
||||
reference:
|
||||
type: string
|
||||
report:
|
||||
$ref: '#/definitions/api.ProcessReport'
|
||||
type: object
|
||||
state:
|
||||
$ref: '#/definitions/api.ProcessState'
|
||||
type: object
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
@ -338,7 +622,6 @@ definitions:
|
||||
type: array
|
||||
limits:
|
||||
$ref: '#/definitions/api.ProcessConfigLimits'
|
||||
type: object
|
||||
options:
|
||||
items:
|
||||
type: string
|
||||
@ -358,17 +641,20 @@ definitions:
|
||||
type:
|
||||
enum:
|
||||
- ffmpeg
|
||||
- ""
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- input
|
||||
- output
|
||||
- type
|
||||
type: object
|
||||
api.ProcessConfigIO:
|
||||
properties:
|
||||
address:
|
||||
type: string
|
||||
cleanup:
|
||||
items:
|
||||
$ref: '#/definitions/api.ProcessConfigIOCleanup'
|
||||
type: array
|
||||
id:
|
||||
type: string
|
||||
options:
|
||||
@ -377,7 +663,19 @@ definitions:
|
||||
type: array
|
||||
required:
|
||||
- address
|
||||
- id
|
||||
type: object
|
||||
api.ProcessConfigIOCleanup:
|
||||
properties:
|
||||
max_file_age_seconds:
|
||||
type: integer
|
||||
max_files:
|
||||
type: integer
|
||||
pattern:
|
||||
type: string
|
||||
purge_on_delete:
|
||||
type: boolean
|
||||
required:
|
||||
- pattern
|
||||
type: object
|
||||
api.ProcessConfigLimits:
|
||||
properties:
|
||||
@ -440,7 +738,6 @@ definitions:
|
||||
type: string
|
||||
progress:
|
||||
$ref: '#/definitions/api.Progress'
|
||||
type: object
|
||||
reconnect_seconds:
|
||||
type: integer
|
||||
runtime_seconds:
|
||||
@ -486,7 +783,6 @@ definitions:
|
||||
avstream:
|
||||
$ref: '#/definitions/api.AVstream'
|
||||
description: avstream
|
||||
type: object
|
||||
bitrate_kbit:
|
||||
description: kbit/s
|
||||
type: number
|
||||
@ -589,10 +885,8 @@ definitions:
|
||||
properties:
|
||||
active:
|
||||
$ref: '#/definitions/api.SessionSummaryActive'
|
||||
type: object
|
||||
summary:
|
||||
$ref: '#/definitions/api.SessionSummarySummary'
|
||||
type: object
|
||||
type: object
|
||||
api.SessionSummaryActive:
|
||||
properties:
|
||||
@ -795,8 +1089,10 @@ definitions:
|
||||
enable_prometheus:
|
||||
type: boolean
|
||||
interval_sec:
|
||||
description: seconds
|
||||
type: integer
|
||||
range_sec:
|
||||
description: seconds
|
||||
type: integer
|
||||
type: object
|
||||
name:
|
||||
@ -820,6 +1116,8 @@ definitions:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
ui_path:
|
||||
type: string
|
||||
type: object
|
||||
rtmp:
|
||||
properties:
|
||||
@ -843,7 +1141,7 @@ definitions:
|
||||
url:
|
||||
type: string
|
||||
type: object
|
||||
stats:
|
||||
sessions:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
@ -925,6 +1223,8 @@ definitions:
|
||||
key_file:
|
||||
type: string
|
||||
type: object
|
||||
update_check:
|
||||
type: boolean
|
||||
version:
|
||||
type: integer
|
||||
type: object
|
||||
@ -1114,14 +1414,14 @@ definitions:
|
||||
info:
|
||||
contact:
|
||||
email: hello@datarhei.com
|
||||
name: datarheiCORE Support
|
||||
name: datarhei Core Support
|
||||
url: https://www.datarhei.com
|
||||
description: Expose REST API for the datarheiCORE
|
||||
description: Expose REST API for the datarhei Core
|
||||
license:
|
||||
name: ???
|
||||
url: nothing
|
||||
name: Apache 2.0
|
||||
url: https://github.com/datarhei/core/blob/main/LICENSE
|
||||
title: datarhei Core API
|
||||
version: "6.0"
|
||||
version: "3.0"
|
||||
paths:
|
||||
/{path}:
|
||||
get:
|
||||
@ -1173,7 +1473,8 @@ paths:
|
||||
produces:
|
||||
- text/html
|
||||
responses:
|
||||
"200": {}
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Load GraphQL playground
|
||||
@ -1639,8 +1940,7 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
@ -1667,15 +1967,13 @@ paths:
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
schema: {}
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
@ -1943,8 +2241,7 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
@ -1977,15 +2274,13 @@ paths:
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
schema: {}
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.Metadata'
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
@ -2340,10 +2635,6 @@ paths:
|
||||
description: Sessions summary
|
||||
schema:
|
||||
$ref: '#/definitions/api.SessionsSummary'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/api.Error'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get a summary of all active and past sessions
|
||||
@ -2364,10 +2655,6 @@ paths:
|
||||
description: Active sessions listing
|
||||
schema:
|
||||
$ref: '#/definitions/api.SessionsActive'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/api.Error'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get a minimal summary of all active sessions
|
||||
|
||||
@ -17,10 +17,7 @@ func DevicesV4L() ([]HWDevice, error) {
|
||||
cmd := exec.Command("v4l2-ctl", "--list-devices")
|
||||
cmd.Env = []string{}
|
||||
cmd.Stdout = buf
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return devices, err
|
||||
}
|
||||
cmd.Run()
|
||||
|
||||
devices = parseV4LDevices(buf)
|
||||
|
||||
|
||||
42
go.mod
42
go.mod
@ -3,41 +3,37 @@ module github.com/datarhei/core
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.1
|
||||
github.com/agnivade/levenshtein v1.1.1 // indirect
|
||||
github.com/99designs/gqlgen v0.17.9
|
||||
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1
|
||||
github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce
|
||||
github.com/go-openapi/spec v0.20.6 // indirect
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.10.1
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0
|
||||
github.com/go-playground/validator/v10 v10.11.0
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/labstack/echo/v4 v4.7.0
|
||||
github.com/labstack/echo/v4 v4.7.2
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0
|
||||
github.com/lufia/plan9stats v0.0.0-20220305071607-d0b38dbe16db // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
||||
github.com/prometheus/client_golang v1.12.1
|
||||
github.com/shirou/gopsutil/v3 v3.22.2
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/swaggo/echo-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.8.0
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.4.1
|
||||
github.com/prometheus/client_golang v1.12.2
|
||||
github.com/prometheus/common v0.34.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.4
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/swaggo/echo-swagger v1.3.2
|
||||
github.com/swaggo/swag v1.8.2
|
||||
github.com/tklauser/numcpus v0.5.0 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.4.4
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70
|
||||
golang.org/x/mod v0.5.1
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
golang.org/x/sys v0.0.0-20220307203707-22a9840ba4d7 // indirect
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 // indirect
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
|
||||
)
|
||||
|
||||
138
go.sum
138
go.sum
@ -31,20 +31,17 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/99designs/gqlgen v0.17.1 h1:i2qQMPKHQjHgBWYIpO4TsaQpPqMHCPK1+h95ipvH8VU=
|
||||
github.com/99designs/gqlgen v0.17.1/go.mod h1:K5fzLKwtph+FFgh9j7nFbRUdBKvTcGnsta51fsMTn3o=
|
||||
github.com/99designs/gqlgen v0.17.9 h1:0XvE3nMaTaLYq7XbBz1MY0t9BFcntydlt1zzNa4eY+4=
|
||||
github.com/99designs/gqlgen v0.17.9/go.mod h1:PThAZAK9t2pAat7g8QdSI4dCBMOhBO+t2qj+0jvDqps=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d h1:4BQNwS4T13UU3Yee4GfzZH3Q9SNpKeJvLigfw8fDjX0=
|
||||
@ -83,7 +80,6 @@ github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce/go.mod h1:Jcw/6jZDQQ
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@ -97,18 +93,22 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ=
|
||||
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
|
||||
@ -119,14 +119,14 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.10.1 h1:uA0+amWMiglNZKZ9FJRKUAe9U3RX91eVn1JYXMWt7ig=
|
||||
github.com/go-playground/validator/v10 v10.10.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
|
||||
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -167,8 +167,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -185,7 +186,6 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@ -223,10 +223,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.1.14/go.mod h1:Q5KZ1vD3V5FEzjM79hjwVrC3ABr7F5IdM23bXQMRDGg=
|
||||
github.com/labstack/echo/v4 v4.7.0 h1:8wHgZhoE9OT1NSLw6sfrX7ZGpWMtO5Zlfr68+BIo180=
|
||||
github.com/labstack/echo/v4 v4.7.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
||||
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
@ -235,31 +233,25 @@ github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y=
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20220305071607-d0b38dbe16db h1:QT3DrSQsMWGKZMArbkP9FlS2ZnPLA2z8D7fU+G3BZ3o=
|
||||
github.com/lufia/plan9stats v0.0.0-20220305071607-d0b38dbe16db/go.mod h1:VgrrWVwBO2+6XKn8ypT3WUqvoxCa8R2M5to2tRzGovI=
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 h1:aczX6NMOtt6L4YT0fQvKkDK6LZEtdOso9sUH89V1+P0=
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281/go.mod h1:lc+czkgO/8F7puNki5jk8QyujbfK1LOT7Wl0ON2hxyk=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matryer/moq v0.2.3 h1:Q06vEqnBYjjfx5KKgHfYRKE/lvlRu+Nj+xodG4YdHnU=
|
||||
github.com/matryer/moq v0.2.3/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/matryer/moq v0.2.7 h1:RtpiPUM8L7ZSCbSwK+QcZH/E9tgqAkFjKQxsRs25b4w=
|
||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
|
||||
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
@ -268,7 +260,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
|
||||
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
@ -289,8 +280,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
|
||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@ -299,8 +291,9 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.34.0 h1:RBmGO9d/FVjqHT0yUGQwBJhkwKV+wPCn7KGpvfab0uE=
|
||||
github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
@ -316,8 +309,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil/v3 v3.22.2 h1:wCrArWFkHYIdDxx/FSfF5RB4dpJYW6t7rcp3+zL8uks=
|
||||
github.com/shirou/gopsutil/v3 v3.22.2/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY=
|
||||
github.com/shirou/gopsutil/v3 v3.22.4 h1:srAQaiX6jX/cYL6q29aE0m8lOskT9CurZ9N61YR3yoI=
|
||||
github.com/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
@ -331,32 +324,30 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/swaggo/echo-swagger v1.3.0 h1:xxL/4jbCY4Z3udUvqOas+IpTMKbxrKdEKwtS7He0Qhg=
|
||||
github.com/swaggo/echo-swagger v1.3.0/go.mod h1:snY6MlGK+pQAfJNEfX5qaOzt/QuM/WINVxGgQaZVJgg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/swaggo/echo-swagger v1.3.2 h1:D+3BNl8JMC6pKhA+egjh4LGI0jNesqlt77WahTHfTXQ=
|
||||
github.com/swaggo/echo-swagger v1.3.2/go.mod h1:Sjj0O7Puf939HXhxhfZdR49MIrtcg3mLgdg3/qVcbyw=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/swag v1.7.9/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU=
|
||||
github.com/swaggo/swag v1.8.0 h1:80NNhvpJcuItNpBDqgJwDuKlMmaZ/OATOzhG3bhcM3w=
|
||||
github.com/swaggo/swag v1.8.0/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU=
|
||||
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
|
||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||
github.com/swaggo/swag v1.8.2 h1:D4aBiVS2a65zhyk3WFqOUz7Rz0sOaUcgeErcid5uGL4=
|
||||
github.com/swaggo/swag v1.8.2/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
||||
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A=
|
||||
github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
|
||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vektah/gqlparser/v2 v2.4.0/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/vektah/gqlparser/v2 v2.4.1 h1:QOyEn8DAPMUMARGMeshKDkDgNmVoEaEGiDB0uWxcSlQ=
|
||||
github.com/vektah/gqlparser/v2 v2.4.1/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/vektah/gqlparser/v2 v2.4.4 h1:rh9hwZ5Jx9cCq88zXz2YHKmuQBuwY1JErHU8GywFdwE=
|
||||
github.com/vektah/gqlparser/v2 v2.4.4/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@ -364,6 +355,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -381,13 +374,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 h1:syTAU9FwmvzEoIYMqcPHOcVm4H3U5u90WsvuYgwpETU=
|
||||
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -419,8 +412,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -456,14 +450,17 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -478,7 +475,6 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -487,15 +483,12 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -520,17 +513,16 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220307203707-22a9840ba4d7 h1:8IVLkfbr2cLhv0a/vKq4UFUcJym8RmDoDboxCFWEjYE=
|
||||
golang.org/x/sys v0.0.0-20220307203707-22a9840ba4d7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -545,8 +537,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@ -587,11 +579,11 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -672,8 +664,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@ -17,11 +17,11 @@ type ProbeIO struct {
|
||||
Type string `json:"type"`
|
||||
Codec string `json:"codec"`
|
||||
Coder string `json:"coder"`
|
||||
Bitrate json.Number `json:"bitrate_kbps"`
|
||||
Duration json.Number `json:"duration_sec"`
|
||||
Bitrate json.Number `json:"bitrate_kbps" swaggertype:"number"`
|
||||
Duration json.Number `json:"duration_sec" swaggertype:"number"`
|
||||
|
||||
// video
|
||||
FPS json.Number `json:"fps"`
|
||||
FPS json.Number `json:"fps" swaggertype:"number"`
|
||||
Pixfmt string `json:"pix_fmt"`
|
||||
Width uint64 `json:"width"`
|
||||
Height uint64 `json:"height"`
|
||||
|
||||
@ -29,9 +29,10 @@ type ProcessConfigIO struct {
|
||||
}
|
||||
|
||||
type ProcessConfigIOCleanup struct {
|
||||
Pattern string `json:"pattern" validate:"required"`
|
||||
MaxFiles uint `json:"max_files"`
|
||||
MaxFileAge uint `json:"max_file_age_seconds"`
|
||||
Pattern string `json:"pattern" validate:"required"`
|
||||
MaxFiles uint `json:"max_files"`
|
||||
MaxFileAge uint `json:"max_file_age_seconds"`
|
||||
PurgeOnDelete bool `json:"purge_on_delete"`
|
||||
}
|
||||
|
||||
type ProcessConfigLimits struct {
|
||||
@ -91,9 +92,10 @@ func (cfg *ProcessConfig) Marshal() *app.Config {
|
||||
|
||||
for _, c := range x.Cleanup {
|
||||
output.Cleanup = append(output.Cleanup, app.ConfigIOCleanup{
|
||||
Pattern: c.Pattern,
|
||||
MaxFiles: c.MaxFiles,
|
||||
MaxFileAge: c.MaxFileAge,
|
||||
Pattern: c.Pattern,
|
||||
MaxFiles: c.MaxFiles,
|
||||
MaxFileAge: c.MaxFileAge,
|
||||
PurgeOnDelete: c.PurgeOnDelete,
|
||||
})
|
||||
}
|
||||
|
||||
@ -237,7 +239,7 @@ type ProcessState struct {
|
||||
LastLog string `json:"last_logline"`
|
||||
Progress *Progress `json:"progress"`
|
||||
Memory uint64 `json:"memory_bytes"`
|
||||
CPU json.Number `json:"cpu_usage"`
|
||||
CPU json.Number `json:"cpu_usage" swaggertype:"number"`
|
||||
Command []string `json:"command"`
|
||||
}
|
||||
|
||||
|
||||
@ -20,15 +20,15 @@ type ProgressIO struct {
|
||||
Codec string `json:"codec"`
|
||||
Coder string `json:"coder"`
|
||||
Frame uint64 `json:"frame"`
|
||||
FPS json.Number `json:"fps"`
|
||||
FPS json.Number `json:"fps" swaggertype:"number"`
|
||||
Packet uint64 `json:"packet"`
|
||||
PPS json.Number `json:"pps"`
|
||||
Size uint64 `json:"size_kb"` // kbytes
|
||||
Bitrate json.Number `json:"bitrate_kbit"` // kbit/s
|
||||
PPS json.Number `json:"pps" swaggertype:"number"`
|
||||
Size uint64 `json:"size_kb"` // kbytes
|
||||
Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number"` // kbit/s
|
||||
|
||||
// Video
|
||||
Pixfmt string `json:"pix_fmt,omitempty"`
|
||||
Quantizer json.Number `json:"q,omitempty"`
|
||||
Quantizer json.Number `json:"q,omitempty" swaggertype:"number"`
|
||||
Width uint64 `json:"width,omitempty"`
|
||||
Height uint64 `json:"height,omitempty"`
|
||||
|
||||
@ -81,12 +81,12 @@ type Progress struct {
|
||||
Output []ProgressIO `json:"outputs"`
|
||||
Frame uint64 `json:"frame"`
|
||||
Packet uint64 `json:"packet"`
|
||||
FPS json.Number `json:"fps"`
|
||||
Quantizer json.Number `json:"q"`
|
||||
FPS json.Number `json:"fps" swaggertype:"number"`
|
||||
Quantizer json.Number `json:"q" swaggertype:"number"`
|
||||
Size uint64 `json:"size_kb"` // kbytes
|
||||
Time json.Number `json:"time"`
|
||||
Bitrate json.Number `json:"bitrate_kbit"` // kbit/s
|
||||
Speed json.Number `json:"speed"`
|
||||
Time json.Number `json:"time" swaggertype:"number"`
|
||||
Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number"` // kbit/s
|
||||
Speed json.Number `json:"speed" swaggertype:"number"`
|
||||
Drop uint64 `json:"drop"`
|
||||
Dup uint64 `json:"dup"`
|
||||
}
|
||||
|
||||
@ -30,8 +30,8 @@ type Session struct {
|
||||
Extra string `json:"extra"`
|
||||
RxBytes uint64 `json:"bytes_rx"`
|
||||
TxBytes uint64 `json:"bytes_tx"`
|
||||
RxBitrate json.Number `json:"bandwidth_rx_kbit"` // kbit/s
|
||||
TxBitrate json.Number `json:"bandwidth_tx_kbit"` // kbit/s
|
||||
RxBitrate json.Number `json:"bandwidth_rx_kbit" swaggertype:"number"` // kbit/s
|
||||
TxBitrate json.Number `json:"bandwidth_tx_kbit" swaggertype:"number"` // kbit/s
|
||||
}
|
||||
|
||||
func (s *Session) Unmarshal(sess session.Session) {
|
||||
@ -51,11 +51,11 @@ func (s *Session) Unmarshal(sess session.Session) {
|
||||
type SessionSummaryActive struct {
|
||||
SessionList []Session `json:"list"`
|
||||
Sessions uint64 `json:"sessions"`
|
||||
RxBitrate json.Number `json:"bandwidth_rx_mbit"` // mbit/s
|
||||
TxBitrate json.Number `json:"bandwidth_tx_mbit"` // mbit/s
|
||||
RxBitrate json.Number `json:"bandwidth_rx_mbit" swaggertype:"number"` // mbit/s
|
||||
TxBitrate json.Number `json:"bandwidth_tx_mbit" swaggertype:"number"` // mbit/s
|
||||
MaxSessions uint64 `json:"max_sessions"`
|
||||
MaxRxBitrate json.Number `json:"max_bandwidth_rx_mbit"` // mbit/s
|
||||
MaxTxBitrate json.Number `json:"max_bandwidth_tx_mbit"` // mbit/s
|
||||
MaxRxBitrate json.Number `json:"max_bandwidth_rx_mbit" swaggertype:"number"` // mbit/s
|
||||
MaxTxBitrate json.Number `json:"max_bandwidth_tx_mbit" swaggertype:"number"` // mbit/s
|
||||
}
|
||||
|
||||
// SessionSummarySummary represents the summary (history) of all finished sessions
|
||||
|
||||
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/datarhei/core/http/api"
|
||||
@ -64,6 +65,8 @@ func (h *DiskFSHandler) GetFile(c echo.Context) error {
|
||||
c.Response().Header().Set("Last-Modified", stat.ModTime().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
||||
|
||||
if path, ok := stat.IsLink(); ok {
|
||||
path = filepath.Clean("/" + path)
|
||||
|
||||
if path[0] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
|
||||
@ -31,7 +31,6 @@ func NewSession(registry session.Registry) *SessionHandler {
|
||||
// @Security ApiKeyAuth
|
||||
// @Param collectors query string false "Comma separated list of collectors"
|
||||
// @Success 200 {object} api.SessionsSummary "Sessions summary"
|
||||
// @Failure 404 {object} api.Error
|
||||
// @Router /api/v3/session [get]
|
||||
func (s *SessionHandler) Summary(c echo.Context) error {
|
||||
collectors := strings.Split(util.DefaultQuery(c, "collectors", ""), ",")
|
||||
@ -39,13 +38,8 @@ func (s *SessionHandler) Summary(c echo.Context) error {
|
||||
sessionsSummary := make(api.SessionsSummary)
|
||||
|
||||
for _, name := range collectors {
|
||||
collector := s.registry.Collector(name)
|
||||
if collector == nil {
|
||||
return api.Err(http.StatusNotFound, "Unknown collector", "Registered collectors are: %s", strings.Join(s.registry.Collectors(), ", "))
|
||||
}
|
||||
|
||||
summary := api.SessionSummary{}
|
||||
summary.Unmarshal(collector.Summary())
|
||||
summary.Unmarshal(s.registry.Summary(name))
|
||||
|
||||
sessionsSummary[name] = summary
|
||||
}
|
||||
@ -61,7 +55,6 @@ func (s *SessionHandler) Summary(c echo.Context) error {
|
||||
// @Security ApiKeyAuth
|
||||
// @Param collectors query string false "Comma separated list of collectors"
|
||||
// @Success 200 {object} api.SessionsActive "Active sessions listing"
|
||||
// @Failure 404 {object} api.Error
|
||||
// @Router /api/v3/session/active [get]
|
||||
func (s *SessionHandler) Active(c echo.Context) error {
|
||||
collectors := strings.Split(util.DefaultQuery(c, "collectors", ""), ",")
|
||||
@ -69,14 +62,10 @@ func (s *SessionHandler) Active(c echo.Context) error {
|
||||
sessionsActive := make(api.SessionsActive)
|
||||
|
||||
for _, name := range collectors {
|
||||
collector := s.registry.Collector(name)
|
||||
if collector == nil {
|
||||
return api.Err(http.StatusNotFound, "Unknown collector", "Registered collectors are: %s", strings.Join(s.registry.Collectors(), ", "))
|
||||
}
|
||||
sessions := s.registry.Active(name)
|
||||
active := []api.Session{}
|
||||
|
||||
sessions := collector.Active()
|
||||
|
||||
active := make([]api.Session, len(sessions))
|
||||
active = make([]api.Session, len(sessions))
|
||||
|
||||
for i, s := range sessions {
|
||||
active[i].Unmarshal(s)
|
||||
|
||||
@ -69,6 +69,8 @@ func (h *DiskFSHandler) GetFile(c echo.Context) error {
|
||||
c.Response().Header().Set("Last-Modified", stat.ModTime().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
||||
|
||||
if path, ok := stat.IsLink(); ok {
|
||||
path = filepath.Clean("/" + path)
|
||||
|
||||
if path[0] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/datarhei/core/http/api"
|
||||
"github.com/datarhei/core/http/handler/util"
|
||||
@ -51,6 +52,8 @@ func (h *MemFSHandler) GetFile(c echo.Context) error {
|
||||
c.Response().Header().Set("Last-Modified", stat.ModTime().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
||||
|
||||
if path, ok := stat.IsLink(); ok {
|
||||
path = filepath.Clean("/" + path)
|
||||
|
||||
if path[0] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
|
||||
@ -55,7 +55,11 @@ func NewHLSWithConfig(config HLSConfig) echo.MiddlewareFunc {
|
||||
}
|
||||
|
||||
if config.EgressCollector == nil {
|
||||
config.EgressCollector = DefaultHTTPConfig.Collector
|
||||
config.EgressCollector = DefaultHLSConfig.EgressCollector
|
||||
}
|
||||
|
||||
if config.IngressCollector == nil {
|
||||
config.IngressCollector = DefaultHLSConfig.IngressCollector
|
||||
}
|
||||
|
||||
hls := hls{
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
// @title datarhei Core API
|
||||
// @version 6.0
|
||||
// @description Expose REST API for the datarheiCORE
|
||||
// @version 3.0
|
||||
// @description Expose REST API for the datarhei Core
|
||||
|
||||
// @contact.name datarheiCORE Support
|
||||
// @contact.name datarhei Core Support
|
||||
// @contact.url https://www.datarhei.com
|
||||
// @contact.email hello@datarhei.com
|
||||
|
||||
// @license.name ???
|
||||
// @license.url nothing
|
||||
// @license.name Apache 2.0
|
||||
// @license.url https://github.com/datarhei/core/blob/main/LICENSE
|
||||
|
||||
// @BasePath /
|
||||
|
||||
|
||||
@ -204,17 +204,13 @@ func (fs *diskFilesystem) Files() int64 {
|
||||
}
|
||||
|
||||
func (fs *diskFilesystem) Symlink(oldname, newname string) error {
|
||||
if !filepath.IsAbs(oldname) {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldname = filepath.Join(fs.dir, oldname)
|
||||
oldname = filepath.Join(fs.dir, filepath.Clean("/"+oldname))
|
||||
|
||||
if !filepath.IsAbs(newname) {
|
||||
return nil
|
||||
}
|
||||
|
||||
newname = filepath.Join(fs.dir, newname)
|
||||
newname = filepath.Join(fs.dir, filepath.Clean("/"+newname))
|
||||
|
||||
err := os.Symlink(oldname, newname)
|
||||
|
||||
@ -222,11 +218,7 @@ func (fs *diskFilesystem) Symlink(oldname, newname string) error {
|
||||
}
|
||||
|
||||
func (fs *diskFilesystem) Open(path string) File {
|
||||
if !filepath.IsAbs(path) {
|
||||
return nil
|
||||
}
|
||||
|
||||
path = filepath.Join(fs.dir, path)
|
||||
path = filepath.Join(fs.dir, filepath.Clean("/"+path))
|
||||
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
@ -243,16 +235,7 @@ func (fs *diskFilesystem) Open(path string) File {
|
||||
}
|
||||
|
||||
func (fs *diskFilesystem) Store(path string, r io.Reader) (int64, bool, error) {
|
||||
if !filepath.IsAbs(path) {
|
||||
return -1, false, fmt.Errorf("Invalid path")
|
||||
}
|
||||
|
||||
path = filepath.Join(fs.dir, path)
|
||||
|
||||
// Check that we're not leaving our base directory
|
||||
if !strings.HasPrefix(path, fs.dir) {
|
||||
return -1, false, fmt.Errorf("Invalid path")
|
||||
}
|
||||
path = filepath.Join(fs.dir, filepath.Clean("/"+path))
|
||||
|
||||
replace := true
|
||||
|
||||
@ -283,11 +266,7 @@ func (fs *diskFilesystem) Store(path string, r io.Reader) (int64, bool, error) {
|
||||
}
|
||||
|
||||
func (fs *diskFilesystem) Delete(path string) int64 {
|
||||
if !filepath.IsAbs(path) {
|
||||
return -1
|
||||
}
|
||||
|
||||
path = filepath.Join(fs.dir, path)
|
||||
path = filepath.Join(fs.dir, filepath.Clean("/"+path))
|
||||
|
||||
finfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
|
||||
@ -270,7 +270,13 @@ func (e *Event) WithField(key string, value interface{}) Logger {
|
||||
})
|
||||
}
|
||||
|
||||
const maxFields = 1024
|
||||
|
||||
func (e *Event) WithFields(f Fields) Logger {
|
||||
if maxFields-len(e.Data)-len(f) < 0 {
|
||||
return e
|
||||
}
|
||||
|
||||
data := make(Fields, len(e.Data)+len(f))
|
||||
for k, v := range e.Data {
|
||||
data[k] = v
|
||||
|
||||
@ -3,9 +3,10 @@ package app
|
||||
import "github.com/datarhei/core/process"
|
||||
|
||||
type ConfigIOCleanup struct {
|
||||
Pattern string `json:"pattern"`
|
||||
MaxFiles uint `json:"max_files"`
|
||||
MaxFileAge uint `json:"max_file_age_seconds"`
|
||||
Pattern string `json:"pattern"`
|
||||
MaxFiles uint `json:"max_files"`
|
||||
MaxFileAge uint `json:"max_file_age_seconds"`
|
||||
PurgeOnDelete bool `json:"purge_on_delete"`
|
||||
}
|
||||
|
||||
type ConfigIO struct {
|
||||
|
||||
@ -16,9 +16,10 @@ type Config struct {
|
||||
}
|
||||
|
||||
type Pattern struct {
|
||||
Pattern string
|
||||
MaxFiles uint
|
||||
MaxFileAge time.Duration
|
||||
Pattern string
|
||||
MaxFiles uint
|
||||
MaxFileAge time.Duration
|
||||
PurgeOnDelete bool
|
||||
}
|
||||
|
||||
type Filesystem interface {
|
||||
@ -116,7 +117,11 @@ func (fs *filesystem) UnsetCleanup(id string) {
|
||||
fs.cleanupLock.Lock()
|
||||
defer fs.cleanupLock.Unlock()
|
||||
|
||||
patterns, _ := fs.cleanupPatterns[id]
|
||||
|
||||
delete(fs.cleanupPatterns, id)
|
||||
|
||||
fs.purge(patterns)
|
||||
}
|
||||
|
||||
func (fs *filesystem) cleanup() {
|
||||
@ -150,6 +155,20 @@ func (fs *filesystem) cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *filesystem) purge(patterns []Pattern) {
|
||||
for _, pattern := range patterns {
|
||||
if !pattern.PurgeOnDelete {
|
||||
continue
|
||||
}
|
||||
|
||||
files := fs.Filesystem.List(pattern.Pattern)
|
||||
for _, f := range files {
|
||||
fs.logger.Debug().WithField("path", f.Name()).Log("Purging file")
|
||||
fs.Filesystem.Delete(f.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *filesystem) cleanupTicker(ctx context.Context, interval time.Duration) {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
@ -63,6 +63,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
type task struct {
|
||||
valid bool
|
||||
id string // ID of the task/process
|
||||
reference string
|
||||
process *app.Process
|
||||
@ -188,7 +189,9 @@ func (r *restream) Stop() {
|
||||
// altering their order such that on a subsequent
|
||||
// Start() they will get restarted.
|
||||
for id, t := range r.tasks {
|
||||
t.ffmpeg.Stop()
|
||||
if t.ffmpeg != nil {
|
||||
t.ffmpeg.Stop()
|
||||
}
|
||||
|
||||
r.unsetCleanup(id)
|
||||
}
|
||||
@ -221,6 +224,10 @@ func (r *restream) observe(ctx context.Context, interval time.Duration) {
|
||||
// Stop all tasks that write to disk
|
||||
r.lock.Lock()
|
||||
for id, t := range r.tasks {
|
||||
if !t.valid {
|
||||
continue
|
||||
}
|
||||
|
||||
if !t.usesDisk {
|
||||
continue
|
||||
}
|
||||
@ -244,8 +251,7 @@ func (r *restream) load() error {
|
||||
return err
|
||||
}
|
||||
|
||||
r.metadata = data.Metadata.System
|
||||
r.tasks = make(map[string]*task)
|
||||
tasks := make(map[string]*task)
|
||||
|
||||
for id, process := range data.Process {
|
||||
t := &task{
|
||||
@ -259,11 +265,11 @@ func (r *restream) load() error {
|
||||
// Replace all placeholders in the config
|
||||
r.resolvePlaceholders(t.config, r.fs.diskfs.Base(), r.fs.memfs.Base())
|
||||
|
||||
r.tasks[id] = t
|
||||
tasks[id] = t
|
||||
}
|
||||
|
||||
for id, userdata := range data.Metadata.Process {
|
||||
t, ok := r.tasks[id]
|
||||
t, ok := tasks[id]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@ -274,20 +280,23 @@ func (r *restream) load() error {
|
||||
// Now that all tasks are defined and all placeholders are
|
||||
// replaced, we can resolve references and validate the
|
||||
// inputs and outputs.
|
||||
for _, t := range r.tasks {
|
||||
err := r.resolveAddresses(t.config)
|
||||
for _, t := range tasks {
|
||||
err := r.resolveAddresses(tasks, t.config)
|
||||
if err != nil {
|
||||
return err
|
||||
r.logger.Warn().WithField("id", t.id).WithError(err).Log("Ignoring")
|
||||
continue
|
||||
}
|
||||
|
||||
t.usesDisk, err = r.validateConfig(t.config)
|
||||
if err != nil {
|
||||
return err
|
||||
r.logger.Warn().WithField("id", t.id).WithError(err).Log("Ignoring")
|
||||
continue
|
||||
}
|
||||
|
||||
err = r.setPlayoutPorts(t)
|
||||
if err != nil {
|
||||
return err
|
||||
r.logger.Warn().WithField("id", t.id).WithError(err).Log("Ignoring")
|
||||
continue
|
||||
}
|
||||
|
||||
t.command = r.createCommand(t.config)
|
||||
@ -306,8 +315,12 @@ func (r *restream) load() error {
|
||||
}
|
||||
|
||||
t.ffmpeg = ffmpeg
|
||||
t.valid = true
|
||||
}
|
||||
|
||||
r.tasks = tasks
|
||||
r.metadata = data.Metadata.System
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -399,7 +412,7 @@ func (r *restream) createTask(config *app.Config) (*task, error) {
|
||||
|
||||
r.resolvePlaceholders(t.config, r.fs.diskfs.Base(), r.fs.memfs.Base())
|
||||
|
||||
err := r.resolveAddresses(t.config)
|
||||
err := r.resolveAddresses(r.tasks, t.config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -430,6 +443,7 @@ func (r *restream) createTask(config *app.Config) (*task, error) {
|
||||
}
|
||||
|
||||
t.ffmpeg = ffmpeg
|
||||
t.valid = true
|
||||
|
||||
return t, nil
|
||||
}
|
||||
@ -440,17 +454,19 @@ func (r *restream) setCleanup(id string, config *app.Config) {
|
||||
if strings.HasPrefix(c.Pattern, "memfs:") {
|
||||
r.fs.memfs.SetCleanup(id, []rfs.Pattern{
|
||||
{
|
||||
Pattern: strings.TrimPrefix(c.Pattern, "memfs:"),
|
||||
MaxFiles: c.MaxFiles,
|
||||
MaxFileAge: time.Duration(c.MaxFileAge) * time.Second,
|
||||
Pattern: strings.TrimPrefix(c.Pattern, "memfs:"),
|
||||
MaxFiles: c.MaxFiles,
|
||||
MaxFileAge: time.Duration(c.MaxFileAge) * time.Second,
|
||||
PurgeOnDelete: c.PurgeOnDelete,
|
||||
},
|
||||
})
|
||||
} else if strings.HasPrefix(c.Pattern, "diskfs:") {
|
||||
r.fs.memfs.SetCleanup(id, []rfs.Pattern{
|
||||
{
|
||||
Pattern: strings.TrimPrefix(c.Pattern, "diskfs:"),
|
||||
MaxFiles: c.MaxFiles,
|
||||
MaxFileAge: time.Duration(c.MaxFileAge) * time.Second,
|
||||
Pattern: strings.TrimPrefix(c.Pattern, "diskfs:"),
|
||||
MaxFiles: c.MaxFiles,
|
||||
MaxFileAge: time.Duration(c.MaxFileAge) * time.Second,
|
||||
PurgeOnDelete: c.PurgeOnDelete,
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -754,10 +770,10 @@ func (r *restream) validateOutputAddress(address, basedir string) (string, bool,
|
||||
return "file:" + address, true, nil
|
||||
}
|
||||
|
||||
func (r *restream) resolveAddresses(config *app.Config) error {
|
||||
func (r *restream) resolveAddresses(tasks map[string]*task, config *app.Config) error {
|
||||
for i, input := range config.Input {
|
||||
// Resolve any references
|
||||
address, err := r.resolveAddress(config.ID, input.Address)
|
||||
address, err := r.resolveAddress(tasks, config.ID, input.Address)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reference error for '#%s:%s': %w", config.ID, input.ID, err)
|
||||
}
|
||||
@ -770,7 +786,7 @@ func (r *restream) resolveAddresses(config *app.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) resolveAddress(id, address string) (string, error) {
|
||||
func (r *restream) resolveAddress(tasks map[string]*task, id, address string) (string, error) {
|
||||
re := regexp.MustCompile(`^#(.+):output=(.+)`)
|
||||
|
||||
if len(address) == 0 {
|
||||
@ -790,7 +806,7 @@ func (r *restream) resolveAddress(id, address string) (string, error) {
|
||||
return address, fmt.Errorf("self-reference not possible (%s)", address)
|
||||
}
|
||||
|
||||
task, ok := r.tasks[matches[1]]
|
||||
task, ok := tasks[matches[1]]
|
||||
if !ok {
|
||||
return address, fmt.Errorf("unknown process '%s' (%s)", matches[1], address)
|
||||
}
|
||||
@ -886,6 +902,10 @@ func (r *restream) startProcess(id string) error {
|
||||
return fmt.Errorf("unknown process ID (%s)", id)
|
||||
}
|
||||
|
||||
if !task.valid {
|
||||
return fmt.Errorf("invalid process definition")
|
||||
}
|
||||
|
||||
status := task.ffmpeg.Status()
|
||||
|
||||
if task.process.Order == "start" && status.Order == "start" {
|
||||
@ -953,6 +973,10 @@ func (r *restream) restartProcess(id string) error {
|
||||
return fmt.Errorf("unknown process ID (%s)", id)
|
||||
}
|
||||
|
||||
if !task.valid {
|
||||
return fmt.Errorf("invalid process definition")
|
||||
}
|
||||
|
||||
if task.process.Order == "stop" {
|
||||
return nil
|
||||
}
|
||||
@ -982,11 +1006,13 @@ func (r *restream) reloadProcess(id string) error {
|
||||
return fmt.Errorf("unknown process ID (%s)", id)
|
||||
}
|
||||
|
||||
t.valid = false
|
||||
|
||||
t.config = t.process.Config.Clone()
|
||||
|
||||
r.resolvePlaceholders(t.config, r.fs.diskfs.Base(), r.fs.memfs.Base())
|
||||
|
||||
err := r.resolveAddresses(t.config)
|
||||
err := r.resolveAddresses(r.tasks, t.config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1024,6 +1050,7 @@ func (r *restream) reloadProcess(id string) error {
|
||||
}
|
||||
|
||||
t.ffmpeg = ffmpeg
|
||||
t.valid = true
|
||||
|
||||
if order == "start" {
|
||||
r.startProcess(id)
|
||||
@ -1043,6 +1070,10 @@ func (r *restream) GetProcessState(id string) (*app.State, error) {
|
||||
return state, fmt.Errorf("unknown process ID (%s)", id)
|
||||
}
|
||||
|
||||
if !task.valid {
|
||||
return state, fmt.Errorf("invalid process definition")
|
||||
}
|
||||
|
||||
status := task.ffmpeg.Status()
|
||||
|
||||
state.Order = task.process.Order
|
||||
@ -1100,6 +1131,10 @@ func (r *restream) GetProcessLog(id string) (*app.Log, error) {
|
||||
return &app.Log{}, fmt.Errorf("unknown process ID (%s)", id)
|
||||
}
|
||||
|
||||
if !task.valid {
|
||||
return &app.Log{}, fmt.Errorf("invalid process definition")
|
||||
}
|
||||
|
||||
log := &app.Log{}
|
||||
|
||||
current := task.parser.Report()
|
||||
@ -1150,6 +1185,10 @@ func (r *restream) Probe(id string) app.Probe {
|
||||
|
||||
r.lock.RUnlock()
|
||||
|
||||
if !task.valid {
|
||||
return appprobe
|
||||
}
|
||||
|
||||
var command []string
|
||||
|
||||
// Copy global options
|
||||
@ -1210,6 +1249,10 @@ func (r *restream) GetPlayout(id, inputid string) (string, error) {
|
||||
return "", fmt.Errorf("unknown process ID '%s'", id)
|
||||
}
|
||||
|
||||
if !task.valid {
|
||||
return "", fmt.Errorf("Invalid process definition")
|
||||
}
|
||||
|
||||
port, ok := task.playout[inputid]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("no playout for input ID '%s' and process '%s'", inputid, id)
|
||||
|
||||
@ -24,12 +24,26 @@ type Config struct {
|
||||
|
||||
// The Registry interface
|
||||
type Registry interface {
|
||||
// Register returns a new collector from conf and registers it under the id and error is nil. In case of error
|
||||
// the returned collector is nil and the error is not nil.
|
||||
Register(id string, conf CollectorConfig) (Collector, error)
|
||||
|
||||
// Unregister unregisters the collector with the ID, returns error if the ID is not registered
|
||||
Unregister(id string) error
|
||||
|
||||
// UnregisterAll unregisters al registered collectors
|
||||
UnregisterAll()
|
||||
|
||||
// Collectors returns an array of all registered IDs
|
||||
Collectors() []string
|
||||
|
||||
// Collector returns the collector with the ID, or nil if the ID is not registered
|
||||
Collector(id string) Collector
|
||||
|
||||
// Summary returns the summary from a collector with the ID, or an empty summary if the ID is not registered
|
||||
Summary(id string) Summary
|
||||
|
||||
// Active returns the active sessions from a collector with the ID, or an empty list if the ID is not registered
|
||||
Active(id string) []Session
|
||||
}
|
||||
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/.gitignore
generated
vendored
1
vendor/github.com/99designs/gqlgen/.gitignore
generated
vendored
@ -14,3 +14,4 @@
|
||||
.idea/
|
||||
*.test
|
||||
*.out
|
||||
gqlgen
|
||||
|
||||
406
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
406
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
@ -5,12 +5,416 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.1...HEAD)
|
||||
## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.7...HEAD)
|
||||
|
||||
<!-- end of if -->
|
||||
<!-- end of CommitGroups -->
|
||||
<a name="v0.17.7"></a>
|
||||
## [v0.17.7](https://github.com/99designs/gqlgen/compare/v0.17.6...v0.17.7) - 2022-05-24
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/2b1dff1b71f89c95e946bbe5948b7061f9c47aa8"><tt>2b1dff1b</tt></a> release v0.17.7
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/b2087f944d9b9af6e776a9d97662c9e8b86a8c3b"><tt>b2087f94</tt></a> Update module dependencies (<a href="https://github.com/99designs/gqlgen/pull/92">#2192</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/8825ac460b047e22724ed7728c7d7ffbf1b523a9"><tt>8825ac46</tt></a> Fix misprint (<a href="https://github.com/99designs/gqlgen/pull/87">#2187</a>)</summary>
|
||||
|
||||
* Fix misprint
|
||||
|
||||
* Fix misprint
|
||||
|
||||
* Re-generate
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/41daa5d8dc1e35bdbfe68e95b37c10599b224456"><tt>41daa5d8</tt></a> fix <a href="https://github.com/99designs/gqlgen/pull/91">#2190](https://github.com/99designs/gqlgen/issues/2190) - don't use backslash for "embed" paths on windows ([#2191</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/0cce5544f06fd84831ef2ca0f60e16f7f554814d"><tt>0cce5544</tt></a> Update Changelog
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/26644541aafbcdb46f10a6ff0f5894637227c331"><tt>26644541</tt></a> v0.17.6 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.6"></a>
|
||||
## [v0.17.6](https://github.com/99designs/gqlgen/compare/v0.17.5...v0.17.6) - 2022-05-23
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/358d45dcfc2b022fdda9476a37f44c0622607ae9"><tt>358d45dc</tt></a> release v0.17.6
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/7c95938c5f1278fa14a13a92eb88d117102e0330"><tt>7c95938c</tt></a> Improve operation error handling (<a href="https://github.com/99designs/gqlgen/pull/84">#2184</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/2526f6871166377b4f444ad8d22577a632b0abf4"><tt>2526f687</tt></a> Correct identation (<a href="https://github.com/99designs/gqlgen/pull/82">#2182</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/f7bf453c79d82b01ed4baed894043aaff645bf2f"><tt>f7bf453c</tt></a> Bump dset from 3.1.1 to 3.1.2 in /integration (<a href="https://github.com/99designs/gqlgen/pull/76">#2176</a>)</summary>
|
||||
|
||||
Bumps [dset](https://github.com/lukeed/dset) from 3.1.1 to 3.1.2.
|
||||
- [Release notes](https://github.com/lukeed/dset/releases)
|
||||
- [Commits](https://github.com/lukeed/dset/compare/v3.1.1...v3.1.2)
|
||||
|
||||
---
|
||||
updated-dependencies:
|
||||
- dependency-name: dset
|
||||
dependency-type: indirect
|
||||
...
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/4cdf70261a9dc8af589399f09b56d0f90606a9fa"><tt>4cdf7026</tt></a> Update getting-started.md (<a href="https://github.com/99designs/gqlgen/pull/57">#2157</a>)</summary>
|
||||
|
||||
Fix getting-started missing fields resolver config
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/eef7bfaad1b524f9e2fc0c1150fdb321c276069e"><tt>eef7bfaa</tt></a> fix: prevents goroutine leak at websocket transport (<a href="https://github.com/99designs/gqlgen/pull/68">#2168</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/b8ec51d8629a24288353b4ee4be70fff3645b03e"><tt>b8ec51d8</tt></a> go: update gqlparser to latest (<a href="https://github.com/99designs/gqlgen/pull/49">#2149</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/ec3e597e7b45e17464cd8c7faaa51e75755ce3cf"><tt>ec3e597e</tt></a> Fix docs bug in field collection (<a href="https://github.com/99designs/gqlgen/pull/41">#2141</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/f6b352316fae4b4fdc6317e24ea94ba48ac29e85"><tt>f6b35231</tt></a> Add argument to WebsocketErrorFunc (<a href="https://github.com/99designs/gqlgen/pull/24">#2124</a>)</summary>
|
||||
|
||||
* Add argument to WebsocketErrorFunc
|
||||
|
||||
to determine whether the error ocured on read or write to the websocket.
|
||||
|
||||
* Wrap websocket error
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/0f016df3ae7ee4898358dc67a491689164297df6"><tt>0f016df3</tt></a> Fix invalid query parameter for playground subscription endpoint (<a href="https://github.com/99designs/gqlgen/pull/48">#2148</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/fb5751ab478603a864977f9fbe70655776d7fb55"><tt>fb5751ab</tt></a> use "embed" in generated code (<a href="https://github.com/99designs/gqlgen/pull/19">#2119</a>)</summary>
|
||||
|
||||
* use "embed" in generated code
|
||||
|
||||
* don't use embed for builtins
|
||||
|
||||
* working poc
|
||||
|
||||
* handle no embeddable sources
|
||||
|
||||
* fix dir
|
||||
|
||||
* comment
|
||||
|
||||
* add test for embedding
|
||||
|
||||
* improve error handling
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/d38911f1a9d7f0ec39a74a95994d95291f1922c3"><tt>d38911f1</tt></a> Allow absolute https://github.com/99designs/gqlgens to the GraphQL playground (<a href="https://github.com/99designs/gqlgen/pull/42">#2142</a>)</summary>
|
||||
|
||||
* Allow absolute URLs to the GraphQL playground
|
||||
|
||||
* Add test for playground URLs
|
||||
|
||||
* Close res.Body in playground test
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/3228f36fec50930483801b27b92658592fab5e87"><tt>3228f36f</tt></a> Update getting-started.md (<a href="https://github.com/99designs/gqlgen/pull/40">#2140</a>)</summary>
|
||||
|
||||
* Update getting-started.md
|
||||
|
||||
function rand.Int requires two parameters and returns two value in golang version 1.18.1.
|
||||
|
||||
* Highlight the package used so people don't pick crypto/rand
|
||||
|
||||
* Revert to original
|
||||
|
||||
* Remove extra space
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/33fe0b9b824ec86699059f410505c02659fc6c81"><tt>33fe0b9b</tt></a> Update package.json (<a href="https://github.com/99designs/gqlgen/pull/38">#2138</a>)</summary>
|
||||
|
||||
I added `graphql-ws` because there is no graphql-ws in package.json
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/f8e837b824ef4903a60f3cb974ef72fb4718a858"><tt>f8e837b8</tt></a> Use MultipartReader to parse file uploads (<a href="https://github.com/99designs/gqlgen/pull/35">#2135</a>)</summary>
|
||||
|
||||
Use a streaming MultipartReader to parse requests with file
|
||||
uploads. The GraphQL multipart request specification guarantees
|
||||
that the operations and map form fields will come first.
|
||||
|
||||
There are two reasons motivating this change:
|
||||
|
||||
- This allows for file uploads without specifying a specific
|
||||
filename.
|
||||
- This avoids unnecessary copies for requests with more than one
|
||||
file. Go's ParseForm already copies the request's body into
|
||||
memory or on disk. We were also doing this manually as a second
|
||||
step.
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/05bfc1fb12f73648833e1055e775e074a6df7eed"><tt>05bfc1fb</tt></a> Upddate Changelog
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/62f694f0a8cf24f52dffca5823bb44fa1c32f97b"><tt>62f694f0</tt></a> v0.17.5 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.5"></a>
|
||||
## [v0.17.5](https://github.com/99designs/gqlgen/compare/v0.17.4...v0.17.5) - 2022-04-29
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/fd97e74eafc898278fd4b74477cb053393672232"><tt>fd97e74e</tt></a> release v0.17.5
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/9250f9ac1f90b27da0bd8583ef8dcf0894d70686"><tt>9250f9ac</tt></a> Feature: Add FTV1 Support via Handler (<a href="https://github.com/99designs/gqlgen/pull/32">#2132</a>)</summary>
|
||||
|
||||
* initial support for ftv1 traces via handler
|
||||
|
||||
* remove testing json extension
|
||||
|
||||
* remove binary from commit and add to .gitignore
|
||||
|
||||
* updating go.mod
|
||||
|
||||
* updating examples go.sum
|
||||
|
||||
* rerunning generate within the examples folder
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/fce3a11a9f570ffed3e9035d32deddfb3076c2cf"><tt>fce3a11a</tt></a> feat: added graphql.UnmarshalInputFromContext (<a href="https://github.com/99designs/gqlgen/pull/31">#2131</a>)</summary>
|
||||
|
||||
* feat: added graphql.UnmarshalInputFromContext
|
||||
|
||||
* chore: run go generate for _examples
|
||||
|
||||
* fix: apply suggestions from code review
|
||||
|
||||
|
||||
* fix: update error cases
|
||||
|
||||
* fix: fixed unit-test by update root_.gotpl
|
||||
|
||||
* fix: apply suggestions from code review
|
||||
|
||||
* fix: update graphql/input.go
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/6a24e88147fb2523af0163d7fa84d296b5e32e4d"><tt>6a24e881</tt></a> update instructions to specify package of Role (<a href="https://github.com/99designs/gqlgen/pull/30">#2130</a>)</summary>
|
||||
|
||||
Can't compile with the example unless I also include `model.` for Role.
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/ccfa245b1eb2657e588bf73f4df0e99f96869cbd"><tt>ccfa245b</tt></a> Ignore protobuf files in coverage (<a href="https://github.com/99designs/gqlgen/pull/33">#2133</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/0465dcb1e8e4177945c2670f15316ac96e4b992a"><tt>0465dcb1</tt></a> Update federation.md (<a href="https://github.com/99designs/gqlgen/pull/29">#2129</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/8f0631dcd3ca6fcfcd3dc6e69f4a92fec54e6dc7"><tt>8f0631dc</tt></a> Update Changelog
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/41611560d45f1226b860e795bcb35b5ecf09c5b3"><tt>41611560</tt></a> v0.17.4 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.4"></a>
|
||||
## [v0.17.4](https://github.com/99designs/gqlgen/compare/v0.17.3...v0.17.4) - 2022-04-25
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/d6de831a28a0f1d8834c5dba4216dcd763814d3f"><tt>d6de831a</tt></a> release v0.17.4
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/2a2a3dcb67c7d713e41476eac47e20ab0e21fba7"><tt>2a2a3dcb</tt></a> Feature: Adds Federation 2 Support (<a href="https://github.com/99designs/gqlgen/pull/15">#2115</a>)</summary>
|
||||
|
||||
* fed2 rough support
|
||||
|
||||
* autodetection of fed2
|
||||
|
||||
* adding basic tests for changes
|
||||
|
||||
* fixing docs
|
||||
|
||||
* Update plugin/federation/federation.go
|
||||
|
||||
* removing custom scalar since it was causing issues
|
||||
|
||||
* fixing lint test
|
||||
|
||||
* should fix for real this time
|
||||
|
||||
* fixing test failures
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/77260e88c853a047e4e61a5357ceda4a5ea26405"><tt>77260e88</tt></a> shorten some generated code (<a href="https://github.com/99designs/gqlgen/pull/20">#2120</a>)</summary>
|
||||
|
||||
* shorten some generated code
|
||||
|
||||
* generate examples
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/4da17e1c7a59149eb6c2f5d60fcf11a2374b2488"><tt>4da17e1c</tt></a> update modules except mapstructure (<a href="https://github.com/99designs/gqlgen/pull/18">#2118</a>)</summary>
|
||||
|
||||
* Update modules
|
||||
|
||||
|
||||
* Update modules except for mapstructure
|
||||
|
||||
|
||||
* Try to update to v1.3.1
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/cddbf02d494e3aeaac3f60d1708b25facc5b767d"><tt>cddbf02d</tt></a> Update Changelog file
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/8f80f4efe8947b55919ce37291f4e908f57fd8dc"><tt>8f80f4ef</tt></a> v0.17.3 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.3"></a>
|
||||
## [v0.17.3](https://github.com/99designs/gqlgen/compare/v0.17.2...v0.17.3) - 2022-04-20
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/0bb262d1a0143f60640f60ebbb516e0f4cd79042"><tt>0bb262d1</tt></a> release v0.17.3
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/8d0bd22aff1cdb6ad2e36190e11871b169f8da0a"><tt>8d0bd22a</tt></a> Update gqlparser (<a href="https://github.com/99designs/gqlgen/pull/09">#2109</a>)</summary>
|
||||
|
||||
* Update gqlparser
|
||||
|
||||
|
||||
* Update tests to be NoError
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/ec0dea883a2c967d533e5f1530791ad72a08198b"><tt>ec0dea88</tt></a> Fix the ability of websockets to get errors (<a href="https://github.com/99designs/gqlgen/pull/97">#2097</a>)</summary>
|
||||
|
||||
Because DispatchOperation creates tempResponseContext,
|
||||
which is passed into Exec, which is then used in _Subscription to
|
||||
generate the next function. Inside the various subscription functions
|
||||
when generating next the context was captured there.
|
||||
|
||||
Which means later when the returned function from DispatchOperation is
|
||||
called. The responseContext which accumulates the errors is the
|
||||
tempResponseContext which we no longer have access to to read the errors
|
||||
out of it.
|
||||
|
||||
Instead add a context to next() so that it can be passed through and
|
||||
accumulated the errors as expected.
|
||||
|
||||
Added a unit test for this as well.
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/e3f04b42f1fc5d4b13dc0579b2ec713f770a4fd0"><tt>e3f04b42</tt></a> Change the error message to be consumer targeted (<a href="https://github.com/99designs/gqlgen/pull/96">#2096</a>)</summary>
|
||||
|
||||
* Change the error message to be slightly more clear
|
||||
|
||||
* Rebase on updated origin/master.
|
||||
|
||||
Fix the test to not be sensitive to array ordering.
|
||||
Re-generate on master as there was a schema change.
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/5a49764956ffb674df2c9bee19455bb1fd3407db"><tt>5a497649</tt></a> Fix websocket subscriptions to not double close. (<a href="https://github.com/99designs/gqlgen/pull/95">#2095</a>)</summary>
|
||||
|
||||
We were closing at the end of the loop and also in the defer.
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/a15a9bfdbad30b2f5ce7a966ec1190c108c4df3e"><tt>a15a9bfd</tt></a> Update test.yml to be valid
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/a1538928a569a09834579db941863ccce28113e3"><tt>a1538928</tt></a> Use Github API to update the docs (<a href="https://github.com/99designs/gqlgen/pull/01">#2101</a>)</summary>
|
||||
|
||||
* Use Github API to update the docs
|
||||
|
||||
Instead of a hard-coded version of the docs we want to realease, this
|
||||
uses the Github API to get the last 20 versions and publish those. This
|
||||
will allow any script invoking this to make sure to always have the
|
||||
latest version of the docs
|
||||
|
||||
* Reinstate set -e
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/3bf437c232f8be30a473cf94495a1014c0583af2"><tt>3bf437c2</tt></a> Update golangci-lint (<a href="https://github.com/99designs/gqlgen/pull/03">#2103</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/12c6d0bf15431f666d08c4c82581957e1b727898"><tt>12c6d0bf</tt></a> Fix misprint (<a href="https://github.com/99designs/gqlgen/pull/02">#2102</a>)</summary>
|
||||
|
||||
* Fix misprint
|
||||
|
||||
* Update websocket_graphql_transport_ws.go
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/9f5fad13fa6275139e051788cc5fe8c2b2630428"><tt>9f5fad13</tt></a> Bump minimist from 1.2.5 to 1.2.6 in /integration (<a href="https://github.com/99designs/gqlgen/pull/85">#2085</a>)</summary>
|
||||
|
||||
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
|
||||
- [Release notes](https://github.com/substack/minimist/releases)
|
||||
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)
|
||||
|
||||
---
|
||||
updated-dependencies:
|
||||
- dependency-name: minimist
|
||||
dependency-type: indirect
|
||||
...
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/035e1d6eeb81179ddec3d36d8776212d8fe35cd6"><tt>035e1d6e</tt></a> Add AllowedMethods field to transport.Options (<a href="https://github.com/99designs/gqlgen/pull/80">#2080</a>)</summary>
|
||||
|
||||
* Add AllowedMethods field to transport.Options
|
||||
|
||||
to enable users to specify allowed HTTP methods.
|
||||
|
||||
* Update graphql/handler/transport/options.go
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/f0fdb116f45350aabf698c20bf6410283f96bb11"><tt>f0fdb116</tt></a> Add instructions for enabling autobinding (<a href="https://github.com/99designs/gqlgen/pull/79">#2079</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/12b0b38583e2c7b2174585bf1243a98cbbc2eba6"><tt>12b0b385</tt></a> Bump Playground version (<a href="https://github.com/99designs/gqlgen/pull/78">#2078</a>)</summary>
|
||||
|
||||
* update playground
|
||||
|
||||
* enables tabs
|
||||
|
||||
* update shas
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/1324c3ffb9ff0afef6e9cc41d99b5b4b9bc928b6"><tt>1324c3ff</tt></a> Merge pull request <a href="https://github.com/99designs/gqlgen/pull/62">#2062</a> from a8m/childfield</summary>
|
||||
|
||||
graphql: add FieldContext.Child field function and enable it in codegen
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/bf9caeaee091e32178fe2906894a7c7e72fdd66d"><tt>bf9caeae</tt></a> graphql: add FieldContext.ChildArgs field and enable it in codegen
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/36fb3dc6733601f96162bc80fccda42e34b3b7ff"><tt>36fb3dc6</tt></a> codegen: allow binding methods with optional variadic arguments (<a href="https://github.com/99designs/gqlgen/pull/66">#2066</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/fba5edd4fa1176ef0f2840f3bb90fe10b9f4b695"><tt>fba5edd4</tt></a> Update Changelog
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/48b2b7e1521c50d03cabf524bbb78805e3fb023f"><tt>48b2b7e1</tt></a> v0.17.2 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.2"></a>
|
||||
## [v0.17.2](https://github.com/99designs/gqlgen/compare/v0.17.1...v0.17.2) - 2022-03-21
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/1f04d38a4441c5de6171400218b9dd25cebb3639"><tt>1f04d38a</tt></a> release v0.17.2
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/87fc5f22e8fbfa28a180cbf0e7008af9f830273e"><tt>87fc5f22</tt></a> Fix <a href="https://github.com/99designs/gqlgen/pull/52">#1961](https://github.com/99designs/gqlgen/issues/1961) for Go 1.18 ([#2052</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/f85d59d30ae055fd89b79aa3d7e3ca1c7fcaedfa"><tt>f85d59d3</tt></a> fixed modelgen test schema (<a href="https://github.com/99designs/gqlgen/pull/32">#2032</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/d873ff8bb9927b302752bd48d7836f2597db558e"><tt>d873ff8b</tt></a> v0.17.1 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.1"></a>
|
||||
## [v0.17.1](https://github.com/99designs/gqlgen/compare/v0.17.0...v0.17.1) - 2022-03-02
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/5ea50aee16088ed414be73ca9a59a90f622c9483"><tt>5ea50aee</tt></a> release v0.17.1
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/a493a4239673c5922281628fc8b94c727398283e"><tt>a493a423</tt></a> Prepare for new release
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/9f520a2897cf42750e7290cbd83de6fdf13f2e75"><tt>9f520a28</tt></a> Update golangci-lint and fix resource leak (<a href="https://github.com/99designs/gqlgen/pull/24">#2024</a>)</summary>
|
||||
|
||||
* Fix golangci-lint in CI
|
||||
|
||||
16
vendor/github.com/99designs/gqlgen/api/generate.go
generated
vendored
16
vendor/github.com/99designs/gqlgen/api/generate.go
generated
vendored
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"syscall"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen"
|
||||
@ -24,7 +25,20 @@ func Generate(cfg *config.Config, option ...Option) error {
|
||||
}
|
||||
plugins = append(plugins, resolvergen.New())
|
||||
if cfg.Federation.IsDefined() {
|
||||
plugins = append([]plugin.Plugin{federation.New()}, plugins...)
|
||||
if cfg.Federation.Version == 0 { // default to using the user's choice of version, but if unset, try to sort out which federation version to use
|
||||
urlRegex := regexp.MustCompile(`(?s)@link.*\(.*url:.*?"(.*?)"[^)]+\)`) // regex to grab the url of a link directive, should it exist
|
||||
|
||||
// check the sources, and if one is marked as federation v2, we mark the entirety to be generated using that format
|
||||
for _, v := range cfg.Sources {
|
||||
cfg.Federation.Version = 1
|
||||
urlString := urlRegex.FindStringSubmatch(v.Input)
|
||||
if urlString != nil && urlString[1] == "https://specs.apollo.dev/federation/v2.0" {
|
||||
cfg.Federation.Version = 2
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
plugins = append([]plugin.Plugin{federation.New(cfg.Federation.Version)}, plugins...)
|
||||
}
|
||||
|
||||
for _, o := range option {
|
||||
|
||||
12
vendor/github.com/99designs/gqlgen/codegen/args.go
generated
vendored
12
vendor/github.com/99designs/gqlgen/codegen/args.go
generated
vendored
@ -73,11 +73,15 @@ func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgu
|
||||
return &newArg, nil
|
||||
}
|
||||
|
||||
func (b *builder) bindArgs(field *Field, params *types.Tuple) ([]*FieldArgument, error) {
|
||||
var newArgs []*FieldArgument
|
||||
|
||||
func (b *builder) bindArgs(field *Field, sig *types.Signature, params *types.Tuple) ([]*FieldArgument, error) {
|
||||
n := params.Len()
|
||||
newArgs := make([]*FieldArgument, 0, len(field.Args))
|
||||
// Accept variadic methods (i.e. have optional parameters).
|
||||
if params.Len() > len(field.Args) && sig.Variadic() {
|
||||
n = len(field.Args)
|
||||
}
|
||||
nextArg:
|
||||
for j := 0; j < params.Len(); j++ {
|
||||
for j := 0; j < n; j++ {
|
||||
param := params.At(j)
|
||||
for _, oldArg := range field.Args {
|
||||
if strings.EqualFold(oldArg.Name, param.Name()) {
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/codegen/config/package.go
generated
vendored
1
vendor/github.com/99designs/gqlgen/codegen/config/package.go
generated
vendored
@ -12,6 +12,7 @@ import (
|
||||
type PackageConfig struct {
|
||||
Filename string `yaml:"filename,omitempty"`
|
||||
Package string `yaml:"package,omitempty"`
|
||||
Version int `yaml:"version,omitempty"`
|
||||
}
|
||||
|
||||
func (c *PackageConfig) ImportPath() string {
|
||||
|
||||
48
vendor/github.com/99designs/gqlgen/codegen/data.go
generated
vendored
48
vendor/github.com/99designs/gqlgen/codegen/data.go
generated
vendored
@ -2,7 +2,10 @@ package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
|
||||
@ -30,6 +33,26 @@ type Data struct {
|
||||
QueryRoot *Object
|
||||
MutationRoot *Object
|
||||
SubscriptionRoot *Object
|
||||
AugmentedSources []AugmentedSource
|
||||
}
|
||||
|
||||
func (d *Data) HasEmbeddableSources() bool {
|
||||
hasEmbeddableSources := false
|
||||
for _, s := range d.AugmentedSources {
|
||||
if s.Embeddable {
|
||||
hasEmbeddableSources = true
|
||||
}
|
||||
}
|
||||
return hasEmbeddableSources
|
||||
}
|
||||
|
||||
// AugmentedSource contains extra information about graphql schema files which is not known directly from the Config.Sources data
|
||||
type AugmentedSource struct {
|
||||
// path relative to Config.Exec.Filename
|
||||
RelativePath string
|
||||
Embeddable bool
|
||||
BuiltIn bool
|
||||
Source string
|
||||
}
|
||||
|
||||
type builder struct {
|
||||
@ -147,6 +170,31 @@ func BuildData(cfg *config.Config) (*Data, error) {
|
||||
// otherwise show a generic error message
|
||||
return nil, fmt.Errorf("invalid types were encountered while traversing the go source code, this probably means the invalid code generated isnt correct. add try adding -v to debug")
|
||||
}
|
||||
aSources := []AugmentedSource{}
|
||||
for _, s := range cfg.Sources {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get working directory: %w", err)
|
||||
}
|
||||
outputDir := cfg.Exec.Dir()
|
||||
sourcePath := filepath.Join(wd, s.Name)
|
||||
relative, err := filepath.Rel(outputDir, sourcePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compute path of %s relative to %s: %w", sourcePath, outputDir, err)
|
||||
}
|
||||
relative = filepath.ToSlash(relative)
|
||||
embeddable := true
|
||||
if strings.HasPrefix(relative, "..") || s.BuiltIn {
|
||||
embeddable = false
|
||||
}
|
||||
aSources = append(aSources, AugmentedSource{
|
||||
RelativePath: relative,
|
||||
Embeddable: embeddable,
|
||||
BuiltIn: s.BuiltIn,
|
||||
Source: s.Input,
|
||||
})
|
||||
}
|
||||
s.AugmentedSources = aSources
|
||||
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
10
vendor/github.com/99designs/gqlgen/codegen/directives.gotpl
generated
vendored
10
vendor/github.com/99designs/gqlgen/codegen/directives.gotpl
generated
vendored
@ -70,7 +70,7 @@ func (ec *executionContext) _mutationMiddleware(ctx context.Context, obj *ast.Op
|
||||
{{ end }}
|
||||
|
||||
{{ if .Directives.LocationDirectives "SUBSCRIPTION" }}
|
||||
func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) func() graphql.Marshaler {
|
||||
func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) func(ctx context.Context) graphql.Marshaler {
|
||||
for _, d := range obj.Directives {
|
||||
switch d.Name {
|
||||
{{- range $directive := .Directives.LocationDirectives "SUBSCRIPTION" }}
|
||||
@ -80,7 +80,7 @@ func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *as
|
||||
args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return func() graphql.Marshaler {
|
||||
return func(ctx context.Context) graphql.Marshaler {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
@ -98,15 +98,15 @@ func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *as
|
||||
tmp, err := next(ctx)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return func() graphql.Marshaler {
|
||||
return func(ctx context.Context) graphql.Marshaler {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
if data, ok := tmp.(func() graphql.Marshaler); ok {
|
||||
if data, ok := tmp.(func(ctx context.Context) graphql.Marshaler); ok {
|
||||
return data
|
||||
}
|
||||
ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp)
|
||||
return func() graphql.Marshaler {
|
||||
return func(ctx context.Context) graphql.Marshaler {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
|
||||
14
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
14
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
@ -179,8 +179,8 @@ func (b *builder) bindField(obj *Object, f *Field) (errret error) {
|
||||
params = types.NewTuple(vars...)
|
||||
}
|
||||
|
||||
// Try to match target function's arguments with GraphQL field arguments
|
||||
newArgs, err := b.bindArgs(f, params)
|
||||
// Try to match target function's arguments with GraphQL field arguments.
|
||||
newArgs, err := b.bindArgs(f, sig, params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s:%d: %w", pos.Filename, pos.Line, err)
|
||||
}
|
||||
@ -483,6 +483,14 @@ func (f *Field) ArgsFunc() string {
|
||||
return "field_" + f.Object.Definition.Name + "_" + f.Name + "_args"
|
||||
}
|
||||
|
||||
func (f *Field) FieldContextFunc() string {
|
||||
return "fieldContext_" + f.Object.Definition.Name + "_" + f.Name
|
||||
}
|
||||
|
||||
func (f *Field) ChildFieldContextFunc(name string) string {
|
||||
return "fieldContext_" + f.TypeReference.Definition.Name + "_" + name
|
||||
}
|
||||
|
||||
func (f *Field) ResolverType() string {
|
||||
if !f.IsResolver {
|
||||
return ""
|
||||
@ -549,7 +557,7 @@ func (f *Field) CallArgs() string {
|
||||
}
|
||||
|
||||
for _, arg := range f.Args {
|
||||
args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
|
||||
args = append(args, "fc.Args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
|
||||
}
|
||||
|
||||
return strings.Join(args, ", ")
|
||||
|
||||
87
vendor/github.com/99designs/gqlgen/codegen/field.gotpl
generated
vendored
87
vendor/github.com/99designs/gqlgen/codegen/field.gotpl
generated
vendored
@ -1,34 +1,21 @@
|
||||
{{- range $object := .Objects }}{{- range $field := $object.Fields }}
|
||||
|
||||
func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) (ret {{ if $object.Stream }}func(){{ end }}graphql.Marshaler) {
|
||||
func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) (ret {{ if $object.Stream }}func(ctx context.Context){{ end }}graphql.Marshaler) {
|
||||
{{- $null := "graphql.Null" }}
|
||||
{{- if $object.Stream }}
|
||||
{{- $null = "nil" }}
|
||||
{{- end }}
|
||||
fc, err := ec.{{ $field.FieldContextFunc }}(ctx, field)
|
||||
if err != nil {
|
||||
return {{ $null }}
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func () {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = {{ $null }}
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: {{or $field.IsMethod $field.IsResolver}},
|
||||
IsResolver: {{ $field.IsResolver }},
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
{{- if $field.Args }}
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return {{ $null }}
|
||||
}
|
||||
fc.Args = args
|
||||
{{- end }}
|
||||
{{- if $.AllDirectives.LocationDirectives "FIELD" }}
|
||||
resTmp := ec._fieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {
|
||||
{{ template "field" $field }}
|
||||
@ -51,18 +38,22 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
|
||||
return {{ $null }}
|
||||
}
|
||||
{{- if $object.Stream }}
|
||||
return func() graphql.Marshaler {
|
||||
res, ok := <-resTmp.(<-chan {{$field.TypeReference.GO | ref}})
|
||||
if !ok {
|
||||
return func(ctx context.Context) graphql.Marshaler {
|
||||
select {
|
||||
case res, ok := <-resTmp.(<-chan {{$field.TypeReference.GO | ref}}):
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return graphql.WriterFunc(func(w io.Writer) {
|
||||
w.Write([]byte{'{'})
|
||||
graphql.MarshalString(field.Alias).MarshalGQL(w)
|
||||
w.Write([]byte{':'})
|
||||
ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w)
|
||||
w.Write([]byte{'}'})
|
||||
})
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
return graphql.WriterFunc(func(w io.Writer) {
|
||||
w.Write([]byte{'{'})
|
||||
graphql.MarshalString(field.Alias).MarshalGQL(w)
|
||||
w.Write([]byte{':'})
|
||||
ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w)
|
||||
w.Write([]byte{'}'})
|
||||
})
|
||||
}
|
||||
{{- else }}
|
||||
res := resTmp.({{$field.TypeReference.GO | ref}})
|
||||
@ -71,6 +62,44 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (ec *executionContext) {{ $field.FieldContextFunc }}(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: {{quote $field.Object.Name}},
|
||||
Field: field,
|
||||
IsMethod: {{or $field.IsMethod $field.IsResolver}},
|
||||
IsResolver: {{ $field.IsResolver }},
|
||||
Child: func (ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
{{- if not $field.TypeReference.Definition.Fields }}
|
||||
return nil, errors.New("field of type {{ $field.TypeReference.Definition.Name }} does not have child fields")
|
||||
{{- else if ne $field.TypeReference.Definition.Kind "OBJECT" }}
|
||||
return nil, errors.New("FieldContext.Child cannot be called on type {{ $field.TypeReference.Definition.Kind }}")
|
||||
{{- else }}
|
||||
switch field.Name {
|
||||
{{- range $f := $field.TypeReference.Definition.Fields }}
|
||||
case "{{ $f.Name }}":
|
||||
return ec.{{ $field.ChildFieldContextFunc $f.Name }}(ctx, field)
|
||||
{{- end }}
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type {{ $field.TypeReference.Definition.Name }}", field.Name)
|
||||
{{- end }}
|
||||
},
|
||||
}
|
||||
{{- if $field.Args }}
|
||||
defer func () {
|
||||
if r := recover(); r != nil {
|
||||
err = ec.Recover(ctx, r)
|
||||
ec.Error(ctx, err)
|
||||
}
|
||||
}()
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
if fc.Args, err = ec.{{ $field.ArgsFunc }}(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
{{- end }}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
{{- end }}{{- end}}
|
||||
|
||||
{{ define "field" }}
|
||||
|
||||
29
vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
generated
vendored
29
vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
generated
vendored
@ -7,6 +7,7 @@
|
||||
{{ reserveImport "sync/atomic" }}
|
||||
{{ reserveImport "errors" }}
|
||||
{{ reserveImport "bytes" }}
|
||||
{{ reserveImport "embed" }}
|
||||
|
||||
{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }}
|
||||
{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }}
|
||||
@ -135,6 +136,13 @@
|
||||
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
rc := graphql.GetOperationContext(ctx)
|
||||
ec := executionContext{rc, e}
|
||||
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
|
||||
{{- range $input := .Inputs -}}
|
||||
{{ if not $input.HasUnmarshal }}
|
||||
ec.unmarshalInput{{ $input.Name }},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
)
|
||||
first := true
|
||||
|
||||
switch rc.Operation.Operation {
|
||||
@ -142,6 +150,7 @@
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
if !first { return nil }
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
@ -162,6 +171,7 @@
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
if !first { return nil }
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "MUTATION" -}}
|
||||
data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
@ -190,7 +200,7 @@
|
||||
var buf bytes.Buffer
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
buf.Reset()
|
||||
data := next()
|
||||
data := next(ctx)
|
||||
|
||||
if data == nil {
|
||||
return nil
|
||||
@ -226,9 +236,22 @@
|
||||
return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil
|
||||
}
|
||||
|
||||
{{if .HasEmbeddableSources }}
|
||||
//go:embed{{- range $source := .AugmentedSources }}{{if $source.Embeddable}} {{$source.RelativePath|quote}}{{end}}{{- end }}
|
||||
var sourcesFS embed.FS
|
||||
|
||||
func sourceData(filename string) string {
|
||||
data, err := sourcesFS.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("codegen problem: %s not available", filename))
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
var sources = []*ast.Source{
|
||||
{{- range $source := .Config.Sources }}
|
||||
{Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}},
|
||||
{{- range $source := .AugmentedSources }}
|
||||
{Name: {{$source.RelativePath|quote}}, Input: {{if (not $source.Embeddable)}}{{$source.Source|rawQuote}}{{else}}sourceData({{$source.RelativePath|quote}}){{end}}, BuiltIn: {{$source.BuiltIn}}},
|
||||
{{- end }}
|
||||
}
|
||||
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
||||
|
||||
11
vendor/github.com/99designs/gqlgen/codegen/object.gotpl
generated
vendored
11
vendor/github.com/99designs/gqlgen/codegen/object.gotpl
generated
vendored
@ -3,7 +3,7 @@
|
||||
var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}}
|
||||
|
||||
{{- if .Stream }}
|
||||
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {
|
||||
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func(ctx context.Context) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors)
|
||||
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
@ -80,13 +80,12 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec
|
||||
{{end}}
|
||||
})
|
||||
{{- else }}
|
||||
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||
return ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
|
||||
}
|
||||
{{if $object.Root}}
|
||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc)
|
||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||
return ec._{{$object.Name}}_{{$field.Name}}(ctx, field)
|
||||
})
|
||||
{{else}}
|
||||
out.Values[i] = innerFunc(ctx)
|
||||
out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field, obj)
|
||||
{{end}}
|
||||
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
|
||||
30
vendor/github.com/99designs/gqlgen/codegen/root_.gotpl
generated
vendored
30
vendor/github.com/99designs/gqlgen/codegen/root_.gotpl
generated
vendored
@ -7,6 +7,7 @@
|
||||
{{ reserveImport "sync/atomic" }}
|
||||
{{ reserveImport "errors" }}
|
||||
{{ reserveImport "bytes" }}
|
||||
{{ reserveImport "embed" }}
|
||||
|
||||
{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }}
|
||||
{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }}
|
||||
@ -102,6 +103,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
rc := graphql.GetOperationContext(ctx)
|
||||
ec := executionContext{rc, e}
|
||||
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
|
||||
{{- range $input := .Inputs -}}
|
||||
{{ if not $input.HasUnmarshal }}
|
||||
ec.unmarshalInput{{ $input.Name }},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
)
|
||||
first := true
|
||||
|
||||
switch rc.Operation.Operation {
|
||||
@ -109,6 +117,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
if !first { return nil }
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
@ -129,6 +138,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
if !first { return nil }
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "MUTATION" -}}
|
||||
data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
@ -157,7 +167,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
var buf bytes.Buffer
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
buf.Reset()
|
||||
data := next()
|
||||
data := next(ctx)
|
||||
|
||||
if data == nil {
|
||||
return nil
|
||||
@ -193,9 +203,23 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er
|
||||
return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil
|
||||
}
|
||||
|
||||
|
||||
{{if .HasEmbeddableSources }}
|
||||
//go:embed{{- range $source := .AugmentedSources }}{{if $source.Embeddable}} {{$source.RelativePath|quote}}{{end}}{{- end }}
|
||||
var sourcesFS embed.FS
|
||||
|
||||
func sourceData(filename string) string {
|
||||
data, err := sourcesFS.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("codegen problem: %s not available", filename))
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
{{- end}}
|
||||
|
||||
var sources = []*ast.Source{
|
||||
{{- range $source := .Config.Sources }}
|
||||
{Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}},
|
||||
{{- range $source := .AugmentedSources }}
|
||||
{Name: {{$source.RelativePath|quote}}, Input: {{if (not $source.Embeddable)}}{{$source.Source|rawQuote}}{{else}}sourceData({{$source.RelativePath|quote}}){{end}}, BuiltIn: {{$source.BuiltIn}}},
|
||||
{{- end }}
|
||||
}
|
||||
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/codegen/type.gotpl
generated
vendored
4
vendor/github.com/99designs/gqlgen/codegen/type.gotpl
generated
vendored
@ -151,7 +151,7 @@
|
||||
if v == nil {
|
||||
{{- if $type.GQL.NonNull }}
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
{{- end }}
|
||||
return graphql.Null
|
||||
@ -174,7 +174,7 @@
|
||||
{{- if $type.GQL.NonNull }}
|
||||
if res == graphql.Null {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
28
vendor/github.com/99designs/gqlgen/go.mod
generated
vendored
28
vendor/github.com/99designs/gqlgen/go.mod
generated
vendored
@ -3,22 +3,20 @@ module github.com/99designs/gqlgen
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/hashicorp/golang-lru v0.5.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0
|
||||
github.com/matryer/moq v0.2.3
|
||||
github.com/mattn/go-colorable v0.1.4
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/mitchellh/mapstructure v1.2.3
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
github.com/vektah/gqlparser/v2 v2.4.0
|
||||
golang.org/x/tools v0.1.9
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
github.com/matryer/moq v0.2.7
|
||||
github.com/mattn/go-colorable v0.1.12
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/mitchellh/mapstructure v1.3.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/urfave/cli/v2 v2.8.1
|
||||
github.com/vektah/gqlparser/v2 v2.4.4
|
||||
golang.org/x/tools v0.1.10
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/agnivade/levenshtein v1.1.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||
)
|
||||
require github.com/agnivade/levenshtein v1.1.1 // indirect
|
||||
|
||||
80
vendor/github.com/99designs/gqlgen/go.sum
generated
vendored
80
vendor/github.com/99designs/gqlgen/go.sum
generated
vendored
@ -1,12 +1,11 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
|
||||
github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -14,10 +13,13 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0 h1:AQgYHURDOmnVJ62jnEk0W/7yFKEn+Lv8RHN6t7mB0Zo=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
@ -27,73 +29,77 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4=
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
|
||||
github.com/matryer/moq v0.2.3 h1:Q06vEqnBYjjfx5KKgHfYRKE/lvlRu+Nj+xodG4YdHnU=
|
||||
github.com/matryer/moq v0.2.3/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mitchellh/mapstructure v1.2.3 h1:f/MjBEBDLttYCGfRaKBbKSRVF5aV2O6fnBpzknuE3jU=
|
||||
github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/matryer/moq v0.2.7 h1:RtpiPUM8L7ZSCbSwK+QcZH/E9tgqAkFjKQxsRs25b4w=
|
||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
|
||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/vektah/gqlparser/v2 v2.4.0 h1:EmA4dw9mqHm0j6Xzb9T21hOrp3oXmxnS40vwki70DZU=
|
||||
github.com/vektah/gqlparser/v2 v2.4.0/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
|
||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
|
||||
github.com/vektah/gqlparser/v2 v2.4.4 h1:rh9hwZ5Jx9cCq88zXz2YHKmuQBuwY1JErHU8GywFdwE=
|
||||
github.com/vektah/gqlparser/v2 v2.4.4/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
19
vendor/github.com/99designs/gqlgen/graphql/context_field.go
generated
vendored
19
vendor/github.com/99designs/gqlgen/graphql/context_field.go
generated
vendored
@ -30,6 +30,25 @@ type FieldContext struct {
|
||||
IsMethod bool
|
||||
// IsResolver indicates if the field has a user-specified resolver
|
||||
IsResolver bool
|
||||
// Child allows getting a child FieldContext by its field collection description.
|
||||
// Note that, the returned child FieldContext represents the context as it was
|
||||
// before the execution of the field resolver. For example:
|
||||
//
|
||||
// srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (interface{}, error) {
|
||||
// fc := graphql.GetFieldContext(ctx)
|
||||
// op := graphql.GetOperationContext(ctx)
|
||||
// collected := graphql.CollectFields(opCtx, fc.Field.Selections, []string{"User"})
|
||||
//
|
||||
// child, err := fc.Child(ctx, collected[0])
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// fmt.Println("child context %q with args: %v", child.Field.Name, child.Args)
|
||||
//
|
||||
// return next(ctx)
|
||||
// })
|
||||
//
|
||||
Child func(context.Context, CollectedField) (*FieldContext, error)
|
||||
}
|
||||
|
||||
type FieldStats struct {
|
||||
|
||||
11
vendor/github.com/99designs/gqlgen/graphql/executor/executor.go
generated
vendored
11
vendor/github.com/99designs/gqlgen/graphql/executor/executor.go
generated
vendored
@ -67,7 +67,9 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
|
||||
rc.Operation = rc.Doc.Operations.ForName(params.OperationName)
|
||||
if rc.Operation == nil {
|
||||
return rc, gqlerror.List{gqlerror.Errorf("operation %s not found", params.OperationName)}
|
||||
err := gqlerror.Errorf("operation %s not found", params.OperationName)
|
||||
errcode.Set(err, errcode.ValidationFailed)
|
||||
return rc, gqlerror.List{err}
|
||||
}
|
||||
|
||||
var err *gqlerror.Error
|
||||
@ -178,6 +180,13 @@ func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query s
|
||||
stats.Parsing.End = graphql.Now()
|
||||
|
||||
stats.Validation.Start = graphql.Now()
|
||||
|
||||
if len(doc.Operations) == 0 {
|
||||
err = gqlerror.Errorf("no operation provided")
|
||||
errcode.Set(err, errcode.ValidationFailed)
|
||||
return nil, gqlerror.List{err}
|
||||
}
|
||||
|
||||
listErr := validator.Validate(e.es.Schema(), doc)
|
||||
if len(listErr) != 0 {
|
||||
for _, e := range listErr {
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/graphql/handler.go
generated
vendored
1
vendor/github.com/99designs/gqlgen/graphql/handler.go
generated
vendored
@ -27,6 +27,7 @@ type (
|
||||
OperationName string `json:"operationName"`
|
||||
Variables map[string]interface{} `json:"variables"`
|
||||
Extensions map[string]interface{} `json:"extensions"`
|
||||
Headers http.Header `json:"headers"`
|
||||
|
||||
ReadTime TraceTiming `json:"-"`
|
||||
}
|
||||
|
||||
195
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go
generated
vendored
195
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
@ -64,133 +63,145 @@ func (f MultipartForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.G
|
||||
return
|
||||
}
|
||||
r.Body = http.MaxBytesReader(w, r.Body, f.maxUploadSize())
|
||||
if err = r.ParseMultipartForm(f.maxMemory()); err != nil {
|
||||
defer r.Body.Close()
|
||||
|
||||
mr, err := r.MultipartReader()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if strings.Contains(err.Error(), "request body too large") {
|
||||
writeJsonError(w, "failed to parse multipart form, request body too large")
|
||||
return
|
||||
}
|
||||
writeJsonError(w, "failed to parse multipart form")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
part, err := mr.NextPart()
|
||||
if err != nil || part.FormName() != "operations" {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "first part must be operations")
|
||||
return
|
||||
}
|
||||
|
||||
var params graphql.RawParams
|
||||
|
||||
if err = jsonDecode(strings.NewReader(r.Form.Get("operations")), ¶ms); err != nil {
|
||||
if err = jsonDecode(part, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "operations form field could not be decoded")
|
||||
return
|
||||
}
|
||||
|
||||
part, err = mr.NextPart()
|
||||
if err != nil || part.FormName() != "map" {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "second part must be map")
|
||||
return
|
||||
}
|
||||
|
||||
uploadsMap := map[string][]string{}
|
||||
if err = json.Unmarshal([]byte(r.Form.Get("map")), &uploadsMap); err != nil {
|
||||
if err = json.NewDecoder(part).Decode(&uploadsMap); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "map form field could not be decoded")
|
||||
return
|
||||
}
|
||||
|
||||
var upload graphql.Upload
|
||||
for key, paths := range uploadsMap {
|
||||
for {
|
||||
part, err = mr.NextPart()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to parse part")
|
||||
return
|
||||
}
|
||||
|
||||
key := part.FormName()
|
||||
filename := part.FileName()
|
||||
contentType := part.Header.Get("Content-Type")
|
||||
|
||||
paths := uploadsMap[key]
|
||||
if len(paths) == 0 {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "invalid empty operations paths list for key %s", key)
|
||||
return
|
||||
}
|
||||
file, header, err := r.FormFile(key)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to get key %s from form", key)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
delete(uploadsMap, key)
|
||||
|
||||
if len(paths) == 1 {
|
||||
upload = graphql.Upload{
|
||||
File: file,
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
ContentType: header.Header.Get("Content-Type"),
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, paths[0]); err != nil {
|
||||
var upload graphql.Upload
|
||||
if r.ContentLength < f.maxMemory() {
|
||||
fileBytes, err := ioutil.ReadAll(part)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
writeJsonErrorf(w, "failed to read file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
upload = graphql.Upload{
|
||||
File: &bytesReader{s: &fileBytes, i: 0, prevRune: -1},
|
||||
Size: int64(len(fileBytes)),
|
||||
Filename: filename,
|
||||
ContentType: contentType,
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if r.ContentLength < f.maxMemory() {
|
||||
fileBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to read file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
upload = graphql.Upload{
|
||||
File: &bytesReader{s: &fileBytes, i: 0, prevRune: -1},
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
ContentType: header.Header.Get("Content-Type"),
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "gqlgen-")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to create temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
tmpName := tmpFile.Name()
|
||||
defer func() {
|
||||
_ = os.Remove(tmpName)
|
||||
}()
|
||||
_, err = io.Copy(tmpFile, file)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
writeJsonErrorf(w, "failed to copy to temp file and close temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
writeJsonErrorf(w, "failed to copy to temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "gqlgen-")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to create temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
tmpName := tmpFile.Name()
|
||||
defer func() {
|
||||
_ = os.Remove(tmpName)
|
||||
}()
|
||||
fileSize, err := io.Copy(tmpFile, part)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to close temp file for key %s", key)
|
||||
writeJsonErrorf(w, "failed to copy to temp file and close temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
pathTmpFile, err := os.Open(tmpName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to open temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
defer pathTmpFile.Close()
|
||||
upload = graphql.Upload{
|
||||
File: pathTmpFile,
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
ContentType: header.Header.Get("Content-Type"),
|
||||
}
|
||||
writeJsonErrorf(w, "failed to copy to temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to close temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
pathTmpFile, err := os.Open(tmpName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to open temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
defer pathTmpFile.Close()
|
||||
upload = graphql.Upload{
|
||||
File: pathTmpFile,
|
||||
Size: fileSize,
|
||||
Filename: filename,
|
||||
ContentType: contentType,
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for key := range uploadsMap {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to get key %s from form", key)
|
||||
return
|
||||
}
|
||||
|
||||
params.Headers = r.Header
|
||||
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go
generated
vendored
1
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go
generated
vendored
@ -32,6 +32,7 @@ func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecut
|
||||
raw := &graphql.RawParams{
|
||||
Query: r.URL.Query().Get("query"),
|
||||
OperationName: r.URL.Query().Get("operationName"),
|
||||
Headers: r.Header,
|
||||
}
|
||||
raw.ReadTime.Start = graphql.Now()
|
||||
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
@ -36,6 +36,9 @@ func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecu
|
||||
writeJsonErrorf(w, "json body could not be decoded: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
params.Headers = r.Header
|
||||
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
|
||||
15
vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go
generated
vendored
15
vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go
generated
vendored
@ -2,12 +2,16 @@ package transport
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
// Options responds to http OPTIONS and HEAD requests
|
||||
type Options struct{}
|
||||
type Options struct {
|
||||
// AllowedMethods is a list of allowed HTTP methods.
|
||||
AllowedMethods []string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = Options{}
|
||||
|
||||
@ -18,9 +22,16 @@ func (o Options) Supports(r *http.Request) bool {
|
||||
func (o Options) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
switch r.Method {
|
||||
case http.MethodOptions:
|
||||
w.Header().Set("Allow", "OPTIONS, GET, POST")
|
||||
w.Header().Set("Allow", o.allowedMethods())
|
||||
w.WriteHeader(http.StatusOK)
|
||||
case http.MethodHead:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (o Options) allowedMethods() string {
|
||||
if len(o.AllowedMethods) == 0 {
|
||||
return "OPTIONS, GET, POST"
|
||||
}
|
||||
return strings.Join(o.AllowedMethods, ", ")
|
||||
}
|
||||
|
||||
36
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
36
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
@ -49,7 +49,24 @@ type (
|
||||
|
||||
var errReadTimeout = errors.New("read timeout")
|
||||
|
||||
var _ graphql.Transport = Websocket{}
|
||||
type WebsocketError struct {
|
||||
Err error
|
||||
|
||||
// IsReadError flags whether the error occurred on read or write to the websocket
|
||||
IsReadError bool
|
||||
}
|
||||
|
||||
func (e WebsocketError) Error() string {
|
||||
if e.IsReadError {
|
||||
return fmt.Sprintf("websocket read: %v", e.Err)
|
||||
}
|
||||
return fmt.Sprintf("websocket write: %v", e.Err)
|
||||
}
|
||||
|
||||
var (
|
||||
_ graphql.Transport = Websocket{}
|
||||
_ error = WebsocketError{}
|
||||
)
|
||||
|
||||
func (t Websocket) Supports(r *http.Request) bool {
|
||||
return r.Header.Get("Upgrade") != ""
|
||||
@ -94,9 +111,12 @@ func (t Websocket) Do(w http.ResponseWriter, r *http.Request, exec graphql.Graph
|
||||
conn.run()
|
||||
}
|
||||
|
||||
func (c *wsConnection) handlePossibleError(err error) {
|
||||
func (c *wsConnection) handlePossibleError(err error, isReadError bool) {
|
||||
if c.ErrorFunc != nil && err != nil {
|
||||
c.ErrorFunc(c.ctx, err)
|
||||
c.ErrorFunc(c.ctx, WebsocketError{
|
||||
Err: err,
|
||||
IsReadError: isReadError,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +201,7 @@ func (c *wsConnection) init() bool {
|
||||
|
||||
func (c *wsConnection) write(msg *message) {
|
||||
c.mu.Lock()
|
||||
c.handlePossibleError(c.me.Send(msg))
|
||||
c.handlePossibleError(c.me.Send(msg), false)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
@ -227,7 +247,7 @@ func (c *wsConnection) run() {
|
||||
if err != nil {
|
||||
// If the connection got closed by us, don't report the error
|
||||
if !errors.Is(err, net.ErrClosed) {
|
||||
c.handlePossibleError(err)
|
||||
c.handlePossibleError(err, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -358,12 +378,8 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) {
|
||||
|
||||
c.sendResponse(msg.id, response)
|
||||
}
|
||||
c.complete(msg.id)
|
||||
|
||||
c.mu.Lock()
|
||||
delete(c.active, msg.id)
|
||||
c.mu.Unlock()
|
||||
cancel()
|
||||
// complete and context cancel comes from the defer
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md
|
||||
// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md
|
||||
const (
|
||||
graphqltransportwsSubprotocol = "graphql-transport-ws"
|
||||
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go
generated
vendored
@ -7,7 +7,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md
|
||||
// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md
|
||||
const (
|
||||
graphqlwsSubprotocol = "graphql-ws"
|
||||
|
||||
|
||||
55
vendor/github.com/99designs/gqlgen/graphql/input.go
generated
vendored
Normal file
55
vendor/github.com/99designs/gqlgen/graphql/input.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const unmarshalInputCtx key = "unmarshal_input_context"
|
||||
|
||||
// BuildUnmarshalerMap returns a map of unmarshal functions of the ExecutableContext
|
||||
// to use with the WithUnmarshalerMap function.
|
||||
func BuildUnmarshalerMap(unmarshaler ...interface{}) map[reflect.Type]reflect.Value {
|
||||
maps := make(map[reflect.Type]reflect.Value)
|
||||
for _, v := range unmarshaler {
|
||||
ft := reflect.TypeOf(v)
|
||||
if ft.Kind() == reflect.Func {
|
||||
maps[ft.Out(0)] = reflect.ValueOf(v)
|
||||
}
|
||||
}
|
||||
|
||||
return maps
|
||||
}
|
||||
|
||||
// WithUnmarshalerMap returns a new context with a map from input types to their unmarshaler functions.
|
||||
func WithUnmarshalerMap(ctx context.Context, maps map[reflect.Type]reflect.Value) context.Context {
|
||||
return context.WithValue(ctx, unmarshalInputCtx, maps)
|
||||
}
|
||||
|
||||
// UnmarshalInputFromContext allows unmarshaling input object from a context.
|
||||
func UnmarshalInputFromContext(ctx context.Context, raw, v interface{}) error {
|
||||
m, ok := ctx.Value(unmarshalInputCtx).(map[reflect.Type]reflect.Value)
|
||||
if m == nil || !ok {
|
||||
return errors.New("graphql: the input context is empty")
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.Kind() != reflect.Ptr || rv.IsNil() {
|
||||
return errors.New("graphql: input must be a non-nil pointer")
|
||||
}
|
||||
if fn, ok := m[rv.Elem().Type()]; ok {
|
||||
res := fn.Call([]reflect.Value{
|
||||
reflect.ValueOf(ctx),
|
||||
reflect.ValueOf(raw),
|
||||
})
|
||||
if err := res[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
|
||||
rv.Elem().Set(res[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New("graphql: no unmarshal function found")
|
||||
}
|
||||
54
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
54
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
@ -3,6 +3,7 @@ package playground
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
@ -36,14 +37,20 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
></script>
|
||||
|
||||
<script>
|
||||
const url = location.protocol + '//' + location.host + '{{.endpoint}}';
|
||||
{{- if .endpointIsAbsolute}}
|
||||
const url = {{.endpoint}};
|
||||
const subscriptionUrl = {{.subscriptionEndpoint}};
|
||||
{{- else}}
|
||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + '{{.endpoint}}';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
||||
{{- end}}
|
||||
|
||||
const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl });
|
||||
ReactDOM.render(
|
||||
React.createElement(GraphiQL, {
|
||||
fetcher: fetcher,
|
||||
tabs: true,
|
||||
headerEditorEnabled: true,
|
||||
shouldPersistHeaders: true
|
||||
}),
|
||||
@ -54,20 +61,47 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
</html>
|
||||
`))
|
||||
|
||||
// Handler responsible for setting up the playground
|
||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
err := page.Execute(w, map[string]string{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"version": "1.5.16",
|
||||
"cssSRI": "sha256-HADQowUuFum02+Ckkv5Yu5ygRoLllHZqg0TFZXY7NHI=",
|
||||
"jsSRI": "sha256-uHp12yvpXC4PC9+6JmITxKuLYwjlW9crq9ywPE5Rxco=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
err := page.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "1.8.2",
|
||||
"cssSRI": "sha256-CDHiHbYkDSUc3+DS2TU89I9e2W3sJRUOqSmp7JC+LBw=",
|
||||
"jsSRI": "sha256-X8vqrqZ6Rvvoq4tvRVM3LoMZCQH8jwW92tnX0iPiHPc=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endpointHasScheme checks if the endpoint has a scheme.
|
||||
func endpointHasScheme(endpoint string) bool {
|
||||
u, err := url.Parse(endpoint)
|
||||
return err == nil && u.Scheme != ""
|
||||
}
|
||||
|
||||
// getSubscriptionEndpoint returns the subscription endpoint for the given
|
||||
// endpoint if it is parsable as a URL, or an empty string.
|
||||
func getSubscriptionEndpoint(endpoint string) string {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "https":
|
||||
u.Scheme = "wss"
|
||||
default:
|
||||
u.Scheme = "ws"
|
||||
}
|
||||
|
||||
return u.String()
|
||||
}
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
@ -1,3 +1,3 @@
|
||||
package graphql
|
||||
|
||||
const Version = "v0.17.1"
|
||||
const Version = "v0.17.9"
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/internal/code/packages.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/internal/code/packages.go
generated
vendored
@ -17,7 +17,8 @@ var mode = packages.NeedName |
|
||||
packages.NeedTypes |
|
||||
packages.NeedSyntax |
|
||||
packages.NeedTypesInfo |
|
||||
packages.NeedModule
|
||||
packages.NeedModule |
|
||||
packages.NeedDeps
|
||||
|
||||
// Packages is a wrapper around x/tools/go/packages that maintains a (hopefully prewarmed) cache of packages
|
||||
// that can be invalidated as writes are made and packages are known to change.
|
||||
|
||||
73
vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
generated
vendored
73
vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
generated
vendored
@ -16,12 +16,17 @@ import (
|
||||
|
||||
type federation struct {
|
||||
Entities []*Entity
|
||||
Version int
|
||||
}
|
||||
|
||||
// New returns a federation plugin that injects
|
||||
// federated directives and types into the schema
|
||||
func New() plugin.Plugin {
|
||||
return &federation{}
|
||||
func New(version int) plugin.Plugin {
|
||||
if version == 0 {
|
||||
version = 1
|
||||
}
|
||||
|
||||
return &federation{Version: version}
|
||||
}
|
||||
|
||||
// Name returns the plugin name
|
||||
@ -51,6 +56,7 @@ func (f *federation) MutateConfig(cfg *config.Config) error {
|
||||
Model: config.StringList{"github.com/99designs/gqlgen/graphql.Map"},
|
||||
},
|
||||
}
|
||||
|
||||
for typeName, entry := range builtins {
|
||||
if cfg.Models.Exists(typeName) {
|
||||
return fmt.Errorf("%v already exists which must be reserved when Federation is enabled", typeName)
|
||||
@ -63,22 +69,46 @@ func (f *federation) MutateConfig(cfg *config.Config) error {
|
||||
cfg.Directives["key"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
cfg.Directives["extends"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
|
||||
// Federation 2 specific directives
|
||||
if f.Version == 2 {
|
||||
cfg.Directives["shareable"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
cfg.Directives["link"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
cfg.Directives["tag"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
cfg.Directives["override"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
cfg.Directives["inaccessible"] = config.DirectiveConfig{SkipRuntime: true}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *federation) InjectSourceEarly() *ast.Source {
|
||||
input := `
|
||||
scalar _Any
|
||||
scalar _FieldSet
|
||||
|
||||
directive @external on FIELD_DEFINITION
|
||||
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @extends on OBJECT | INTERFACE
|
||||
`
|
||||
// add version-specific changes on key directive, as well as adding the new directives for federation 2
|
||||
if f.Version == 1 {
|
||||
input += `
|
||||
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
|
||||
`
|
||||
} else if f.Version == 2 {
|
||||
input += `
|
||||
directive @key(fields: _FieldSet!, resolvable: Boolean) repeatable on OBJECT | INTERFACE
|
||||
directive @link(import: [String!], url: String!) repeatable on SCHEMA
|
||||
directive @shareable on OBJECT | FIELD_DEFINITION
|
||||
directive @tag repeatable on OBJECT | FIELD_DEFINITION | INTERFACE | UNION
|
||||
directive @override(from: String!) on FIELD_DEFINITION
|
||||
directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
|
||||
`
|
||||
}
|
||||
return &ast.Source{
|
||||
Name: "federation/directives.graphql",
|
||||
Input: `
|
||||
scalar _Any
|
||||
scalar _FieldSet
|
||||
|
||||
directive @external on FIELD_DEFINITION
|
||||
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
|
||||
directive @extends on OBJECT | INTERFACE
|
||||
`,
|
||||
Name: "federation/directives.graphql",
|
||||
Input: input,
|
||||
BuiltIn: true,
|
||||
}
|
||||
}
|
||||
@ -290,10 +320,21 @@ func (f *federation) setEntities(schema *ast.Schema) {
|
||||
// }
|
||||
if !e.allFieldsAreExternal() {
|
||||
for _, dir := range keys {
|
||||
if len(dir.Arguments) != 1 || dir.Arguments[0].Name != "fields" {
|
||||
panic("Exactly one `fields` argument needed for @key declaration.")
|
||||
if len(dir.Arguments) > 2 {
|
||||
panic("More than two arguments provided for @key declaration.")
|
||||
}
|
||||
arg := dir.Arguments[0]
|
||||
var arg *ast.Argument
|
||||
|
||||
// since keys are able to now have multiple arguments, we need to check both possible for a possible @key(fields="" fields="")
|
||||
for _, a := range dir.Arguments {
|
||||
if a.Name == "fields" {
|
||||
if arg != nil {
|
||||
panic("More than one `fields` provided for @key declaration.")
|
||||
}
|
||||
arg = a
|
||||
}
|
||||
}
|
||||
|
||||
keyFieldSet := fieldset.New(arg.Value.Raw, nil)
|
||||
|
||||
keyFields := make([]*KeyField, len(keyFieldSet))
|
||||
|
||||
5
vendor/github.com/PuerkitoBio/purell/.gitignore
generated
vendored
5
vendor/github.com/PuerkitoBio/purell/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
||||
*.sublime-*
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.swo
|
||||
tags
|
||||
12
vendor/github.com/PuerkitoBio/purell/.travis.yml
generated
vendored
12
vendor/github.com/PuerkitoBio/purell/.travis.yml
generated
vendored
@ -1,12 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.x
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- "1.10.x"
|
||||
- "1.11.x"
|
||||
- tip
|
||||
12
vendor/github.com/PuerkitoBio/purell/LICENSE
generated
vendored
12
vendor/github.com/PuerkitoBio/purell/LICENSE
generated
vendored
@ -1,12 +0,0 @@
|
||||
Copyright (c) 2012, Martin Angers
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
188
vendor/github.com/PuerkitoBio/purell/README.md
generated
vendored
188
vendor/github.com/PuerkitoBio/purell/README.md
generated
vendored
@ -1,188 +0,0 @@
|
||||
# Purell
|
||||
|
||||
Purell is a tiny Go library to normalize URLs. It returns a pure URL. Pure-ell. Sanitizer and all. Yeah, I know...
|
||||
|
||||
Based on the [wikipedia paper][wiki] and the [RFC 3986 document][rfc].
|
||||
|
||||
[](http://travis-ci.org/PuerkitoBio/purell)
|
||||
|
||||
## Install
|
||||
|
||||
`go get github.com/PuerkitoBio/purell`
|
||||
|
||||
## Changelog
|
||||
|
||||
* **v1.1.1** : Fix failing test due to Go1.12 changes (thanks to @ianlancetaylor).
|
||||
* **2016-11-14 (v1.1.0)** : IDN: Conform to RFC 5895: Fold character width (thanks to @beeker1121).
|
||||
* **2016-07-27 (v1.0.0)** : Normalize IDN to ASCII (thanks to @zenovich).
|
||||
* **2015-02-08** : Add fix for relative paths issue ([PR #5][pr5]) and add fix for unnecessary encoding of reserved characters ([see issue #7][iss7]).
|
||||
* **v0.2.0** : Add benchmarks, Attempt IDN support.
|
||||
* **v0.1.0** : Initial release.
|
||||
|
||||
## Examples
|
||||
|
||||
From `example_test.go` (note that in your code, you would import "github.com/PuerkitoBio/purell", and would prefix references to its methods and constants with "purell."):
|
||||
|
||||
```go
|
||||
package purell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func ExampleNormalizeURLString() {
|
||||
if normalized, err := NormalizeURLString("hTTp://someWEBsite.com:80/Amazing%3f/url/",
|
||||
FlagLowercaseScheme|FlagLowercaseHost|FlagUppercaseEscapes); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
fmt.Print(normalized)
|
||||
}
|
||||
// Output: http://somewebsite.com:80/Amazing%3F/url/
|
||||
}
|
||||
|
||||
func ExampleMustNormalizeURLString() {
|
||||
normalized := MustNormalizeURLString("hTTpS://someWEBsite.com:443/Amazing%fa/url/",
|
||||
FlagsUnsafeGreedy)
|
||||
fmt.Print(normalized)
|
||||
|
||||
// Output: http://somewebsite.com/Amazing%FA/url
|
||||
}
|
||||
|
||||
func ExampleNormalizeURL() {
|
||||
if u, err := url.Parse("Http://SomeUrl.com:8080/a/b/.././c///g?c=3&a=1&b=9&c=0#target"); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
normalized := NormalizeURL(u, FlagsUsuallySafeGreedy|FlagRemoveDuplicateSlashes|FlagRemoveFragment)
|
||||
fmt.Print(normalized)
|
||||
}
|
||||
|
||||
// Output: http://someurl.com:8080/a/c/g?c=3&a=1&b=9&c=0
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
As seen in the examples above, purell offers three methods, `NormalizeURLString(string, NormalizationFlags) (string, error)`, `MustNormalizeURLString(string, NormalizationFlags) (string)` and `NormalizeURL(*url.URL, NormalizationFlags) (string)`. They all normalize the provided URL based on the specified flags. Here are the available flags:
|
||||
|
||||
```go
|
||||
const (
|
||||
// Safe normalizations
|
||||
FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1
|
||||
FlagLowercaseHost // http://HOST -> http://host
|
||||
FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF
|
||||
FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA
|
||||
FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$
|
||||
FlagRemoveDefaultPort // http://host:80 -> http://host
|
||||
FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path
|
||||
|
||||
// Usually safe normalizations
|
||||
FlagRemoveTrailingSlash // http://host/path/ -> http://host/path
|
||||
FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags)
|
||||
FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c
|
||||
|
||||
// Unsafe normalizations
|
||||
FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/
|
||||
FlagRemoveFragment // http://host/path#fragment -> http://host/path
|
||||
FlagForceHTTP // https://host -> http://host
|
||||
FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b
|
||||
FlagRemoveWWW // http://www.host/ -> http://host/
|
||||
FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags)
|
||||
FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3
|
||||
|
||||
// Normalizations not in the wikipedia article, required to cover tests cases
|
||||
// submitted by jehiah
|
||||
FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147
|
||||
FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147
|
||||
FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147
|
||||
FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path
|
||||
FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path
|
||||
|
||||
// Convenience set of safe normalizations
|
||||
FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator
|
||||
|
||||
// For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags,
|
||||
// while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix".
|
||||
|
||||
// Convenience set of usually safe normalizations (includes FlagsSafe)
|
||||
FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments
|
||||
FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments
|
||||
|
||||
// Convenience set of unsafe normalizations (includes FlagsUsuallySafe)
|
||||
FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery
|
||||
FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery
|
||||
|
||||
// Convenience set of all available flags
|
||||
FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator
|
||||
FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator
|
||||
)
|
||||
```
|
||||
|
||||
For convenience, the set of flags `FlagsSafe`, `FlagsUsuallySafe[Greedy|NonGreedy]`, `FlagsUnsafe[Greedy|NonGreedy]` and `FlagsAll[Greedy|NonGreedy]` are provided for the similarly grouped normalizations on [wikipedia's URL normalization page][wiki]. You can add (using the bitwise OR `|` operator) or remove (using the bitwise AND NOT `&^` operator) individual flags from the sets if required, to build your own custom set.
|
||||
|
||||
The [full godoc reference is available on gopkgdoc][godoc].
|
||||
|
||||
Some things to note:
|
||||
|
||||
* `FlagDecodeUnnecessaryEscapes`, `FlagEncodeNecessaryEscapes`, `FlagUppercaseEscapes` and `FlagRemoveEmptyQuerySeparator` are always implicitly set, because internally, the URL string is parsed as an URL object, which automatically decodes unnecessary escapes, uppercases and encodes necessary ones, and removes empty query separators (an unnecessary `?` at the end of the url). So this operation cannot **not** be done. For this reason, `FlagRemoveEmptyQuerySeparator` (as well as the other three) has been included in the `FlagsSafe` convenience set, instead of `FlagsUnsafe`, where Wikipedia puts it.
|
||||
|
||||
* The `FlagDecodeUnnecessaryEscapes` decodes the following escapes (*from -> to*):
|
||||
- %24 -> $
|
||||
- %26 -> &
|
||||
- %2B-%3B -> +,-./0123456789:;
|
||||
- %3D -> =
|
||||
- %40-%5A -> @ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
- %5F -> _
|
||||
- %61-%7A -> abcdefghijklmnopqrstuvwxyz
|
||||
- %7E -> ~
|
||||
|
||||
|
||||
* When the `NormalizeURL` function is used (passing an URL object), this source URL object is modified (that is, after the call, the URL object will be modified to reflect the normalization).
|
||||
|
||||
* The *replace IP with domain name* normalization (`http://208.77.188.166/ → http://www.example.com/`) is obviously not possible for a library without making some network requests. This is not implemented in purell.
|
||||
|
||||
* The *remove unused query string parameters* and *remove default query parameters* are also not implemented, since this is a very case-specific normalization, and it is quite trivial to do with an URL object.
|
||||
|
||||
### Safe vs Usually Safe vs Unsafe
|
||||
|
||||
Purell allows you to control the level of risk you take while normalizing an URL. You can aggressively normalize, play it totally safe, or anything in between.
|
||||
|
||||
Consider the following URL:
|
||||
|
||||
`HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid`
|
||||
|
||||
Normalizing with the `FlagsSafe` gives:
|
||||
|
||||
`https://www.root.com/toto/tE%1F///a/./b/../c/?z=3&w=2&a=4&w=1#invalid`
|
||||
|
||||
With the `FlagsUsuallySafeGreedy`:
|
||||
|
||||
`https://www.root.com/toto/tE%1F///a/c?z=3&w=2&a=4&w=1#invalid`
|
||||
|
||||
And with `FlagsUnsafeGreedy`:
|
||||
|
||||
`http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3`
|
||||
|
||||
## TODOs
|
||||
|
||||
* Add a class/default instance to allow specifying custom directory index names? At the moment, removing directory index removes `(^|/)((?:default|index)\.\w{1,4})$`.
|
||||
|
||||
## Thanks / Contributions
|
||||
|
||||
@rogpeppe
|
||||
@jehiah
|
||||
@opennota
|
||||
@pchristopher1275
|
||||
@zenovich
|
||||
@beeker1121
|
||||
|
||||
## License
|
||||
|
||||
The [BSD 3-Clause license][bsd].
|
||||
|
||||
[bsd]: http://opensource.org/licenses/BSD-3-Clause
|
||||
[wiki]: http://en.wikipedia.org/wiki/URL_normalization
|
||||
[rfc]: http://tools.ietf.org/html/rfc3986#section-6
|
||||
[godoc]: http://go.pkgdoc.org/github.com/PuerkitoBio/purell
|
||||
[pr5]: https://github.com/PuerkitoBio/purell/pull/5
|
||||
[iss7]: https://github.com/PuerkitoBio/purell/issues/7
|
||||
379
vendor/github.com/PuerkitoBio/purell/purell.go
generated
vendored
379
vendor/github.com/PuerkitoBio/purell/purell.go
generated
vendored
@ -1,379 +0,0 @@
|
||||
/*
|
||||
Package purell offers URL normalization as described on the wikipedia page:
|
||||
http://en.wikipedia.org/wiki/URL_normalization
|
||||
*/
|
||||
package purell
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/urlesc"
|
||||
"golang.org/x/net/idna"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
"golang.org/x/text/width"
|
||||
)
|
||||
|
||||
// A set of normalization flags determines how a URL will
|
||||
// be normalized.
|
||||
type NormalizationFlags uint
|
||||
|
||||
const (
|
||||
// Safe normalizations
|
||||
FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1
|
||||
FlagLowercaseHost // http://HOST -> http://host
|
||||
FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF
|
||||
FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA
|
||||
FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$
|
||||
FlagRemoveDefaultPort // http://host:80 -> http://host
|
||||
FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path
|
||||
|
||||
// Usually safe normalizations
|
||||
FlagRemoveTrailingSlash // http://host/path/ -> http://host/path
|
||||
FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags)
|
||||
FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c
|
||||
|
||||
// Unsafe normalizations
|
||||
FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/
|
||||
FlagRemoveFragment // http://host/path#fragment -> http://host/path
|
||||
FlagForceHTTP // https://host -> http://host
|
||||
FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b
|
||||
FlagRemoveWWW // http://www.host/ -> http://host/
|
||||
FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags)
|
||||
FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3
|
||||
|
||||
// Normalizations not in the wikipedia article, required to cover tests cases
|
||||
// submitted by jehiah
|
||||
FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147
|
||||
FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147
|
||||
FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147
|
||||
FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path
|
||||
FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path
|
||||
|
||||
// Convenience set of safe normalizations
|
||||
FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator
|
||||
|
||||
// For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags,
|
||||
// while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix".
|
||||
|
||||
// Convenience set of usually safe normalizations (includes FlagsSafe)
|
||||
FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments
|
||||
FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments
|
||||
|
||||
// Convenience set of unsafe normalizations (includes FlagsUsuallySafe)
|
||||
FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery
|
||||
FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery
|
||||
|
||||
// Convenience set of all available flags
|
||||
FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator
|
||||
FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator
|
||||
)
|
||||
|
||||
const (
|
||||
defaultHttpPort = ":80"
|
||||
defaultHttpsPort = ":443"
|
||||
)
|
||||
|
||||
// Regular expressions used by the normalizations
|
||||
var rxPort = regexp.MustCompile(`(:\d+)/?$`)
|
||||
var rxDirIndex = regexp.MustCompile(`(^|/)((?:default|index)\.\w{1,4})$`)
|
||||
var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
||||
var rxDWORDHost = regexp.MustCompile(`^(\d+)((?:\.+)?(?:\:\d*)?)$`)
|
||||
var rxOctalHost = regexp.MustCompile(`^(0\d*)\.(0\d*)\.(0\d*)\.(0\d*)((?:\.+)?(?:\:\d*)?)$`)
|
||||
var rxHexHost = regexp.MustCompile(`^0x([0-9A-Fa-f]+)((?:\.+)?(?:\:\d*)?)$`)
|
||||
var rxHostDots = regexp.MustCompile(`^(.+?)(:\d+)?$`)
|
||||
var rxEmptyPort = regexp.MustCompile(`:+$`)
|
||||
|
||||
// Map of flags to implementation function.
|
||||
// FlagDecodeUnnecessaryEscapes has no action, since it is done automatically
|
||||
// by parsing the string as an URL. Same for FlagUppercaseEscapes and FlagRemoveEmptyQuerySeparator.
|
||||
|
||||
// Since maps have undefined traversing order, make a slice of ordered keys
|
||||
var flagsOrder = []NormalizationFlags{
|
||||
FlagLowercaseScheme,
|
||||
FlagLowercaseHost,
|
||||
FlagRemoveDefaultPort,
|
||||
FlagRemoveDirectoryIndex,
|
||||
FlagRemoveDotSegments,
|
||||
FlagRemoveFragment,
|
||||
FlagForceHTTP, // Must be after remove default port (because https=443/http=80)
|
||||
FlagRemoveDuplicateSlashes,
|
||||
FlagRemoveWWW,
|
||||
FlagAddWWW,
|
||||
FlagSortQuery,
|
||||
FlagDecodeDWORDHost,
|
||||
FlagDecodeOctalHost,
|
||||
FlagDecodeHexHost,
|
||||
FlagRemoveUnnecessaryHostDots,
|
||||
FlagRemoveEmptyPortSeparator,
|
||||
FlagRemoveTrailingSlash, // These two (add/remove trailing slash) must be last
|
||||
FlagAddTrailingSlash,
|
||||
}
|
||||
|
||||
// ... and then the map, where order is unimportant
|
||||
var flags = map[NormalizationFlags]func(*url.URL){
|
||||
FlagLowercaseScheme: lowercaseScheme,
|
||||
FlagLowercaseHost: lowercaseHost,
|
||||
FlagRemoveDefaultPort: removeDefaultPort,
|
||||
FlagRemoveDirectoryIndex: removeDirectoryIndex,
|
||||
FlagRemoveDotSegments: removeDotSegments,
|
||||
FlagRemoveFragment: removeFragment,
|
||||
FlagForceHTTP: forceHTTP,
|
||||
FlagRemoveDuplicateSlashes: removeDuplicateSlashes,
|
||||
FlagRemoveWWW: removeWWW,
|
||||
FlagAddWWW: addWWW,
|
||||
FlagSortQuery: sortQuery,
|
||||
FlagDecodeDWORDHost: decodeDWORDHost,
|
||||
FlagDecodeOctalHost: decodeOctalHost,
|
||||
FlagDecodeHexHost: decodeHexHost,
|
||||
FlagRemoveUnnecessaryHostDots: removeUnncessaryHostDots,
|
||||
FlagRemoveEmptyPortSeparator: removeEmptyPortSeparator,
|
||||
FlagRemoveTrailingSlash: removeTrailingSlash,
|
||||
FlagAddTrailingSlash: addTrailingSlash,
|
||||
}
|
||||
|
||||
// MustNormalizeURLString returns the normalized string, and panics if an error occurs.
|
||||
// It takes an URL string as input, as well as the normalization flags.
|
||||
func MustNormalizeURLString(u string, f NormalizationFlags) string {
|
||||
result, e := NormalizeURLString(u, f)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// NormalizeURLString returns the normalized string, or an error if it can't be parsed into an URL object.
|
||||
// It takes an URL string as input, as well as the normalization flags.
|
||||
func NormalizeURLString(u string, f NormalizationFlags) (string, error) {
|
||||
parsed, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if f&FlagLowercaseHost == FlagLowercaseHost {
|
||||
parsed.Host = strings.ToLower(parsed.Host)
|
||||
}
|
||||
|
||||
// The idna package doesn't fully conform to RFC 5895
|
||||
// (https://tools.ietf.org/html/rfc5895), so we do it here.
|
||||
// Taken from Go 1.8 cycle source, courtesy of bradfitz.
|
||||
// TODO: Remove when (if?) idna package conforms to RFC 5895.
|
||||
parsed.Host = width.Fold.String(parsed.Host)
|
||||
parsed.Host = norm.NFC.String(parsed.Host)
|
||||
if parsed.Host, err = idna.ToASCII(parsed.Host); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return NormalizeURL(parsed, f), nil
|
||||
}
|
||||
|
||||
// NormalizeURL returns the normalized string.
|
||||
// It takes a parsed URL object as input, as well as the normalization flags.
|
||||
func NormalizeURL(u *url.URL, f NormalizationFlags) string {
|
||||
for _, k := range flagsOrder {
|
||||
if f&k == k {
|
||||
flags[k](u)
|
||||
}
|
||||
}
|
||||
return urlesc.Escape(u)
|
||||
}
|
||||
|
||||
func lowercaseScheme(u *url.URL) {
|
||||
if len(u.Scheme) > 0 {
|
||||
u.Scheme = strings.ToLower(u.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
func lowercaseHost(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
u.Host = strings.ToLower(u.Host)
|
||||
}
|
||||
}
|
||||
|
||||
func removeDefaultPort(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
scheme := strings.ToLower(u.Scheme)
|
||||
u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {
|
||||
if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) {
|
||||
return ""
|
||||
}
|
||||
return val
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func removeTrailingSlash(u *url.URL) {
|
||||
if l := len(u.Path); l > 0 {
|
||||
if strings.HasSuffix(u.Path, "/") {
|
||||
u.Path = u.Path[:l-1]
|
||||
}
|
||||
} else if l = len(u.Host); l > 0 {
|
||||
if strings.HasSuffix(u.Host, "/") {
|
||||
u.Host = u.Host[:l-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addTrailingSlash(u *url.URL) {
|
||||
if l := len(u.Path); l > 0 {
|
||||
if !strings.HasSuffix(u.Path, "/") {
|
||||
u.Path += "/"
|
||||
}
|
||||
} else if l = len(u.Host); l > 0 {
|
||||
if !strings.HasSuffix(u.Host, "/") {
|
||||
u.Host += "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeDotSegments(u *url.URL) {
|
||||
if len(u.Path) > 0 {
|
||||
var dotFree []string
|
||||
var lastIsDot bool
|
||||
|
||||
sections := strings.Split(u.Path, "/")
|
||||
for _, s := range sections {
|
||||
if s == ".." {
|
||||
if len(dotFree) > 0 {
|
||||
dotFree = dotFree[:len(dotFree)-1]
|
||||
}
|
||||
} else if s != "." {
|
||||
dotFree = append(dotFree, s)
|
||||
}
|
||||
lastIsDot = (s == "." || s == "..")
|
||||
}
|
||||
// Special case if host does not end with / and new path does not begin with /
|
||||
u.Path = strings.Join(dotFree, "/")
|
||||
if u.Host != "" && !strings.HasSuffix(u.Host, "/") && !strings.HasPrefix(u.Path, "/") {
|
||||
u.Path = "/" + u.Path
|
||||
}
|
||||
// Special case if the last segment was a dot, make sure the path ends with a slash
|
||||
if lastIsDot && !strings.HasSuffix(u.Path, "/") {
|
||||
u.Path += "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeDirectoryIndex(u *url.URL) {
|
||||
if len(u.Path) > 0 {
|
||||
u.Path = rxDirIndex.ReplaceAllString(u.Path, "$1")
|
||||
}
|
||||
}
|
||||
|
||||
func removeFragment(u *url.URL) {
|
||||
u.Fragment = ""
|
||||
}
|
||||
|
||||
func forceHTTP(u *url.URL) {
|
||||
if strings.ToLower(u.Scheme) == "https" {
|
||||
u.Scheme = "http"
|
||||
}
|
||||
}
|
||||
|
||||
func removeDuplicateSlashes(u *url.URL) {
|
||||
if len(u.Path) > 0 {
|
||||
u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/")
|
||||
}
|
||||
}
|
||||
|
||||
func removeWWW(u *url.URL) {
|
||||
if len(u.Host) > 0 && strings.HasPrefix(strings.ToLower(u.Host), "www.") {
|
||||
u.Host = u.Host[4:]
|
||||
}
|
||||
}
|
||||
|
||||
func addWWW(u *url.URL) {
|
||||
if len(u.Host) > 0 && !strings.HasPrefix(strings.ToLower(u.Host), "www.") {
|
||||
u.Host = "www." + u.Host
|
||||
}
|
||||
}
|
||||
|
||||
func sortQuery(u *url.URL) {
|
||||
q := u.Query()
|
||||
|
||||
if len(q) > 0 {
|
||||
arKeys := make([]string, len(q))
|
||||
i := 0
|
||||
for k := range q {
|
||||
arKeys[i] = k
|
||||
i++
|
||||
}
|
||||
sort.Strings(arKeys)
|
||||
buf := new(bytes.Buffer)
|
||||
for _, k := range arKeys {
|
||||
sort.Strings(q[k])
|
||||
for _, v := range q[k] {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteRune('&')
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%s=%s", k, urlesc.QueryEscape(v)))
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild the raw query string
|
||||
u.RawQuery = buf.String()
|
||||
}
|
||||
}
|
||||
|
||||
func decodeDWORDHost(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
if matches := rxDWORDHost.FindStringSubmatch(u.Host); len(matches) > 2 {
|
||||
var parts [4]int64
|
||||
|
||||
dword, _ := strconv.ParseInt(matches[1], 10, 0)
|
||||
for i, shift := range []uint{24, 16, 8, 0} {
|
||||
parts[i] = dword >> shift & 0xFF
|
||||
}
|
||||
u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeOctalHost(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
if matches := rxOctalHost.FindStringSubmatch(u.Host); len(matches) > 5 {
|
||||
var parts [4]int64
|
||||
|
||||
for i := 1; i <= 4; i++ {
|
||||
parts[i-1], _ = strconv.ParseInt(matches[i], 8, 0)
|
||||
}
|
||||
u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[5])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeHexHost(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
if matches := rxHexHost.FindStringSubmatch(u.Host); len(matches) > 2 {
|
||||
// Conversion is safe because of regex validation
|
||||
parsed, _ := strconv.ParseInt(matches[1], 16, 0)
|
||||
// Set host as DWORD (base 10) encoded host
|
||||
u.Host = fmt.Sprintf("%d%s", parsed, matches[2])
|
||||
// The rest is the same as decoding a DWORD host
|
||||
decodeDWORDHost(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeUnncessaryHostDots(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
if matches := rxHostDots.FindStringSubmatch(u.Host); len(matches) > 1 {
|
||||
// Trim the leading and trailing dots
|
||||
u.Host = strings.Trim(matches[1], ".")
|
||||
if len(matches) > 2 {
|
||||
u.Host += matches[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeEmptyPortSeparator(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
u.Host = rxEmptyPort.ReplaceAllString(u.Host, "")
|
||||
}
|
||||
}
|
||||
15
vendor/github.com/PuerkitoBio/urlesc/.travis.yml
generated
vendored
15
vendor/github.com/PuerkitoBio/urlesc/.travis.yml
generated
vendored
@ -1,15 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.x
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go build .
|
||||
|
||||
script:
|
||||
- go test -v
|
||||
27
vendor/github.com/PuerkitoBio/urlesc/LICENSE
generated
vendored
27
vendor/github.com/PuerkitoBio/urlesc/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
16
vendor/github.com/PuerkitoBio/urlesc/README.md
generated
vendored
16
vendor/github.com/PuerkitoBio/urlesc/README.md
generated
vendored
@ -1,16 +0,0 @@
|
||||
urlesc [](https://travis-ci.org/PuerkitoBio/urlesc) [](http://godoc.org/github.com/PuerkitoBio/urlesc)
|
||||
======
|
||||
|
||||
Package urlesc implements query escaping as per RFC 3986.
|
||||
|
||||
It contains some parts of the net/url package, modified so as to allow
|
||||
some reserved characters incorrectly escaped by net/url (see [issue 5684](https://github.com/golang/go/issues/5684)).
|
||||
|
||||
## Install
|
||||
|
||||
go get github.com/PuerkitoBio/urlesc
|
||||
|
||||
## License
|
||||
|
||||
Go license (BSD-3-Clause)
|
||||
|
||||
180
vendor/github.com/PuerkitoBio/urlesc/urlesc.go
generated
vendored
180
vendor/github.com/PuerkitoBio/urlesc/urlesc.go
generated
vendored
@ -1,180 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package urlesc implements query escaping as per RFC 3986.
|
||||
// It contains some parts of the net/url package, modified so as to allow
|
||||
// some reserved characters incorrectly escaped by net/url.
|
||||
// See https://github.com/golang/go/issues/5684
|
||||
package urlesc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type encoding int
|
||||
|
||||
const (
|
||||
encodePath encoding = 1 + iota
|
||||
encodeUserPassword
|
||||
encodeQueryComponent
|
||||
encodeFragment
|
||||
)
|
||||
|
||||
// Return true if the specified character should be escaped when
|
||||
// appearing in a URL string, according to RFC 3986.
|
||||
func shouldEscape(c byte, mode encoding) bool {
|
||||
// §2.3 Unreserved characters (alphanum)
|
||||
if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' {
|
||||
return false
|
||||
}
|
||||
|
||||
switch c {
|
||||
case '-', '.', '_', '~': // §2.3 Unreserved characters (mark)
|
||||
return false
|
||||
|
||||
// §2.2 Reserved characters (reserved)
|
||||
case ':', '/', '?', '#', '[', ']', '@', // gen-delims
|
||||
'!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // sub-delims
|
||||
// Different sections of the URL allow a few of
|
||||
// the reserved characters to appear unescaped.
|
||||
switch mode {
|
||||
case encodePath: // §3.3
|
||||
// The RFC allows sub-delims and : @.
|
||||
// '/', '[' and ']' can be used to assign meaning to individual path
|
||||
// segments. This package only manipulates the path as a whole,
|
||||
// so we allow those as well. That leaves only ? and # to escape.
|
||||
return c == '?' || c == '#'
|
||||
|
||||
case encodeUserPassword: // §3.2.1
|
||||
// The RFC allows : and sub-delims in
|
||||
// userinfo. The parsing of userinfo treats ':' as special so we must escape
|
||||
// all the gen-delims.
|
||||
return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' || c == '@'
|
||||
|
||||
case encodeQueryComponent: // §3.4
|
||||
// The RFC allows / and ?.
|
||||
return c != '/' && c != '?'
|
||||
|
||||
case encodeFragment: // §4.1
|
||||
// The RFC text is silent but the grammar allows
|
||||
// everything, so escape nothing but #
|
||||
return c == '#'
|
||||
}
|
||||
}
|
||||
|
||||
// Everything else must be escaped.
|
||||
return true
|
||||
}
|
||||
|
||||
// QueryEscape escapes the string so it can be safely placed
|
||||
// inside a URL query.
|
||||
func QueryEscape(s string) string {
|
||||
return escape(s, encodeQueryComponent)
|
||||
}
|
||||
|
||||
func escape(s string, mode encoding) string {
|
||||
spaceCount, hexCount := 0, 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if shouldEscape(c, mode) {
|
||||
if c == ' ' && mode == encodeQueryComponent {
|
||||
spaceCount++
|
||||
} else {
|
||||
hexCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if spaceCount == 0 && hexCount == 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
t := make([]byte, len(s)+2*hexCount)
|
||||
j := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch c := s[i]; {
|
||||
case c == ' ' && mode == encodeQueryComponent:
|
||||
t[j] = '+'
|
||||
j++
|
||||
case shouldEscape(c, mode):
|
||||
t[j] = '%'
|
||||
t[j+1] = "0123456789ABCDEF"[c>>4]
|
||||
t[j+2] = "0123456789ABCDEF"[c&15]
|
||||
j += 3
|
||||
default:
|
||||
t[j] = s[i]
|
||||
j++
|
||||
}
|
||||
}
|
||||
return string(t)
|
||||
}
|
||||
|
||||
var uiReplacer = strings.NewReplacer(
|
||||
"%21", "!",
|
||||
"%27", "'",
|
||||
"%28", "(",
|
||||
"%29", ")",
|
||||
"%2A", "*",
|
||||
)
|
||||
|
||||
// unescapeUserinfo unescapes some characters that need not to be escaped as per RFC3986.
|
||||
func unescapeUserinfo(s string) string {
|
||||
return uiReplacer.Replace(s)
|
||||
}
|
||||
|
||||
// Escape reassembles the URL into a valid URL string.
|
||||
// The general form of the result is one of:
|
||||
//
|
||||
// scheme:opaque
|
||||
// scheme://userinfo@host/path?query#fragment
|
||||
//
|
||||
// If u.Opaque is non-empty, String uses the first form;
|
||||
// otherwise it uses the second form.
|
||||
//
|
||||
// In the second form, the following rules apply:
|
||||
// - if u.Scheme is empty, scheme: is omitted.
|
||||
// - if u.User is nil, userinfo@ is omitted.
|
||||
// - if u.Host is empty, host/ is omitted.
|
||||
// - if u.Scheme and u.Host are empty and u.User is nil,
|
||||
// the entire scheme://userinfo@host/ is omitted.
|
||||
// - if u.Host is non-empty and u.Path begins with a /,
|
||||
// the form host/path does not add its own /.
|
||||
// - if u.RawQuery is empty, ?query is omitted.
|
||||
// - if u.Fragment is empty, #fragment is omitted.
|
||||
func Escape(u *url.URL) string {
|
||||
var buf bytes.Buffer
|
||||
if u.Scheme != "" {
|
||||
buf.WriteString(u.Scheme)
|
||||
buf.WriteByte(':')
|
||||
}
|
||||
if u.Opaque != "" {
|
||||
buf.WriteString(u.Opaque)
|
||||
} else {
|
||||
if u.Scheme != "" || u.Host != "" || u.User != nil {
|
||||
buf.WriteString("//")
|
||||
if ui := u.User; ui != nil {
|
||||
buf.WriteString(unescapeUserinfo(ui.String()))
|
||||
buf.WriteByte('@')
|
||||
}
|
||||
if h := u.Host; h != "" {
|
||||
buf.WriteString(h)
|
||||
}
|
||||
}
|
||||
if u.Path != "" && u.Path[0] != '/' && u.Host != "" {
|
||||
buf.WriteByte('/')
|
||||
}
|
||||
buf.WriteString(escape(u.Path, encodePath))
|
||||
}
|
||||
if u.RawQuery != "" {
|
||||
buf.WriteByte('?')
|
||||
buf.WriteString(u.RawQuery)
|
||||
}
|
||||
if u.Fragment != "" {
|
||||
buf.WriteByte('#')
|
||||
buf.WriteString(escape(u.Fragment, encodeFragment))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
3
vendor/github.com/go-openapi/jsonreference/go.mod
generated
vendored
3
vendor/github.com/go-openapi/jsonreference/go.mod
generated
vendored
@ -1,11 +1,8 @@
|
||||
module github.com/go-openapi/jsonreference
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/purell v1.1.1
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.3
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 // indirect
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
||||
12
vendor/github.com/go-openapi/jsonreference/go.sum
generated
vendored
12
vendor/github.com/go-openapi/jsonreference/go.sum
generated
vendored
@ -1,7 +1,3 @@
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -22,14 +18,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
63
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
Normal file
63
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultHttpPort = ":80"
|
||||
defaultHttpsPort = ":443"
|
||||
)
|
||||
|
||||
// Regular expressions used by the normalizations
|
||||
var rxPort = regexp.MustCompile(`(:\d+)/?$`)
|
||||
var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
||||
|
||||
// NormalizeURL will normalize the specified URL
|
||||
// This was added to replace a previous call to the no longer maintained purell library:
|
||||
// The call that was used looked like the following:
|
||||
// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
|
||||
//
|
||||
// To explain all that was included in the call above, purell.FlagsSafe was really just the following:
|
||||
// - FlagLowercaseScheme
|
||||
// - FlagLowercaseHost
|
||||
// - FlagRemoveDefaultPort
|
||||
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
|
||||
func NormalizeURL(u *url.URL) {
|
||||
lowercaseScheme(u)
|
||||
lowercaseHost(u)
|
||||
removeDefaultPort(u)
|
||||
removeDuplicateSlashes(u)
|
||||
}
|
||||
|
||||
func lowercaseScheme(u *url.URL) {
|
||||
if len(u.Scheme) > 0 {
|
||||
u.Scheme = strings.ToLower(u.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
func lowercaseHost(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
u.Host = strings.ToLower(u.Host)
|
||||
}
|
||||
}
|
||||
|
||||
func removeDefaultPort(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
scheme := strings.ToLower(u.Scheme)
|
||||
u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {
|
||||
if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) {
|
||||
return ""
|
||||
}
|
||||
return val
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func removeDuplicateSlashes(u *url.URL) {
|
||||
if len(u.Path) > 0 {
|
||||
u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/")
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/go-openapi/jsonreference/reference.go
generated
vendored
6
vendor/github.com/go-openapi/jsonreference/reference.go
generated
vendored
@ -30,8 +30,8 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/purell"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/jsonreference/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -114,7 +114,9 @@ func (r *Ref) parse(jsonReferenceString string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
r.referenceURL, _ = url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
|
||||
internal.NormalizeURL(parsed)
|
||||
|
||||
r.referenceURL = parsed
|
||||
refURL := r.referenceURL
|
||||
|
||||
if refURL.Scheme != "" && refURL.Host != "" {
|
||||
|
||||
3
vendor/github.com/go-openapi/spec/go.mod
generated
vendored
3
vendor/github.com/go-openapi/spec/go.mod
generated
vendored
@ -2,10 +2,9 @@ module github.com/go-openapi/spec
|
||||
|
||||
require (
|
||||
github.com/go-openapi/jsonpointer v0.19.5
|
||||
github.com/go-openapi/jsonreference v0.19.6
|
||||
github.com/go-openapi/jsonreference v0.20.0
|
||||
github.com/go-openapi/swag v0.19.15
|
||||
github.com/stretchr/testify v1.6.1
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
|
||||
22
vendor/github.com/go-openapi/spec/go.sum
generated
vendored
22
vendor/github.com/go-openapi/spec/go.sum
generated
vendored
@ -1,17 +1,12 @@
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
@ -19,12 +14,10 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
@ -33,19 +26,9 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
@ -53,7 +36,6 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
17
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
17
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
@ -1,7 +1,7 @@
|
||||
Package validator
|
||||
=================
|
||||
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||

|
||||

|
||||
[](https://travis-ci.org/go-playground/validator)
|
||||
[](https://coveralls.io/github/go-playground/validator?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/go-playground/validator)
|
||||
@ -130,7 +130,7 @@ Baked-in Validations
|
||||
| contains | Contains |
|
||||
| containsany | Contains Any |
|
||||
| containsrune | Contains Rune |
|
||||
| endsnotwith | Ends With |
|
||||
| endsnotwith | Ends Not With |
|
||||
| endswith | Ends With |
|
||||
| excludes | Excludes |
|
||||
| excludesall | Excludes All |
|
||||
@ -153,6 +153,7 @@ Baked-in Validations
|
||||
| bcp47_language_tag | Language tag (BCP 47) |
|
||||
| btc_addr | Bitcoin Address |
|
||||
| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
|
||||
| credit_card | Credit Card Number |
|
||||
| datetime | Datetime |
|
||||
| e164 | e164 formatted phone number |
|
||||
| email | E-mail String
|
||||
@ -189,6 +190,16 @@ Baked-in Validations
|
||||
| uuid5 | Universally Unique Identifier UUID v5 |
|
||||
| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
|
||||
| uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 |
|
||||
| md4 | MD4 hash |
|
||||
| md5 | MD5 hash |
|
||||
| sha256 | SHA256 hash |
|
||||
| sha384 | SHA384 hash |
|
||||
| sha512 | SHA512 hash |
|
||||
| ripemd128 | RIPEMD-128 hash |
|
||||
| ripemd128 | RIPEMD-160 hash |
|
||||
| tiger128 | TIGER128 hash |
|
||||
| tiger160 | TIGER160 hash |
|
||||
| tiger192 | TIGER192 hash |
|
||||
| semver | Semantic Versioning 2.0.0 |
|
||||
| ulid | Universally Unique Lexicographically Sortable Identifier ULID |
|
||||
|
||||
@ -219,6 +230,8 @@ Baked-in Validations
|
||||
| required_with_all | Required With All |
|
||||
| required_without | Required Without |
|
||||
| required_without_all | Required Without All |
|
||||
| excluded_if | Excluded If |
|
||||
| excluded_unless | Excluded Unless |
|
||||
| excluded_with | Excluded With |
|
||||
| excluded_with_all | Excluded With All |
|
||||
| excluded_without | Excluded Without |
|
||||
|
||||
391
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
391
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
@ -75,6 +75,8 @@ var (
|
||||
"required_with_all": requiredWithAll,
|
||||
"required_without": requiredWithout,
|
||||
"required_without_all": requiredWithoutAll,
|
||||
"excluded_if": excludedIf,
|
||||
"excluded_unless": excludedUnless,
|
||||
"excluded_with": excludedWith,
|
||||
"excluded_with_all": excludedWithAll,
|
||||
"excluded_without": excludedWithout,
|
||||
@ -149,6 +151,16 @@ var (
|
||||
"uuid4_rfc4122": isUUID4RFC4122,
|
||||
"uuid5_rfc4122": isUUID5RFC4122,
|
||||
"ulid": isULID,
|
||||
"md4": isMD4,
|
||||
"md5": isMD5,
|
||||
"sha256": isSHA256,
|
||||
"sha384": isSHA384,
|
||||
"sha512": isSHA512,
|
||||
"ripemd128": isRIPEMD128,
|
||||
"ripemd160": isRIPEMD160,
|
||||
"tiger128": isTIGER128,
|
||||
"tiger160": isTIGER160,
|
||||
"tiger192": isTIGER192,
|
||||
"ascii": isASCII,
|
||||
"printascii": isPrintableASCII,
|
||||
"multibyte": hasMultiByteCharacter,
|
||||
@ -201,11 +213,14 @@ var (
|
||||
"bic": isIsoBicFormat,
|
||||
"semver": isSemverFormat,
|
||||
"dns_rfc1035_label": isDnsRFC1035LabelFormat,
|
||||
"credit_card": isCreditCard,
|
||||
}
|
||||
)
|
||||
|
||||
var oneofValsCache = map[string][]string{}
|
||||
var oneofValsCacheRWLock = sync.RWMutex{}
|
||||
var (
|
||||
oneofValsCache = map[string][]string{}
|
||||
oneofValsCacheRWLock = sync.RWMutex{}
|
||||
)
|
||||
|
||||
func parseOneOfParam2(s string) []string {
|
||||
oneofValsCacheRWLock.RLock()
|
||||
@ -261,7 +276,6 @@ func isOneOf(fl FieldLevel) bool {
|
||||
|
||||
// isUnique is the validation function for validating if each array|slice|map value is unique
|
||||
func isUnique(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
v := reflect.ValueOf(struct{}{})
|
||||
@ -311,7 +325,6 @@ func isUnique(fl FieldLevel) bool {
|
||||
|
||||
// isMAC is the validation function for validating if the field's value is a valid MAC address.
|
||||
func isMAC(fl FieldLevel) bool {
|
||||
|
||||
_, err := net.ParseMAC(fl.Field().String())
|
||||
|
||||
return err == nil
|
||||
@ -319,7 +332,6 @@ func isMAC(fl FieldLevel) bool {
|
||||
|
||||
// isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
|
||||
func isCIDRv4(fl FieldLevel) bool {
|
||||
|
||||
ip, _, err := net.ParseCIDR(fl.Field().String())
|
||||
|
||||
return err == nil && ip.To4() != nil
|
||||
@ -327,7 +339,6 @@ func isCIDRv4(fl FieldLevel) bool {
|
||||
|
||||
// isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
|
||||
func isCIDRv6(fl FieldLevel) bool {
|
||||
|
||||
ip, _, err := net.ParseCIDR(fl.Field().String())
|
||||
|
||||
return err == nil && ip.To4() == nil
|
||||
@ -335,7 +346,6 @@ func isCIDRv6(fl FieldLevel) bool {
|
||||
|
||||
// isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
|
||||
func isCIDR(fl FieldLevel) bool {
|
||||
|
||||
_, _, err := net.ParseCIDR(fl.Field().String())
|
||||
|
||||
return err == nil
|
||||
@ -343,7 +353,6 @@ func isCIDR(fl FieldLevel) bool {
|
||||
|
||||
// isIPv4 is the validation function for validating if a value is a valid v4 IP address.
|
||||
func isIPv4(fl FieldLevel) bool {
|
||||
|
||||
ip := net.ParseIP(fl.Field().String())
|
||||
|
||||
return ip != nil && ip.To4() != nil
|
||||
@ -351,7 +360,6 @@ func isIPv4(fl FieldLevel) bool {
|
||||
|
||||
// isIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
|
||||
func isIPv6(fl FieldLevel) bool {
|
||||
|
||||
ip := net.ParseIP(fl.Field().String())
|
||||
|
||||
return ip != nil && ip.To4() == nil
|
||||
@ -359,7 +367,6 @@ func isIPv6(fl FieldLevel) bool {
|
||||
|
||||
// isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
|
||||
func isIP(fl FieldLevel) bool {
|
||||
|
||||
ip := net.ParseIP(fl.Field().String())
|
||||
|
||||
return ip != nil
|
||||
@ -367,7 +374,6 @@ func isIP(fl FieldLevel) bool {
|
||||
|
||||
// isSSN is the validation function for validating if the field's value is a valid SSN.
|
||||
func isSSN(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
|
||||
if field.Len() != 11 {
|
||||
@ -425,7 +431,6 @@ func isLatitude(fl FieldLevel) bool {
|
||||
|
||||
// isDataURI is the validation function for validating if the field's value is a valid data URI.
|
||||
func isDataURI(fl FieldLevel) bool {
|
||||
|
||||
uri := strings.SplitN(fl.Field().String(), ",", 2)
|
||||
|
||||
if len(uri) != 2 {
|
||||
@ -441,7 +446,6 @@ func isDataURI(fl FieldLevel) bool {
|
||||
|
||||
// hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
|
||||
func hasMultiByteCharacter(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
|
||||
if field.Len() == 0 {
|
||||
@ -506,6 +510,56 @@ func isULID(fl FieldLevel) bool {
|
||||
return uLIDRegex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isMD4 is the validation function for validating if the field's value is a valid MD4.
|
||||
func isMD4(fl FieldLevel) bool {
|
||||
return md4Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isMD5 is the validation function for validating if the field's value is a valid MD5.
|
||||
func isMD5(fl FieldLevel) bool {
|
||||
return md5Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isSHA256 is the validation function for validating if the field's value is a valid SHA256.
|
||||
func isSHA256(fl FieldLevel) bool {
|
||||
return sha256Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isSHA384 is the validation function for validating if the field's value is a valid SHA384.
|
||||
func isSHA384(fl FieldLevel) bool {
|
||||
return sha384Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isSHA512 is the validation function for validating if the field's value is a valid SHA512.
|
||||
func isSHA512(fl FieldLevel) bool {
|
||||
return sha512Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isRIPEMD128 is the validation function for validating if the field's value is a valid PIPEMD128.
|
||||
func isRIPEMD128(fl FieldLevel) bool {
|
||||
return ripemd128Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isRIPEMD160 is the validation function for validating if the field's value is a valid PIPEMD160.
|
||||
func isRIPEMD160(fl FieldLevel) bool {
|
||||
return ripemd160Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isTIGER128 is the validation function for validating if the field's value is a valid TIGER128.
|
||||
func isTIGER128(fl FieldLevel) bool {
|
||||
return tiger128Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isTIGER160 is the validation function for validating if the field's value is a valid TIGER160.
|
||||
func isTIGER160(fl FieldLevel) bool {
|
||||
return tiger160Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isTIGER192 is the validation function for validating if the field's value is a valid isTIGER192.
|
||||
func isTIGER192(fl FieldLevel) bool {
|
||||
return tiger192Regex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
|
||||
func isISBN(fl FieldLevel) bool {
|
||||
return isISBN10(fl) || isISBN13(fl)
|
||||
@ -513,7 +567,6 @@ func isISBN(fl FieldLevel) bool {
|
||||
|
||||
// isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
|
||||
func isISBN13(fl FieldLevel) bool {
|
||||
|
||||
s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
|
||||
|
||||
if !iSBN13Regex.MatchString(s) {
|
||||
@ -534,7 +587,6 @@ func isISBN13(fl FieldLevel) bool {
|
||||
|
||||
// isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
|
||||
func isISBN10(fl FieldLevel) bool {
|
||||
|
||||
s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
|
||||
|
||||
if !iSBN10Regex.MatchString(s) {
|
||||
@ -722,7 +774,6 @@ func excludes(fl FieldLevel) bool {
|
||||
|
||||
// containsRune is the validation function for validating that the field's value contains the rune specified within the param.
|
||||
func containsRune(fl FieldLevel) bool {
|
||||
|
||||
r, _ := utf8.DecodeRuneInString(fl.Param())
|
||||
|
||||
return strings.ContainsRune(fl.Field().String(), r)
|
||||
@ -785,7 +836,6 @@ func fieldExcludes(fl FieldLevel) bool {
|
||||
|
||||
// isNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value.
|
||||
func isNeField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -816,12 +866,7 @@ func isNeField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return true
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := currentField.Interface().(time.Time)
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
@ -829,6 +874,10 @@ func isNeField(fl FieldLevel) bool {
|
||||
return !fieldTime.Equal(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -842,7 +891,6 @@ func isNe(fl FieldLevel) bool {
|
||||
|
||||
// isLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value.
|
||||
func isLteCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -869,18 +917,18 @@ func isLteCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
topTime := topField.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != topField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
topTime := topField.Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -890,7 +938,6 @@ func isLteCrossStructField(fl FieldLevel) bool {
|
||||
// isLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value.
|
||||
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
||||
func isLtCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -917,18 +964,18 @@ func isLtCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
topTime := topField.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(topTime)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != topField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
topTime := topField.Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(topTime)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -937,7 +984,6 @@ func isLtCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
// isGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value.
|
||||
func isGteCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -964,18 +1010,18 @@ func isGteCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
topTime := topField.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(topTime) || fieldTime.Equal(topTime)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != topField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
topTime := topField.Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(topTime) || fieldTime.Equal(topTime)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -984,7 +1030,6 @@ func isGteCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
// isGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value.
|
||||
func isGtCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1011,18 +1056,18 @@ func isGtCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
topTime := topField.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(topTime)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != topField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
topTime := topField.Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(topTime)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -1031,7 +1076,6 @@ func isGtCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
// isNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value.
|
||||
func isNeCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1061,18 +1105,18 @@ func isNeCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := field.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := topField.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return !fieldTime.Equal(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != topField.Type() {
|
||||
return true
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := field.Interface().(time.Time)
|
||||
fieldTime := topField.Interface().(time.Time)
|
||||
|
||||
return !fieldTime.Equal(t)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -1081,7 +1125,6 @@ func isNeCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
// isEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value.
|
||||
func isEqCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1111,18 +1154,18 @@ func isEqCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := field.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := topField.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.Equal(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != topField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := field.Interface().(time.Time)
|
||||
fieldTime := topField.Interface().(time.Time)
|
||||
|
||||
return fieldTime.Equal(t)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -1131,7 +1174,6 @@ func isEqCrossStructField(fl FieldLevel) bool {
|
||||
|
||||
// isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
|
||||
func isEqField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1161,19 +1203,18 @@ func isEqField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return false
|
||||
}
|
||||
if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := currentField.Interface().(time.Time)
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
t := currentField.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.Equal(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String:
|
||||
@ -1182,7 +1223,6 @@ func isEqField(fl FieldLevel) bool {
|
||||
|
||||
// isEq is the validation function for validating if the current field's value is equal to the param's value.
|
||||
func isEq(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
|
||||
@ -1234,7 +1274,7 @@ func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
|
||||
return reg.MatchString(field.String())
|
||||
}
|
||||
|
||||
// isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2
|
||||
// isPostcodeByIso3166Alpha2Field validates by field which represents for a value of country code in iso 3166 alpha 2
|
||||
// example: `postcode_iso3166_alpha2_field=CountryCode`
|
||||
func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
|
||||
field := fl.Field()
|
||||
@ -1273,11 +1313,9 @@ func isBase64URL(fl FieldLevel) bool {
|
||||
|
||||
// isURI is the validation function for validating if the current field's value is a valid URI.
|
||||
func isURI(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
|
||||
switch field.Kind() {
|
||||
|
||||
case reflect.String:
|
||||
|
||||
s := field.String()
|
||||
@ -1302,11 +1340,9 @@ func isURI(fl FieldLevel) bool {
|
||||
|
||||
// isURL is the validation function for validating if the current field's value is a valid URL.
|
||||
func isURL(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
|
||||
switch field.Kind() {
|
||||
|
||||
case reflect.String:
|
||||
|
||||
var i int
|
||||
@ -1339,7 +1375,6 @@ func isUrnRFC2141(fl FieldLevel) bool {
|
||||
field := fl.Field()
|
||||
|
||||
switch field.Kind() {
|
||||
|
||||
case reflect.String:
|
||||
|
||||
str := field.String()
|
||||
@ -1542,6 +1577,22 @@ func requiredIf(fl FieldLevel) bool {
|
||||
return hasValue(fl)
|
||||
}
|
||||
|
||||
// excludedIf is the validation function
|
||||
// The field under validation must not be present or is empty only if all the other specified fields are equal to the value following with the specified field.
|
||||
func excludedIf(fl FieldLevel) bool {
|
||||
params := parseOneOfParam2(fl.Param())
|
||||
if len(params)%2 != 0 {
|
||||
panic(fmt.Sprintf("Bad param number for excluded_if %s", fl.FieldName()))
|
||||
}
|
||||
|
||||
for i := 0; i < len(params); i += 2 {
|
||||
if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// requiredUnless is the validation function
|
||||
// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
|
||||
func requiredUnless(fl FieldLevel) bool {
|
||||
@ -1558,6 +1609,21 @@ func requiredUnless(fl FieldLevel) bool {
|
||||
return hasValue(fl)
|
||||
}
|
||||
|
||||
// excludedUnless is the validation function
|
||||
// The field under validation must not be present or is empty unless all the other specified fields are equal to the value following with the specified field.
|
||||
func excludedUnless(fl FieldLevel) bool {
|
||||
params := parseOneOfParam2(fl.Param())
|
||||
if len(params)%2 != 0 {
|
||||
panic(fmt.Sprintf("Bad param number for excluded_unless %s", fl.FieldName()))
|
||||
}
|
||||
for i := 0; i < len(params); i += 2 {
|
||||
if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return !hasValue(fl)
|
||||
}
|
||||
|
||||
// excludedWith is the validation function
|
||||
// The field under validation must not be present or is empty if any of the other specified fields are present.
|
||||
func excludedWith(fl FieldLevel) bool {
|
||||
@ -1650,7 +1716,6 @@ func requiredWithoutAll(fl FieldLevel) bool {
|
||||
|
||||
// isGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
|
||||
func isGteField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1677,18 +1742,18 @@ func isGteField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := currentField.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(t) || fieldTime.Equal(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := currentField.Interface().(time.Time)
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(t) || fieldTime.Equal(t)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String
|
||||
@ -1697,7 +1762,6 @@ func isGteField(fl FieldLevel) bool {
|
||||
|
||||
// isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
|
||||
func isGtField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1724,18 +1788,18 @@ func isGtField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := currentField.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := currentField.Interface().(time.Time)
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
|
||||
return fieldTime.After(t)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String
|
||||
@ -1744,7 +1808,6 @@ func isGtField(fl FieldLevel) bool {
|
||||
|
||||
// isGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
|
||||
func isGte(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
|
||||
@ -1777,10 +1840,10 @@ func isGte(fl FieldLevel) bool {
|
||||
|
||||
case reflect.Struct:
|
||||
|
||||
if field.Type() == timeType {
|
||||
if field.Type().ConvertibleTo(timeType) {
|
||||
|
||||
now := time.Now().UTC()
|
||||
t := field.Interface().(time.Time)
|
||||
t := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return t.After(now) || t.Equal(now)
|
||||
}
|
||||
@ -1791,7 +1854,6 @@ func isGte(fl FieldLevel) bool {
|
||||
|
||||
// isGt is the validation function for validating if the current field's value is greater than the param's value.
|
||||
func isGt(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
|
||||
@ -1823,9 +1885,9 @@ func isGt(fl FieldLevel) bool {
|
||||
return field.Float() > p
|
||||
case reflect.Struct:
|
||||
|
||||
if field.Type() == timeType {
|
||||
if field.Type().ConvertibleTo(timeType) {
|
||||
|
||||
return field.Interface().(time.Time).After(time.Now().UTC())
|
||||
return field.Convert(timeType).Interface().(time.Time).After(time.Now().UTC())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1834,7 +1896,6 @@ func isGt(fl FieldLevel) bool {
|
||||
|
||||
// hasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
|
||||
func hasLengthOf(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
|
||||
@ -1876,7 +1937,6 @@ func hasMinOf(fl FieldLevel) bool {
|
||||
|
||||
// isLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value.
|
||||
func isLteField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1903,18 +1963,18 @@ func isLteField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := currentField.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(t) || fieldTime.Equal(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := currentField.Interface().(time.Time)
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(t) || fieldTime.Equal(t)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String
|
||||
@ -1923,7 +1983,6 @@ func isLteField(fl FieldLevel) bool {
|
||||
|
||||
// isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
|
||||
func isLtField(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
kind := field.Kind()
|
||||
|
||||
@ -1950,18 +2009,18 @@ func isLtField(fl FieldLevel) bool {
|
||||
|
||||
fieldType := field.Type()
|
||||
|
||||
if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
|
||||
|
||||
t := currentField.Convert(timeType).Interface().(time.Time)
|
||||
fieldTime := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(t)
|
||||
}
|
||||
|
||||
// Not Same underlying type i.e. struct and time
|
||||
if fieldType != currentField.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
if fieldType == timeType {
|
||||
|
||||
t := currentField.Interface().(time.Time)
|
||||
fieldTime := field.Interface().(time.Time)
|
||||
|
||||
return fieldTime.Before(t)
|
||||
}
|
||||
}
|
||||
|
||||
// default reflect.String
|
||||
@ -1970,7 +2029,6 @@ func isLtField(fl FieldLevel) bool {
|
||||
|
||||
// isLte is the validation function for validating if the current field's value is less than or equal to the param's value.
|
||||
func isLte(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
|
||||
@ -2003,10 +2061,10 @@ func isLte(fl FieldLevel) bool {
|
||||
|
||||
case reflect.Struct:
|
||||
|
||||
if field.Type() == timeType {
|
||||
if field.Type().ConvertibleTo(timeType) {
|
||||
|
||||
now := time.Now().UTC()
|
||||
t := field.Interface().(time.Time)
|
||||
t := field.Convert(timeType).Interface().(time.Time)
|
||||
|
||||
return t.Before(now) || t.Equal(now)
|
||||
}
|
||||
@ -2017,7 +2075,6 @@ func isLte(fl FieldLevel) bool {
|
||||
|
||||
// isLt is the validation function for validating if the current field's value is less than the param's value.
|
||||
func isLt(fl FieldLevel) bool {
|
||||
|
||||
field := fl.Field()
|
||||
param := fl.Param()
|
||||
|
||||
@ -2050,9 +2107,9 @@ func isLt(fl FieldLevel) bool {
|
||||
|
||||
case reflect.Struct:
|
||||
|
||||
if field.Type() == timeType {
|
||||
if field.Type().ConvertibleTo(timeType) {
|
||||
|
||||
return field.Interface().(time.Time).Before(time.Now().UTC())
|
||||
return field.Convert(timeType).Interface().(time.Time).Before(time.Now().UTC())
|
||||
}
|
||||
}
|
||||
|
||||
@ -2066,7 +2123,6 @@ func hasMaxOf(fl FieldLevel) bool {
|
||||
|
||||
// isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
|
||||
func isTCP4AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP4Addr(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2077,7 +2133,6 @@ func isTCP4AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
|
||||
func isTCP6AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP6Addr(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2089,7 +2144,6 @@ func isTCP6AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
|
||||
func isTCPAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP4Addr(fl) && !isIP6Addr(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2101,7 +2155,6 @@ func isTCPAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
|
||||
func isUDP4AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP4Addr(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2113,7 +2166,6 @@ func isUDP4AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
|
||||
func isUDP6AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP6Addr(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2125,7 +2177,6 @@ func isUDP6AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
|
||||
func isUDPAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP4Addr(fl) && !isIP6Addr(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2137,7 +2188,6 @@ func isUDPAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
|
||||
func isIP4AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIPv4(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2149,7 +2199,6 @@ func isIP4AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
|
||||
func isIP6AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIPv6(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2161,7 +2210,6 @@ func isIP6AddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
|
||||
func isIPAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
if !isIP(fl) {
|
||||
return false
|
||||
}
|
||||
@ -2173,14 +2221,12 @@ func isIPAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
// isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
|
||||
func isUnixAddrResolvable(fl FieldLevel) bool {
|
||||
|
||||
_, err := net.ResolveUnixAddr("unix", fl.Field().String())
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func isIP4Addr(fl FieldLevel) bool {
|
||||
|
||||
val := fl.Field().String()
|
||||
|
||||
if idx := strings.LastIndex(val, ":"); idx != -1 {
|
||||
@ -2193,7 +2239,6 @@ func isIP4Addr(fl FieldLevel) bool {
|
||||
}
|
||||
|
||||
func isIP6Addr(fl FieldLevel) bool {
|
||||
|
||||
val := fl.Field().String()
|
||||
|
||||
if idx := strings.LastIndex(val, ":"); idx != -1 {
|
||||
@ -2436,3 +2481,41 @@ func isDnsRFC1035LabelFormat(fl FieldLevel) bool {
|
||||
val := fl.Field().String()
|
||||
return dnsRegexRFC1035Label.MatchString(val)
|
||||
}
|
||||
|
||||
// isCreditCard is the validation function for validating if the current field's value is a valid credit card number
|
||||
func isCreditCard(fl FieldLevel) bool {
|
||||
val := fl.Field().String()
|
||||
var creditCard bytes.Buffer
|
||||
segments := strings.Split(val, " ")
|
||||
for _, segment := range segments {
|
||||
if len(segment) < 3 {
|
||||
return false
|
||||
}
|
||||
creditCard.WriteString(segment)
|
||||
}
|
||||
|
||||
ccDigits := strings.Split(creditCard.String(), "")
|
||||
size := len(ccDigits)
|
||||
if size < 12 || size > 19 {
|
||||
return false
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for i, digit := range ccDigits {
|
||||
value, err := strconv.Atoi(digit)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if size%2 == 0 && i%2 == 0 || size%2 == 1 && i%2 == 1 {
|
||||
v := value * 2
|
||||
if v >= 10 {
|
||||
sum += 1 + (v % 10)
|
||||
} else {
|
||||
sum += v
|
||||
}
|
||||
} else {
|
||||
sum += value
|
||||
}
|
||||
}
|
||||
return (sum % 10) == 0
|
||||
}
|
||||
|
||||
9
vendor/github.com/go-playground/validator/v10/cache.go
generated
vendored
9
vendor/github.com/go-playground/validator/v10/cache.go
generated
vendored
@ -114,12 +114,13 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
|
||||
cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]}
|
||||
|
||||
numFields := current.NumField()
|
||||
rules := v.rules[typ]
|
||||
|
||||
var ctag *cTag
|
||||
var fld reflect.StructField
|
||||
var tag string
|
||||
var customName string
|
||||
|
||||
|
||||
for i := 0; i < numFields; i++ {
|
||||
|
||||
fld = typ.Field(i)
|
||||
@ -128,7 +129,11 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
|
||||
continue
|
||||
}
|
||||
|
||||
tag = fld.Tag.Get(v.tagName)
|
||||
if rtag, ok := rules[fld.Name]; ok {
|
||||
tag = rtag
|
||||
} else {
|
||||
tag = fld.Tag.Get(v.tagName)
|
||||
}
|
||||
|
||||
if tag == skipValidationTag {
|
||||
continue
|
||||
|
||||
40
vendor/github.com/go-playground/validator/v10/doc.go
generated
vendored
40
vendor/github.com/go-playground/validator/v10/doc.go
generated
vendored
@ -349,6 +349,40 @@ Example:
|
||||
// require the field if the Field1 and Field2 is not present:
|
||||
Usage: required_without_all=Field1 Field2
|
||||
|
||||
Excluded If
|
||||
|
||||
The field under validation must not be present or not empty only if all
|
||||
the other specified fields are equal to the value following the specified
|
||||
field. For strings ensures value is not "". For slices, maps, pointers,
|
||||
interfaces, channels and functions ensures the value is not nil.
|
||||
|
||||
Usage: excluded_if
|
||||
|
||||
Examples:
|
||||
|
||||
// exclude the field if the Field1 is equal to the parameter given:
|
||||
Usage: excluded_if=Field1 foobar
|
||||
|
||||
// exclude the field if the Field1 and Field2 is equal to the value respectively:
|
||||
Usage: excluded_if=Field1 foo Field2 bar
|
||||
|
||||
Excluded Unless
|
||||
|
||||
The field under validation must not be present or empty unless all
|
||||
the other specified fields are equal to the value following the specified
|
||||
field. For strings ensures value is not "". For slices, maps, pointers,
|
||||
interfaces, channels and functions ensures the value is not nil.
|
||||
|
||||
Usage: excluded_unless
|
||||
|
||||
Examples:
|
||||
|
||||
// exclude the field unless the Field1 is equal to the parameter given:
|
||||
Usage: excluded_unless=Field1 foobar
|
||||
|
||||
// exclude the field unless the Field1 and Field2 is equal to the value respectively:
|
||||
Usage: excluded_unless=Field1 foo Field2 bar
|
||||
|
||||
Is Default
|
||||
|
||||
This validates that the value is the default value and is almost the
|
||||
@ -1283,6 +1317,12 @@ More information on https://semver.org/
|
||||
|
||||
Usage: semver
|
||||
|
||||
Credit Card
|
||||
|
||||
This validates that a string value contains a valid credit card number using Luhn algoritm.
|
||||
|
||||
Usage: credit_card
|
||||
|
||||
Alias Validators and Tags
|
||||
|
||||
NOTE: When returning an error, the tag returned in "FieldError" will be
|
||||
|
||||
32
vendor/github.com/go-playground/validator/v10/regexes.go
generated
vendored
32
vendor/github.com/go-playground/validator/v10/regexes.go
generated
vendored
@ -30,6 +30,16 @@ const (
|
||||
uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
|
||||
uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||
uLIDRegexString = "^[A-HJKMNP-TV-Z0-9]{26}$"
|
||||
md4RegexString = "^[0-9a-f]{32}$"
|
||||
md5RegexString = "^[0-9a-f]{32}$"
|
||||
sha256RegexString = "^[0-9a-f]{64}$"
|
||||
sha384RegexString = "^[0-9a-f]{96}$"
|
||||
sha512RegexString = "^[0-9a-f]{128}$"
|
||||
ripemd128RegexString = "^[0-9a-f]{32}$"
|
||||
ripemd160RegexString = "^[0-9a-f]{40}$"
|
||||
tiger128RegexString = "^[0-9a-f]{32}$"
|
||||
tiger160RegexString = "^[0-9a-f]{40}$"
|
||||
tiger192RegexString = "^[0-9a-f]{48}$"
|
||||
aSCIIRegexString = "^[\x00-\x7F]*$"
|
||||
printableASCIIRegexString = "^[\x20-\x7E]*$"
|
||||
multibyteRegexString = "[^\x00-\x7F]"
|
||||
@ -37,12 +47,12 @@ const (
|
||||
latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
|
||||
longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
|
||||
sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$`
|
||||
hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952
|
||||
hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
|
||||
fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{0,62})(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.')
|
||||
btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
|
||||
btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
|
||||
btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
|
||||
hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952
|
||||
hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}){1}(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
|
||||
fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.')
|
||||
btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
|
||||
btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
|
||||
btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
|
||||
ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
|
||||
ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
|
||||
ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
|
||||
@ -84,6 +94,16 @@ var (
|
||||
uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString)
|
||||
uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString)
|
||||
uLIDRegex = regexp.MustCompile(uLIDRegexString)
|
||||
md4Regex = regexp.MustCompile(md4RegexString)
|
||||
md5Regex = regexp.MustCompile(md5RegexString)
|
||||
sha256Regex = regexp.MustCompile(sha256RegexString)
|
||||
sha384Regex = regexp.MustCompile(sha384RegexString)
|
||||
sha512Regex = regexp.MustCompile(sha512RegexString)
|
||||
ripemd128Regex = regexp.MustCompile(ripemd128RegexString)
|
||||
ripemd160Regex = regexp.MustCompile(ripemd160RegexString)
|
||||
tiger128Regex = regexp.MustCompile(tiger128RegexString)
|
||||
tiger160Regex = regexp.MustCompile(tiger160RegexString)
|
||||
tiger192Regex = regexp.MustCompile(tiger192RegexString)
|
||||
aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
|
||||
printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
|
||||
multibyteRegex = regexp.MustCompile(multibyteRegexString)
|
||||
|
||||
2
vendor/github.com/go-playground/validator/v10/util.go
generated
vendored
2
vendor/github.com/go-playground/validator/v10/util.go
generated
vendored
@ -82,7 +82,7 @@ BEGIN:
|
||||
fld := namespace
|
||||
var ns string
|
||||
|
||||
if typ != timeType {
|
||||
if !typ.ConvertibleTo(timeType) {
|
||||
|
||||
idx := strings.Index(namespace, namespaceSeparator)
|
||||
|
||||
|
||||
11
vendor/github.com/go-playground/validator/v10/validator.go
generated
vendored
11
vendor/github.com/go-playground/validator/v10/validator.go
generated
vendored
@ -164,7 +164,7 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
|
||||
|
||||
typ = current.Type()
|
||||
|
||||
if typ != timeType {
|
||||
if !typ.ConvertibleTo(timeType) {
|
||||
|
||||
if ct != nil {
|
||||
|
||||
@ -355,6 +355,10 @@ OUTER:
|
||||
v.ct = ct
|
||||
|
||||
if ct.fn(ctx, v) {
|
||||
if ct.isBlockEnd {
|
||||
ct = ct.next
|
||||
continue OUTER
|
||||
}
|
||||
|
||||
// drain rest of the 'or' values, then continue or leave
|
||||
for {
|
||||
@ -368,6 +372,11 @@ OUTER:
|
||||
if ct.typeof != typeOr {
|
||||
continue OUTER
|
||||
}
|
||||
|
||||
if ct.isBlockEnd {
|
||||
ct = ct.next
|
||||
continue OUTER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
69
vendor/github.com/go-playground/validator/v10/validator_instance.go
generated
vendored
69
vendor/github.com/go-playground/validator/v10/validator_instance.go
generated
vendored
@ -33,6 +33,8 @@ const (
|
||||
excludedWithoutTag = "excluded_without"
|
||||
excludedWithTag = "excluded_with"
|
||||
excludedWithAllTag = "excluded_with_all"
|
||||
excludedIfTag = "excluded_if"
|
||||
excludedUnlessTag = "excluded_unless"
|
||||
skipValidationTag = "-"
|
||||
diveTag = "dive"
|
||||
keysTag = "keys"
|
||||
@ -84,6 +86,7 @@ type Validate struct {
|
||||
aliases map[string]string
|
||||
validations map[string]internalValidationFuncWrapper
|
||||
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
|
||||
rules map[reflect.Type]map[string]string
|
||||
tagCache *tagCache
|
||||
structCache *structCache
|
||||
}
|
||||
@ -120,7 +123,7 @@ func New() *Validate {
|
||||
switch k {
|
||||
// these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour
|
||||
case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag,
|
||||
excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag:
|
||||
excludedIfTag, excludedUnlessTag, excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag:
|
||||
_ = v.registerValidation(k, wrapFunc(val), true, true)
|
||||
default:
|
||||
// no need to error check here, baked in will always be valid
|
||||
@ -152,15 +155,24 @@ func (v *Validate) SetTagName(name string) {
|
||||
func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
|
||||
errs := make(map[string]interface{})
|
||||
for field, rule := range rules {
|
||||
if reflect.ValueOf(rule).Kind() == reflect.Map && reflect.ValueOf(data[field]).Kind() == reflect.Map {
|
||||
err := v.ValidateMapCtx(ctx, data[field].(map[string]interface{}), rule.(map[string]interface{}))
|
||||
if len(err) > 0 {
|
||||
errs[field] = err
|
||||
if ruleObj, ok := rule.(map[string]interface{}); ok {
|
||||
if dataObj, ok := data[field].(map[string]interface{}); ok {
|
||||
err := v.ValidateMapCtx(ctx, dataObj, ruleObj)
|
||||
if len(err) > 0 {
|
||||
errs[field] = err
|
||||
}
|
||||
} else if dataObjs, ok := data[field].([]map[string]interface{}); ok {
|
||||
for _, obj := range dataObjs {
|
||||
err := v.ValidateMapCtx(ctx, obj, ruleObj)
|
||||
if len(err) > 0 {
|
||||
errs[field] = err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
|
||||
}
|
||||
} else if reflect.ValueOf(rule).Kind() == reflect.Map {
|
||||
errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
|
||||
} else {
|
||||
err := v.VarCtx(ctx, data[field], rule.(string))
|
||||
} else if ruleStr, ok := rule.(string); ok {
|
||||
err := v.VarCtx(ctx, data[field], ruleStr)
|
||||
if err != nil {
|
||||
errs[field] = err
|
||||
}
|
||||
@ -169,7 +181,7 @@ func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{
|
||||
return errs
|
||||
}
|
||||
|
||||
// ValidateMap validates map data form a map of tags
|
||||
// ValidateMap validates map data from a map of tags
|
||||
func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
|
||||
return v.ValidateMapCtx(context.Background(), data, rules)
|
||||
}
|
||||
@ -180,6 +192,7 @@ func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]int
|
||||
//
|
||||
// validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
|
||||
// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
|
||||
// // skip if tag key says it should be ignored
|
||||
// if name == "-" {
|
||||
// return ""
|
||||
// }
|
||||
@ -271,6 +284,34 @@ func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...i
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterStructValidationMapRules registers validate map rules.
|
||||
// Be aware that map validation rules supersede those defined on a/the struct if present.
|
||||
//
|
||||
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterStructValidationMapRules(rules map[string]string, types ...interface{}) {
|
||||
if v.rules == nil {
|
||||
v.rules = make(map[reflect.Type]map[string]string)
|
||||
}
|
||||
|
||||
deepCopyRules := make(map[string]string)
|
||||
for i, rule := range rules {
|
||||
deepCopyRules[i] = rule
|
||||
}
|
||||
|
||||
for _, t := range types {
|
||||
typ := reflect.TypeOf(t)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
if typ.Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
v.rules[typ] = deepCopyRules
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
|
||||
//
|
||||
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
@ -331,7 +372,7 @@ func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type() == timeType {
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
@ -376,7 +417,7 @@ func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn Filt
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type() == timeType {
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
@ -424,7 +465,7 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields .
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type() == timeType {
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
@ -514,7 +555,7 @@ func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ..
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type() == timeType {
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
|
||||
4
vendor/github.com/golang-jwt/jwt/v4/claims.go
generated
vendored
4
vendor/github.com/golang-jwt/jwt/v4/claims.go
generated
vendored
@ -56,7 +56,7 @@ func (c RegisteredClaims) Valid() error {
|
||||
// default value in Go, let's not fail the verification for them.
|
||||
if !c.VerifyExpiresAt(now, false) {
|
||||
delta := now.Sub(c.ExpiresAt.Time)
|
||||
vErr.Inner = fmt.Errorf("%s by %v", delta, ErrTokenExpired)
|
||||
vErr.Inner = fmt.Errorf("%s by %s", ErrTokenExpired, delta)
|
||||
vErr.Errors |= ValidationErrorExpired
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ func (c StandardClaims) Valid() error {
|
||||
// default value in Go, let's not fail the verification for them.
|
||||
if !c.VerifyExpiresAt(now, false) {
|
||||
delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
|
||||
vErr.Inner = fmt.Errorf("%s by %v", delta, ErrTokenExpired)
|
||||
vErr.Inner = fmt.Errorf("%s by %s", ErrTokenExpired, delta)
|
||||
vErr.Errors |= ValidationErrorExpired
|
||||
}
|
||||
|
||||
|
||||
6
vendor/github.com/golang-jwt/jwt/v4/go.mod
generated
vendored
6
vendor/github.com/golang-jwt/jwt/v4/go.mod
generated
vendored
@ -1,3 +1,7 @@
|
||||
module github.com/golang-jwt/jwt/v4
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
retract (
|
||||
v4.4.0 // Contains a backwards incompatible change to the Claims interface.
|
||||
)
|
||||
|
||||
179
vendor/github.com/golang/protobuf/ptypes/any.go
generated
vendored
179
vendor/github.com/golang/protobuf/ptypes/any.go
generated
vendored
@ -1,179 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ptypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
anypb "github.com/golang/protobuf/ptypes/any"
|
||||
)
|
||||
|
||||
const urlPrefix = "type.googleapis.com/"
|
||||
|
||||
// AnyMessageName returns the message name contained in an anypb.Any message.
|
||||
// Most type assertions should use the Is function instead.
|
||||
//
|
||||
// Deprecated: Call the any.MessageName method instead.
|
||||
func AnyMessageName(any *anypb.Any) (string, error) {
|
||||
name, err := anyMessageName(any)
|
||||
return string(name), err
|
||||
}
|
||||
func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) {
|
||||
if any == nil {
|
||||
return "", fmt.Errorf("message is nil")
|
||||
}
|
||||
name := protoreflect.FullName(any.TypeUrl)
|
||||
if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 {
|
||||
name = name[i+len("/"):]
|
||||
}
|
||||
if !name.IsValid() {
|
||||
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
|
||||
}
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// MarshalAny marshals the given message m into an anypb.Any message.
|
||||
//
|
||||
// Deprecated: Call the anypb.New function instead.
|
||||
func MarshalAny(m proto.Message) (*anypb.Any, error) {
|
||||
switch dm := m.(type) {
|
||||
case DynamicAny:
|
||||
m = dm.Message
|
||||
case *DynamicAny:
|
||||
if dm == nil {
|
||||
return nil, proto.ErrNil
|
||||
}
|
||||
m = dm.Message
|
||||
}
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil
|
||||
}
|
||||
|
||||
// Empty returns a new message of the type specified in an anypb.Any message.
|
||||
// It returns protoregistry.NotFound if the corresponding message type could not
|
||||
// be resolved in the global registry.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead
|
||||
// to resolve the message name and create a new instance of it.
|
||||
func Empty(any *anypb.Any) (proto.Message, error) {
|
||||
name, err := anyMessageName(any)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.MessageV1(mt.New().Interface()), nil
|
||||
}
|
||||
|
||||
// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message
|
||||
// into the provided message m. It returns an error if the target message
|
||||
// does not match the type in the Any message or if an unmarshal error occurs.
|
||||
//
|
||||
// The target message m may be a *DynamicAny message. If the underlying message
|
||||
// type could not be resolved, then this returns protoregistry.NotFound.
|
||||
//
|
||||
// Deprecated: Call the any.UnmarshalTo method instead.
|
||||
func UnmarshalAny(any *anypb.Any, m proto.Message) error {
|
||||
if dm, ok := m.(*DynamicAny); ok {
|
||||
if dm.Message == nil {
|
||||
var err error
|
||||
dm.Message, err = Empty(any)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
m = dm.Message
|
||||
}
|
||||
|
||||
anyName, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgName := proto.MessageName(m)
|
||||
if anyName != msgName {
|
||||
return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName)
|
||||
}
|
||||
return proto.Unmarshal(any.Value, m)
|
||||
}
|
||||
|
||||
// Is reports whether the Any message contains a message of the specified type.
|
||||
//
|
||||
// Deprecated: Call the any.MessageIs method instead.
|
||||
func Is(any *anypb.Any, m proto.Message) bool {
|
||||
if any == nil || m == nil {
|
||||
return false
|
||||
}
|
||||
name := proto.MessageName(m)
|
||||
if !strings.HasSuffix(any.TypeUrl, name) {
|
||||
return false
|
||||
}
|
||||
return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/'
|
||||
}
|
||||
|
||||
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
|
||||
// allocate a proto.Message for the type specified in an anypb.Any message.
|
||||
// The allocated message is stored in the embedded proto.Message.
|
||||
//
|
||||
// Example:
|
||||
// var x ptypes.DynamicAny
|
||||
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
|
||||
// fmt.Printf("unmarshaled message: %v", x.Message)
|
||||
//
|
||||
// Deprecated: Use the any.UnmarshalNew method instead to unmarshal
|
||||
// the any message contents into a new instance of the underlying message.
|
||||
type DynamicAny struct{ proto.Message }
|
||||
|
||||
func (m DynamicAny) String() string {
|
||||
if m.Message == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return m.Message.String()
|
||||
}
|
||||
func (m DynamicAny) Reset() {
|
||||
if m.Message == nil {
|
||||
return
|
||||
}
|
||||
m.Message.Reset()
|
||||
}
|
||||
func (m DynamicAny) ProtoMessage() {
|
||||
return
|
||||
}
|
||||
func (m DynamicAny) ProtoReflect() protoreflect.Message {
|
||||
if m.Message == nil {
|
||||
return nil
|
||||
}
|
||||
return dynamicAny{proto.MessageReflect(m.Message)}
|
||||
}
|
||||
|
||||
type dynamicAny struct{ protoreflect.Message }
|
||||
|
||||
func (m dynamicAny) Type() protoreflect.MessageType {
|
||||
return dynamicAnyType{m.Message.Type()}
|
||||
}
|
||||
func (m dynamicAny) New() protoreflect.Message {
|
||||
return dynamicAnyType{m.Message.Type()}.New()
|
||||
}
|
||||
func (m dynamicAny) Interface() protoreflect.ProtoMessage {
|
||||
return DynamicAny{proto.MessageV1(m.Message.Interface())}
|
||||
}
|
||||
|
||||
type dynamicAnyType struct{ protoreflect.MessageType }
|
||||
|
||||
func (t dynamicAnyType) New() protoreflect.Message {
|
||||
return dynamicAny{t.MessageType.New()}
|
||||
}
|
||||
func (t dynamicAnyType) Zero() protoreflect.Message {
|
||||
return dynamicAny{t.MessageType.Zero()}
|
||||
}
|
||||
62
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
62
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
@ -1,62 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/any/any.proto
|
||||
|
||||
package any
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// Symbols defined in public import of google/protobuf/any.proto.
|
||||
|
||||
type Any = anypb.Any
|
||||
|
||||
var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{
|
||||
0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
|
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e,
|
||||
0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65,
|
||||
0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{}
|
||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() }
|
||||
func file_github_com_golang_protobuf_ptypes_any_any_proto_init() {
|
||||
if File_github_com_golang_protobuf_ptypes_any_any_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes,
|
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs,
|
||||
}.Build()
|
||||
File_github_com_golang_protobuf_ptypes_any_any_proto = out.File
|
||||
file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil
|
||||
file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil
|
||||
file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil
|
||||
}
|
||||
10
vendor/github.com/golang/protobuf/ptypes/doc.go
generated
vendored
10
vendor/github.com/golang/protobuf/ptypes/doc.go
generated
vendored
@ -1,10 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ptypes provides functionality for interacting with well-known types.
|
||||
//
|
||||
// Deprecated: Well-known types have specialized functionality directly
|
||||
// injected into the generated packages for each message type.
|
||||
// See the deprecation notice for each function for the suggested alternative.
|
||||
package ptypes
|
||||
76
vendor/github.com/golang/protobuf/ptypes/duration.go
generated
vendored
76
vendor/github.com/golang/protobuf/ptypes/duration.go
generated
vendored
@ -1,76 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ptypes
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
durationpb "github.com/golang/protobuf/ptypes/duration"
|
||||
)
|
||||
|
||||
// Range of google.protobuf.Duration as specified in duration.proto.
|
||||
// This is about 10,000 years in seconds.
|
||||
const (
|
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
|
||||
minSeconds = -maxSeconds
|
||||
)
|
||||
|
||||
// Duration converts a durationpb.Duration to a time.Duration.
|
||||
// Duration returns an error if dur is invalid or overflows a time.Duration.
|
||||
//
|
||||
// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead.
|
||||
func Duration(dur *durationpb.Duration) (time.Duration, error) {
|
||||
if err := validateDuration(dur); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d := time.Duration(dur.Seconds) * time.Second
|
||||
if int64(d/time.Second) != dur.Seconds {
|
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur)
|
||||
}
|
||||
if dur.Nanos != 0 {
|
||||
d += time.Duration(dur.Nanos) * time.Nanosecond
|
||||
if (d < 0) != (dur.Nanos < 0) {
|
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur)
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// DurationProto converts a time.Duration to a durationpb.Duration.
|
||||
//
|
||||
// Deprecated: Call the durationpb.New function instead.
|
||||
func DurationProto(d time.Duration) *durationpb.Duration {
|
||||
nanos := d.Nanoseconds()
|
||||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
return &durationpb.Duration{
|
||||
Seconds: int64(secs),
|
||||
Nanos: int32(nanos),
|
||||
}
|
||||
}
|
||||
|
||||
// validateDuration determines whether the durationpb.Duration is valid
|
||||
// according to the definition in google/protobuf/duration.proto.
|
||||
// A valid durpb.Duration may still be too large to fit into a time.Duration
|
||||
// Note that the range of durationpb.Duration is about 10,000 years,
|
||||
// while the range of time.Duration is about 290 years.
|
||||
func validateDuration(dur *durationpb.Duration) error {
|
||||
if dur == nil {
|
||||
return errors.New("duration: nil Duration")
|
||||
}
|
||||
if dur.Seconds < minSeconds || dur.Seconds > maxSeconds {
|
||||
return fmt.Errorf("duration: %v: seconds out of range", dur)
|
||||
}
|
||||
if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 {
|
||||
return fmt.Errorf("duration: %v: nanos out of range", dur)
|
||||
}
|
||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||
if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) {
|
||||
return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
63
vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
generated
vendored
63
vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
generated
vendored
@ -1,63 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/duration/duration.proto
|
||||
|
||||
package duration
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
durationpb "google.golang.org/protobuf/types/known/durationpb"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// Symbols defined in public import of google/protobuf/duration.proto.
|
||||
|
||||
type Duration = durationpb.Duration
|
||||
|
||||
var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{
|
||||
0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
|
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73,
|
||||
0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{}
|
||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() }
|
||||
func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() {
|
||||
if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes,
|
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs,
|
||||
}.Build()
|
||||
File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File
|
||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil
|
||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil
|
||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil
|
||||
}
|
||||
112
vendor/github.com/golang/protobuf/ptypes/timestamp.go
generated
vendored
112
vendor/github.com/golang/protobuf/ptypes/timestamp.go
generated
vendored
@ -1,112 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ptypes
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
timestamppb "github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
// Range of google.protobuf.Duration as specified in timestamp.proto.
|
||||
const (
|
||||
// Seconds field of the earliest valid Timestamp.
|
||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
minValidSeconds = -62135596800
|
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800
|
||||
)
|
||||
|
||||
// Timestamp converts a timestamppb.Timestamp to a time.Time.
|
||||
// It returns an error if the argument is invalid.
|
||||
//
|
||||
// Unlike most Go functions, if Timestamp returns an error, the first return
|
||||
// value is not the zero time.Time. Instead, it is the value obtained from the
|
||||
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||
// do map to valid time.Times.
|
||||
//
|
||||
// A nil Timestamp returns an error. The first return value in that case is
|
||||
// undefined.
|
||||
//
|
||||
// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead.
|
||||
func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) {
|
||||
// Don't return the zero value on error, because corresponds to a valid
|
||||
// timestamp. Instead return whatever time.Unix gives us.
|
||||
var t time.Time
|
||||
if ts == nil {
|
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else {
|
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
|
||||
}
|
||||
return t, validateTimestamp(ts)
|
||||
}
|
||||
|
||||
// TimestampNow returns a google.protobuf.Timestamp for the current time.
|
||||
//
|
||||
// Deprecated: Call the timestamppb.Now function instead.
|
||||
func TimestampNow() *timestamppb.Timestamp {
|
||||
ts, err := TimestampProto(time.Now())
|
||||
if err != nil {
|
||||
panic("ptypes: time.Now() out of Timestamp range")
|
||||
}
|
||||
return ts
|
||||
}
|
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
//
|
||||
// Deprecated: Call the timestamppb.New function instead.
|
||||
func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) {
|
||||
ts := ×tamppb.Timestamp{
|
||||
Seconds: t.Unix(),
|
||||
Nanos: int32(t.Nanosecond()),
|
||||
}
|
||||
if err := validateTimestamp(ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// TimestampString returns the RFC 3339 string for valid Timestamps.
|
||||
// For invalid Timestamps, it returns an error message in parentheses.
|
||||
//
|
||||
// Deprecated: Call the ts.AsTime method instead,
|
||||
// followed by a call to the Format method on the time.Time value.
|
||||
func TimestampString(ts *timestamppb.Timestamp) string {
|
||||
t, err := Timestamp(ts)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("(%v)", err)
|
||||
}
|
||||
return t.Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
// validateTimestamp determines whether a Timestamp is valid.
|
||||
// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01)
|
||||
// and has a Nanos field in the range [0, 1e9).
|
||||
//
|
||||
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||
// Otherwise, it returns an error that describes the problem.
|
||||
//
|
||||
// Every valid Timestamp can be represented by a time.Time,
|
||||
// but the converse is not true.
|
||||
func validateTimestamp(ts *timestamppb.Timestamp) error {
|
||||
if ts == nil {
|
||||
return errors.New("timestamp: nil Timestamp")
|
||||
}
|
||||
if ts.Seconds < minValidSeconds {
|
||||
return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
|
||||
}
|
||||
if ts.Seconds >= maxValidSeconds {
|
||||
return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
|
||||
}
|
||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
|
||||
return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
24
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
24
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,5 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## v4.7.2 - 2022-03-16
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix nil pointer exception when calling Start again after address binding error [#2131](https://github.com/labstack/echo/pull/2131)
|
||||
* Fix CSRF middleware not being able to extract token from multipart/form-data form [#2136](https://github.com/labstack/echo/pull/2136)
|
||||
* Fix Timeout middleware write race [#2126](https://github.com/labstack/echo/pull/2126)
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Recover middleware should not log panic for aborted handler [#2134](https://github.com/labstack/echo/pull/2134)
|
||||
|
||||
|
||||
## v4.7.1 - 2022-03-13
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix `e.Static`, `.File()`, `c.Attachment()` being picky with paths starting with `./`, `../` and `/` after 4.7.0 introduced echo.Filesystem support (Go1.16+) [#2123](https://github.com/labstack/echo/pull/2123)
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Remove some unused code [#2116](https://github.com/labstack/echo/pull/2116)
|
||||
|
||||
|
||||
## v4.7.0 - 2022-03-01
|
||||
|
||||
**Enhancements**
|
||||
|
||||
12
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
12
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@ -246,7 +246,7 @@ const (
|
||||
|
||||
const (
|
||||
// Version of Echo
|
||||
Version = "4.7.0"
|
||||
Version = "4.7.2"
|
||||
website = "https://echo.labstack.com"
|
||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||
banner = `
|
||||
@ -732,7 +732,7 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
return s.Serve(e.Listener)
|
||||
}
|
||||
|
||||
func (e *Echo) configureServer(s *http.Server) (err error) {
|
||||
func (e *Echo) configureServer(s *http.Server) error {
|
||||
// Setup
|
||||
e.colorer.SetOutput(e.Logger.Output())
|
||||
s.ErrorLog = e.StdLogger
|
||||
@ -747,10 +747,11 @@ func (e *Echo) configureServer(s *http.Server) (err error) {
|
||||
|
||||
if s.TLSConfig == nil {
|
||||
if e.Listener == nil {
|
||||
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Listener = l
|
||||
}
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
@ -791,7 +792,7 @@ func (e *Echo) TLSListenerAddr() net.Addr {
|
||||
}
|
||||
|
||||
// StartH2CServer starts a custom http/2 server with h2c (HTTP/2 Cleartext).
|
||||
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) error {
|
||||
e.startupMutex.Lock()
|
||||
// Setup
|
||||
s := e.Server
|
||||
@ -808,11 +809,12 @@ func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||
}
|
||||
|
||||
if e.Listener == nil {
|
||||
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
e.Listener = l
|
||||
}
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
|
||||
40
vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
generated
vendored
40
vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -94,10 +95,12 @@ func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// defaultFS emulates os.Open behaviour with filesystem opened by `os.DirFs`. Difference between `os.Open` and `fs.Open`
|
||||
// is that FS does not allow to open path that start with `..` or `/` etc. For example previously you could have `../images`
|
||||
// in your application but `fs := os.DirFS("./")` would not allow you to use `fs.Open("../images")` and this would break
|
||||
// all old applications that rely on being able to traverse up from current executable run path.
|
||||
// defaultFS exists to preserve pre v4.7.0 behaviour where files were open by `os.Open`.
|
||||
// v4.7 introduced `echo.Filesystem` field which is Go1.16+ `fs.Fs` interface.
|
||||
// Difference between `os.Open` and `fs.Open` is that FS does not allow opening path that start with `.`, `..` or `/`
|
||||
// etc. For example previously you could have `../images` in your application but `fs := os.DirFS("./")` would not
|
||||
// allow you to use `fs.Open("../images")` and this would break all old applications that rely on being able to
|
||||
// traverse up from current executable run path.
|
||||
// NB: private because you really should use fs.FS implementation instances
|
||||
type defaultFS struct {
|
||||
prefix string
|
||||
@ -108,20 +111,26 @@ func newDefaultFS() *defaultFS {
|
||||
dir, _ := os.Getwd()
|
||||
return &defaultFS{
|
||||
prefix: dir,
|
||||
fs: os.DirFS(dir),
|
||||
fs: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (fs defaultFS) Open(name string) (fs.File, error) {
|
||||
if fs.fs == nil {
|
||||
return os.Open(name)
|
||||
}
|
||||
return fs.fs.Open(name)
|
||||
}
|
||||
|
||||
func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
||||
root = filepath.ToSlash(filepath.Clean(root)) // note: fs.FS operates only with slashes. `ToSlash` is necessary for Windows
|
||||
if dFS, ok := currentFs.(*defaultFS); ok {
|
||||
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS to
|
||||
// allow cases when root is given as `../somepath` which is not valid for fs.FS
|
||||
root = filepath.Join(dFS.prefix, root)
|
||||
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS.
|
||||
// fs.Fs.Open does not like relative paths ("./", "../") and absolute paths at all but prior echo.Filesystem we
|
||||
// were able to use paths like `./myfile.log`, `/etc/hosts` and these would work fine with `os.Open` but not with fs.Fs
|
||||
if isRelativePath(root) {
|
||||
root = filepath.Join(dFS.prefix, root)
|
||||
}
|
||||
return &defaultFS{
|
||||
prefix: root,
|
||||
fs: os.DirFS(root),
|
||||
@ -130,6 +139,21 @@ func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
||||
return fs.Sub(currentFs, root)
|
||||
}
|
||||
|
||||
func isRelativePath(path string) bool {
|
||||
if path == "" {
|
||||
return true
|
||||
}
|
||||
if path[0] == '/' {
|
||||
return false
|
||||
}
|
||||
if runtime.GOOS == "windows" && strings.IndexByte(path, ':') != -1 {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#file_and_directory_names
|
||||
// https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MustSubFS creates sub FS from current filesystem or panic on failure.
|
||||
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
|
||||
//
|
||||
|
||||
4
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
@ -168,8 +168,8 @@ func valuesFromCookie(name string) ValuesExtractor {
|
||||
// valuesFromForm returns a function that extracts values from the form field.
|
||||
func valuesFromForm(name string) ValuesExtractor {
|
||||
return func(c echo.Context) ([]string, error) {
|
||||
if parseErr := c.Request().ParseForm(); parseErr != nil {
|
||||
return nil, fmt.Errorf("valuesFromForm parse form failed: %w", parseErr)
|
||||
if c.Request().Form == nil {
|
||||
_ = c.Request().ParseMultipartForm(32 << 20) // same what `c.Request().FormValue(name)` does
|
||||
}
|
||||
values := c.Request().Form[name]
|
||||
if len(values) == 0 {
|
||||
|
||||
4
vendor/github.com/labstack/echo/v4/middleware/recover.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/middleware/recover.go
generated
vendored
@ -2,6 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@ -77,6 +78,9 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc {
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if r == http.ErrAbortHandler {
|
||||
panic(r)
|
||||
}
|
||||
err, ok := r.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("%v", r)
|
||||
|
||||
126
vendor/github.com/labstack/echo/v4/middleware/timeout.go
generated
vendored
126
vendor/github.com/labstack/echo/v4/middleware/timeout.go
generated
vendored
@ -2,10 +2,10 @@ package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
@ -55,29 +55,27 @@ import (
|
||||
// })
|
||||
//
|
||||
|
||||
type (
|
||||
// TimeoutConfig defines the config for Timeout middleware.
|
||||
TimeoutConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
// TimeoutConfig defines the config for Timeout middleware.
|
||||
type TimeoutConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// ErrorMessage is written to response on timeout in addition to http.StatusServiceUnavailable (503) status code
|
||||
// It can be used to define a custom timeout error message
|
||||
ErrorMessage string
|
||||
// ErrorMessage is written to response on timeout in addition to http.StatusServiceUnavailable (503) status code
|
||||
// It can be used to define a custom timeout error message
|
||||
ErrorMessage string
|
||||
|
||||
// OnTimeoutRouteErrorHandler is an error handler that is executed for error that was returned from wrapped route after
|
||||
// request timeouted and we already had sent the error code (503) and message response to the client.
|
||||
// NB: do not write headers/body inside this handler. The response has already been sent to the client and response writer
|
||||
// will not accept anything no more. If you want to know what actual route middleware timeouted use `c.Path()`
|
||||
OnTimeoutRouteErrorHandler func(err error, c echo.Context)
|
||||
// OnTimeoutRouteErrorHandler is an error handler that is executed for error that was returned from wrapped route after
|
||||
// request timeouted and we already had sent the error code (503) and message response to the client.
|
||||
// NB: do not write headers/body inside this handler. The response has already been sent to the client and response writer
|
||||
// will not accept anything no more. If you want to know what actual route middleware timeouted use `c.Path()`
|
||||
OnTimeoutRouteErrorHandler func(err error, c echo.Context)
|
||||
|
||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
||||
// NOTE: when difference between timeout duration and handler execution time is almost the same (in range of 100microseconds)
|
||||
// the result of timeout does not seem to be reliable - could respond timeout, could respond handler output
|
||||
// difference over 500microseconds (0.5millisecond) response seems to be reliable
|
||||
Timeout time.Duration
|
||||
}
|
||||
)
|
||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
||||
// NOTE: when difference between timeout duration and handler execution time is almost the same (in range of 100microseconds)
|
||||
// the result of timeout does not seem to be reliable - could respond timeout, could respond handler output
|
||||
// difference over 500microseconds (0.5millisecond) response seems to be reliable
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultTimeoutConfig is the default Timeout middleware config.
|
||||
@ -94,10 +92,17 @@ func Timeout() echo.MiddlewareFunc {
|
||||
return TimeoutWithConfig(DefaultTimeoutConfig)
|
||||
}
|
||||
|
||||
// TimeoutWithConfig returns a Timeout middleware with config.
|
||||
// See: `Timeout()`.
|
||||
// TimeoutWithConfig returns a Timeout middleware with config or panics on invalid configuration.
|
||||
func TimeoutWithConfig(config TimeoutConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
mw, err := config.ToMiddleware()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return mw
|
||||
}
|
||||
|
||||
// ToMiddleware converts Config to middleware or returns an error for invalid configuration
|
||||
func (config TimeoutConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultTimeoutConfig.Skipper
|
||||
}
|
||||
@ -108,26 +113,29 @@ func TimeoutWithConfig(config TimeoutConfig) echo.MiddlewareFunc {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
errChan := make(chan error, 1)
|
||||
handlerWrapper := echoHandlerFuncWrapper{
|
||||
writer: &ignorableWriter{ResponseWriter: c.Response().Writer},
|
||||
ctx: c,
|
||||
handler: next,
|
||||
errChan: make(chan error, 1),
|
||||
errChan: errChan,
|
||||
errHandler: config.OnTimeoutRouteErrorHandler,
|
||||
}
|
||||
handler := http.TimeoutHandler(handlerWrapper, config.Timeout, config.ErrorMessage)
|
||||
handler.ServeHTTP(c.Response().Writer, c.Request())
|
||||
handler.ServeHTTP(handlerWrapper.writer, c.Request())
|
||||
|
||||
select {
|
||||
case err := <-handlerWrapper.errChan:
|
||||
case err := <-errChan:
|
||||
return err
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
type echoHandlerFuncWrapper struct {
|
||||
writer *ignorableWriter
|
||||
ctx echo.Context
|
||||
handler echo.HandlerFunc
|
||||
errHandler func(err error, c echo.Context)
|
||||
@ -160,23 +168,53 @@ func (t echoHandlerFuncWrapper) ServeHTTP(rw http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
return // on timeout we can not send handler error to client because `http.TimeoutHandler` has already sent headers
|
||||
}
|
||||
// we restore original writer only for cases we did not timeout. On timeout we have already sent response to client
|
||||
// and should not anymore send additional headers/data
|
||||
// so on timeout writer stays what http.TimeoutHandler uses and prevents writing headers/body
|
||||
if err != nil {
|
||||
// Error must be written into Writer created in `http.TimeoutHandler` so to get Response into `commited` state.
|
||||
// So call global error handler to write error to the client. This is needed or `http.TimeoutHandler` will send
|
||||
// status code by itself and after that our tries to write status code will not work anymore and/or create errors in
|
||||
// log about `superfluous response.WriteHeader call from`
|
||||
t.ctx.Error(err)
|
||||
// we pass error from handler to middlewares up in handler chain to act on it if needed. But this means that
|
||||
// global error handler is probably be called twice as `t.ctx.Error` already does that.
|
||||
|
||||
// NB: later call of the global error handler or middlewares will not take any effect, as echo.Response will be
|
||||
// already marked as `committed` because we called global error handler above.
|
||||
t.ctx.Response().Writer = originalWriter // make sure we restore before we signal original coroutine about the error
|
||||
// This is needed as `http.TimeoutHandler` will write status code by itself on error and after that our tries to write
|
||||
// status code will not work anymore as Echo.Response thinks it has been already "committed" and further writes
|
||||
// create errors in log about `superfluous response.WriteHeader call from`
|
||||
t.writer.Ignore(true)
|
||||
t.ctx.Response().Writer = originalWriter // make sure we restore writer before we signal original coroutine about the error
|
||||
// we pass error from handler to middlewares up in handler chain to act on it if needed.
|
||||
t.errChan <- err
|
||||
return
|
||||
}
|
||||
// we restore original writer only for cases we did not timeout. On timeout we have already sent response to client
|
||||
// and should not anymore send additional headers/data
|
||||
// so on timeout writer stays what http.TimeoutHandler uses and prevents writing headers/body
|
||||
t.ctx.Response().Writer = originalWriter
|
||||
}
|
||||
|
||||
// ignorableWriter is ResponseWriter implementations that allows us to mark writer to ignore further write calls. This
|
||||
// is handy in cases when you do not have direct control of code being executed (3rd party middleware) but want to make
|
||||
// sure that external code will not be able to write response to the client.
|
||||
// Writer is coroutine safe for writes.
|
||||
type ignorableWriter struct {
|
||||
http.ResponseWriter
|
||||
|
||||
lock sync.Mutex
|
||||
ignoreWrites bool
|
||||
}
|
||||
|
||||
func (w *ignorableWriter) Ignore(ignore bool) {
|
||||
w.lock.Lock()
|
||||
w.ignoreWrites = ignore
|
||||
w.lock.Unlock()
|
||||
}
|
||||
|
||||
func (w *ignorableWriter) WriteHeader(code int) {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.ignoreWrites {
|
||||
return
|
||||
}
|
||||
w.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
func (w *ignorableWriter) Write(b []byte) (int, error) {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.ignoreWrites {
|
||||
return len(b), nil
|
||||
}
|
||||
return w.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
116
vendor/github.com/lufia/plan9stats/disk.go
generated
vendored
Normal file
116
vendor/github.com/lufia/plan9stats/disk.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Storage represents /dev/sdXX/ctl.
|
||||
type Storage struct {
|
||||
Name string
|
||||
Model string
|
||||
Capacity int64
|
||||
Partitions []*Partition
|
||||
}
|
||||
|
||||
// Partition represents a part of /dev/sdXX/ctl.
|
||||
type Partition struct {
|
||||
Name string
|
||||
Start uint64
|
||||
End uint64
|
||||
}
|
||||
|
||||
func ReadStorages(ctx context.Context, opts ...Option) ([]*Storage, error) {
|
||||
cfg := newConfig(opts...)
|
||||
sdctl := filepath.Join(cfg.rootdir, "/dev/sdctl")
|
||||
f, err := os.Open(sdctl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var a []*Storage
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
fields := bytes.Split(scanner.Bytes(), delim)
|
||||
if len(fields) == 0 {
|
||||
continue
|
||||
}
|
||||
exp := string(fields[0]) + "*"
|
||||
if !strings.HasPrefix(exp, "sd") {
|
||||
continue
|
||||
}
|
||||
dir := filepath.Join(cfg.rootdir, "/dev", exp)
|
||||
m, err := filepath.Glob(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, dir := range m {
|
||||
s, err := readStorage(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a = append(a, s)
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func readStorage(dir string) (*Storage, error) {
|
||||
ctl := filepath.Join(dir, "ctl")
|
||||
f, err := os.Open(ctl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var s Storage
|
||||
s.Name = filepath.Base(dir)
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Bytes()
|
||||
switch {
|
||||
case bytes.HasPrefix(line, []byte("inquiry ")):
|
||||
s.Model = string(bytes.TrimSpace(line[7:]))
|
||||
case bytes.HasPrefix(line, []byte("geometry ")):
|
||||
fields := bytes.Split(line, delim)
|
||||
if len(fields) < 3 {
|
||||
continue
|
||||
}
|
||||
var p intParser
|
||||
sec := p.ParseInt64(string(fields[1]), 10)
|
||||
size := p.ParseInt64(string(fields[2]), 10)
|
||||
if err := p.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.Capacity = sec * size
|
||||
case bytes.HasPrefix(line, []byte("part ")):
|
||||
fields := bytes.Split(line, delim)
|
||||
if len(fields) < 4 {
|
||||
continue
|
||||
}
|
||||
var p intParser
|
||||
start := p.ParseUint64(string(fields[2]), 10)
|
||||
end := p.ParseUint64(string(fields[3]), 10)
|
||||
if err := p.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.Partitions = append(s.Partitions, &Partition{
|
||||
Name: string(fields[1]),
|
||||
Start: start,
|
||||
End: end,
|
||||
})
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &s, nil
|
||||
}
|
||||
2
vendor/github.com/lufia/plan9stats/go.mod
generated
vendored
2
vendor/github.com/lufia/plan9stats/go.mod
generated
vendored
@ -2,4 +2,4 @@ module github.com/lufia/plan9stats
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/google/go-cmp v0.5.7
|
||||
require github.com/google/go-cmp v0.5.8
|
||||
|
||||
6
vendor/github.com/lufia/plan9stats/go.sum
generated
vendored
6
vendor/github.com/lufia/plan9stats/go.sum
generated
vendored
@ -1,4 +1,2 @@
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user