diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 3d15f0c480f..d3444c34f0d 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -33,7 +33,7 @@ jobs: run: docker exec -t build /bin/bash -c "make generate-backend" - name: Run golangci-lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version version: latest @@ -42,19 +42,26 @@ jobs: # working-directory: somedir # Optional: golangci-lint command line arguments. - args: --modules-download-mode=vendor --timeout=5m + # + # Note: By default, the `.golangci.yml` file should be at the root of the repository. + # The location of the configuration file can be changed by using `--config=` + args: --timeout=5m # Optional: show only new issues if it's a pull request. The default value is `false`. # only-new-issues: true - # Optional: if set to true then the action will use pre-installed Go. - # skip-go-installation: true + # Optional: if set to true, then all caching functionality will be completely disabled, + # takes precedence over all other caching options. + # skip-cache: true - # Optional: if set to true then the action don't cache or restore ~/go/pkg. - skip-pkg-cache: true + # Optional: if set to true, then the action won't cache or restore ~/go/pkg. + # skip-pkg-cache: true - # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. - skip-build-cache: true + # Optional: if set to true, then the action won't cache or restore ~/.cache/go-build. + # skip-build-cache: true + + # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'. + # install-mode: "goinstall" - name: Cleanup build container run: docker rm -f -v build diff --git a/.gitignore b/.gitignore index ead0b09f953..2a259b6adfd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ # Go #### +# Vendored dependencies +vendor + # Binaries for programs and plugins *.exe *.exe~ diff --git a/.golangci.yml b/.golangci.yml index 43f7324a0ca..48ca4fd75a7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,7 +1,6 @@ # options for analysis running run: timeout: 5m - modules-download-mode: vendor linters: disable-all: true diff --git a/cmd/stash/main.go b/cmd/stash/main.go index 4aadf4fb1d8..0fbdf2108ad 100644 --- a/cmd/stash/main.go +++ b/cmd/stash/main.go @@ -1,4 +1,4 @@ -//go:generate go run -mod=vendor github.com/99designs/gqlgen +//go:generate go run github.com/99designs/gqlgen package main import ( diff --git a/docker/build/x86_64/Dockerfile b/docker/build/x86_64/Dockerfile index 554c6ff9977..174d6f022fb 100644 --- a/docker/build/x86_64/Dockerfile +++ b/docker/build/x86_64/Dockerfile @@ -21,7 +21,6 @@ RUN apk add --no-cache make alpine-sdk WORKDIR /stash COPY ./go* ./*.go Makefile gqlgen.yml .gqlgenc.yml /stash/ COPY ./scripts /stash/scripts/ -COPY ./vendor /stash/vendor/ COPY ./pkg /stash/pkg/ COPY ./cmd /stash/cmd COPY ./internal /stash/internal diff --git a/docker/build/x86_64/Dockerfile-CUDA b/docker/build/x86_64/Dockerfile-CUDA index 63ecf3d75bb..8195f2324c9 100644 --- a/docker/build/x86_64/Dockerfile-CUDA +++ b/docker/build/x86_64/Dockerfile-CUDA @@ -21,7 +21,6 @@ RUN apt update && apt install -y build-essential golang WORKDIR /stash COPY ./go* ./*.go Makefile gqlgen.yml .gqlgenc.yml /stash/ COPY ./scripts /stash/scripts/ -COPY ./vendor /stash/vendor/ COPY ./pkg /stash/pkg/ COPY ./cmd /stash/cmd COPY ./internal /stash/internal diff --git a/scripts/cross-compile.sh b/scripts/cross-compile.sh index 07d187587bd..2b7e2786fb9 100755 --- a/scripts/cross-compile.sh +++ b/scripts/cross-compile.sh @@ -2,7 +2,7 @@ COMPILER_CONTAINER="stashapp/compiler:7" -BUILD_DATE=`go run -mod=vendor scripts/getDate.go` +BUILD_DATE=`go run scripts/getDate.go` GITHASH=`git rev-parse --short HEAD` STASH_VERSION=`git describe --tags --exclude latest_develop` diff --git a/vendor/github.com/99designs/gqlgen/.dockerignore b/vendor/github.com/99designs/gqlgen/.dockerignore deleted file mode 100644 index c8aadf3c62a..00000000000 --- a/vendor/github.com/99designs/gqlgen/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -/**/node_modules -/codegen/tests/gen -/vendor diff --git a/vendor/github.com/99designs/gqlgen/.editorconfig b/vendor/github.com/99designs/gqlgen/.editorconfig deleted file mode 100644 index feba8bbfc8e..00000000000 --- a/vendor/github.com/99designs/gqlgen/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -root = true - -[*] -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -indent_style = space -indent_size = 4 - -[*.{go,gotpl}] -indent_style = tab - -[*.yml] -indent_size = 2 - -# These often end up with go code inside, so lets keep tabs -[*.{html,md}] -indent_size = 2 -indent_style = tab diff --git a/vendor/github.com/99designs/gqlgen/.gitattributes b/vendor/github.com/99designs/gqlgen/.gitattributes deleted file mode 100644 index 05550114cea..00000000000 --- a/vendor/github.com/99designs/gqlgen/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -/codegen/templates/data.go linguist-generated -/_examples/dataloader/*_gen.go linguist-generated -generated.go linguist-generated diff --git a/vendor/github.com/99designs/gqlgen/.gitignore b/vendor/github.com/99designs/gqlgen/.gitignore deleted file mode 100644 index 9fb9693df8e..00000000000 --- a/vendor/github.com/99designs/gqlgen/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -/vendor -/docs/public -/docs/.hugo_build.lock -/_examples/chat/node_modules -/integration/node_modules -/integration/schema-fetched.graphql -/_examples/chat/package-lock.json -/_examples/federation/package-lock.json -/_examples/federation/node_modules -/codegen/gen -/gen - -/.vscode -.idea/ -*.test -*.out diff --git a/vendor/github.com/99designs/gqlgen/.golangci.yml b/vendor/github.com/99designs/gqlgen/.golangci.yml deleted file mode 100644 index 21099b69b05..00000000000 --- a/vendor/github.com/99designs/gqlgen/.golangci.yml +++ /dev/null @@ -1,39 +0,0 @@ -run: - tests: true - skip-dirs: - - bin - -linters-settings: - errcheck: - ignore: fmt:.*,[rR]ead|[wW]rite|[cC]lose,io:Copy - -linters: - disable-all: true - enable: - - bodyclose - - deadcode - - depguard - - dupl - - errcheck - - gocritic - - gofmt - - goimports - - gosimple - - govet - - ineffassign - - misspell - - nakedret - - prealloc - - staticcheck - - structcheck - - typecheck - - unconvert - - unused - - varcheck - -issues: - exclude-rules: - # Exclude some linters from running on tests files. - - path: _test\.go - linters: - - dupl diff --git a/vendor/github.com/99designs/gqlgen/CHANGELOG.md b/vendor/github.com/99designs/gqlgen/CHANGELOG.md deleted file mode 100644 index af09f4bfec6..00000000000 --- a/vendor/github.com/99designs/gqlgen/CHANGELOG.md +++ /dev/null @@ -1,8634 +0,0 @@ -# CHANGELOG -All notable changes to this project will be documented in this file. - -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). - - -## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.1...HEAD) - - - - -## [v0.17.1](https://github.com/99designs/gqlgen/compare/v0.17.0...v0.17.1) - 2022-03-02 -
9f520a28 Update golangci-lint and fix resource leak (#2024) - -* Fix golangci-lint in CI - -* Fix resource leak - -
- -- 74baaa14 fixed model gen for multiple implemented type (#2021) - -- d31cf6be v0.17.0 postrelease bump - - - - - - -## [v0.17.0](https://github.com/99designs/gqlgen/compare/v0.16.0...v0.17.0) - 2022-03-01 -- e4be5651 release v0.17.0 - -
082bbff6 Revert "Update quickstart (#1850](https://github.com/99designs/gqlgen/issues/1850))" ([#2014) - -This reverts commit 0ab636144bfc875f86e4d9fd7a2686bc57d5050c. - -
- -- a58411b8 Embed templates instead of inlining them (#2019) - -- 839b50df Test gqlgen generate in CI (#2017) - -- 00dc14ad Remove ambient imports (#2016) - -
45e192ea Clean up docs to clarify how to use a particular version (#2015) (closes #1851) - -This reverts commit 57a148f6d12572fe585ecfcafafbb7441dbf9cab. - -* Update getting-started.md - -* Update getting-started.md - -
- -- 3a9413f7 Fix issue template - -
5236fb09 fix introspection for description to be nullable (#2008) - -* fixed introspection for description to be nullable - -* regenerated for integration - -* regenerated - -* fixed introspection package - -* regenerated - -
- -
82fefdb5 support to generate model for intermediate interface (#1982) - -* support to generate model for intermediate interface - -* go generate ./... in example - -* fixed filepath generation - -
- -
3ec83635 Bump ajv from 6.10.2 to 6.12.6 in /integration (#2007) - -Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.10.2 to 6.12.6. -- [Release notes](https://github.com/ajv-validator/ajv/releases) -- [Commits](https://github.com/ajv-validator/ajv/compare/v6.10.2...v6.12.6) - ---- -updated-dependencies: -- dependency-name: ajv - dependency-type: indirect -... - -
- -
9546de2c Web Socket initialization message timeout (#2006) - -* Added an optional timeout to the web socket initialization message read operation. - -* Added a fail message to a web socket init read timeout test. - -
- -
f6ea6230 fixed introspection for schema description and specifiedByhttps://github.com/99designs/gqlgen (#1986) - -* fixed introspection for schema description and specifiedByURL - -* updated to the master latest - -* fixed Description resolver - -* updated integration go file - -* fixed codegen tests for the latest gqlparser - -* updated go mod in example - -* go generate - -* skip specifiedBy - -* regenerate - -* fixed schema-expected.graphql for the latest - -* fixed integration test to use latest tools - -* fixed integration workflow - -* use v2.4.0 - -* fixed sum - -
- -- f17ca15e Fix broken links in docs (#1983) (closes #1734) - -- a0c856b7 Added a callback error handling function to the websocket and added tests for it. (#1975) - -- cfea9f07 generate resolvers for input types (#1950) - -
ffa857ef Websocket i/o timeout fix (#1973) - -* Renamed "pingMesageType" to "pingMessageType" and refactored websocket_graphqlws.go to look more like websocket_graphql_transport_ws.go for the sake of consistency. - -* Made the keep-alive messages graphql-ws only, and the ping-pong messages graphql-transport-ws only (and added tests for it). - -* gofmt - -
- -
d7da5b0d Merge pull request #1958 from 99designs/cleanup-main - -Cleanup main - -
- -
42f32432 Merge pull request #1957 from 99designs/move-init-ci - -Upate init CI step - -
- -- be164748 Cleanup main - -- 8ea290c0 Upate init CI step - -- 56bfb188 Fix 1955: only print message on @key](https://github.com/key) found on interfaces ([#1956) - -
213a085b rename "example" dir to "_examples" (#1734) - -* rename "example" dir to "_examples" - -* fix lint - -* Adjust permissions - -
- -
9262b358 fix: typo in dataloader code sample (#1954) - -* fix: typo in dataloader code sample - -* rename k to key for sample to compile - -
- -- a0543733 remove autobind example (#1949) - -
06bbca37 docs: migrate dataloaders sample to graph-gophers/dataloader (#1871) - -* docs: add dataloader sample - -* finish example - -* add example - -* simplify method - -* replace old example - -* styling - -* Update docs/content/reference/dataloaders.md - -* Update docs/content/reference/dataloaders.md - -* Update docs/content/reference/dataloaders.md - -* Update docs/content/reference/dataloaders.md - -
- -
f9fcfa16 Comment out autobind in the sample config file (#1872) - -The reason is that many people using it for the first time copy exactly that configuration example and then open the issues to say it doesn't work. - -
- -- a30b68de fix: whitelist VERSION and CURRENT_VERSION env vars (#1870) - -
76a533b8 Bump gopkg.in/yaml.v2 from 2.2.4 to 2.2.8 (#1858) - -* Bump gopkg.in/yaml.v2 from 2.2.4 to 2.2.8 - -Bumps [gopkg.in/yaml.v2](https://github.com/go-yaml/yaml) from 2.2.4 to 2.2.8. -- [Release notes](https://github.com/go-yaml/yaml/releases) -- [Commits](https://github.com/go-yaml/yaml/compare/v2.2.4...v2.2.8) - ---- -updated-dependencies: -- dependency-name: gopkg.in/yaml.v2 - dependency-type: direct:production -... - - -* Update go sum for example - -
- -
eed4301c Bump node-fetch from 2.6.1 to 2.6.7 in /integration (#1859) - -Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7. -- [Release notes](https://github.com/node-fetch/node-fetch/releases) -- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7) - ---- -updated-dependencies: -- dependency-name: node-fetch - dependency-type: direct:development -... - -
- -- 7f5dce6d Fix #1776](https://github.com/99designs/gqlgen/issues/1776) : Edit and persist headers in GraphiQL ([#1856) - -- e0b42f99 fix requires directive with nested field when entityResolver directive is used (#1863) - -- 25c2cdcb Fix #1636](https://github.com/99designs/gqlgen/issues/1636) by updating gqlparser ([#1857) - -- c161ab38 fix #1770](https://github.com/99designs/gqlgen/issues/1770) minor error in getting-started.md ([#1771) - -
57a148f6 Remove outdated version reference so example is always for latest (#1851) - -* Also update version reference to next - -* Update getting-started.md - -
- -- 0ab63614 Update quickstart (#1850) - -
a8eba26d Fix #1777](https://github.com/99designs/gqlgen/issues/1777) by updating version constant and adding release checklist ([#1848) - -* Revise to use script 🤦 - -
- - - - - - -## [v0.16.0](https://github.com/99designs/gqlgen/compare/v0.15.1...v0.16.0) - 2022-01-24 -- b90f9750 Merge branch 'master' of github.com:99designs/gqlgen - -- 99523e44 Prepare for v0.16.0 release (#1842) - -- 0563146c Prepare for v0.16.0 release - -
7cefef26 add PrependPlugin (#1839) - -* add PrependPlugin - -related: https://github.com/99designs/gqlgen/pull/1838 - -* added test for PrependPlugin - -
- -
972878a0 Revert "Fix plugin addition (#1717](https://github.com/99designs/gqlgen/issues/1717))" ([#1838) - -This reverts commit f591c8f797e35635fb5eb0e4465c77b6a073896b. - -
- -
1ed7e050 Fix #1832](https://github.com/99designs/gqlgen/issues/1832) [@requires](https://github.com/requires) directive when [@entityResolver](https://github.com/entityResolver) is used ([#1833) - -* fix requires directive for multipleEntity directive - - -* fix lint - -
- -
fcee4c40 Update README.md (#1836) - -Corrected a simple grammar typo. - -
- -
3fb5fd99 Fix #1834](https://github.com/99designs/gqlgen/issues/1834): Implement federation correctly ([#1835) - -* Fix federation implementation which does not conform to Apollo Federation subgraph specification - -* Optimize generated line breaks - -* Run go generate - -
- -
98665071 Imporve gqlgen test cases (#1773) (closes #1765) - -* Imporve test cases for init and generate - -
- -
5d904d87 Merge pull request #1778 from ipfans/gh-pages-patch - -Bump gqlgen.com version list - -
- -- 196ee13b Bump gqlgen.com version - - - - - - -## [v0.15.1](https://github.com/99designs/gqlgen/compare/v0.15.0...v0.15.1) - 2022-01-16 -- 7102a36b Prepare for 0.15.1 release - -
2b8f50b3 Fix #1765](https://github.com/99designs/gqlgen/issues/1765): Sometimes module info not exists or not loaded. ([#1767) - -* Remove failing test - -
- -- 46502e5e fixed broken link (#1768) - - - - - - -## [v0.15.0](https://github.com/99designs/gqlgen/compare/v0.14.0...v0.15.0) - 2022-01-14 -- 99be1951 Prepare for release - -
931271a2 Fix #1762](https://github.com/99designs/gqlgen/issues/1762): Reload packages before merging type systems ([#1763) - -* run gofmt on file - -
- -- e5b5e832 Improve performance of MarshalBoolean (#1757) - -
57664bf0 Migrate playgrounds to GraphiQL (#1751) - -* migrate to GraphiQL playground - -* fix lint - -
- -
b2a832d5 Avoid problems with `val` being undefined in the federation template. (#1760) - -* Avoid problems with `val` being undefined in the federation template. - -When running gqlgen over our schema, we were seeing errors like: -``` -assignments/generated/graphql/service.go:300:4: val declared but not used -``` - -The generated code looks like this: -``` -func entityResolverNameForMobileNavigation(ctx context.Context, rep map[string]interface{}) (string, error) { - for { - var ( - m map[string]interface{} - val interface{} - ok bool - ) - m = rep - if _, ok = m["kaid"]; !ok { - break - } - m = rep - if _, ok = m["language"]; !ok { - break - } - return "findMobileNavigationByKaidAndLanguage", nil - } - return "", fmt.Errorf("%w for MobileNavigation", ErrTypeNotFound) -} -``` - -Looking at the code, it's pretty clear that this happens when there -are multiple key-fields, but each of them has only one keyField.Field -entry. This is because the old code looked at `len(keyFields)` to -decide whether to declare the `val` variable, but looks at -`len(keyField.Field)` for each keyField to decide whether to use the -`val` variable. - -The easiest solution, and the one I do in this PR, is to just declare -`val` all the time, and use a null-assignment to quiet the compiler -when it's not used. - -* run go generate to update generated files - -* run go generate to update moar generated files - -* Adding a test for verify that this fixes the issue. - -From `plugins/federation`, run the following command and verify that no errors are produced - -``` -go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml -``` - -
- -
47015f12 Added pointer to a solution for `no Go files` err (#1747) - -While following the instructions in this getting started guide I run into this error `package github.com/99designs/gqlgen: no Go files` which was pretty annoying to fix. Its a golang issue but for people who are unfamiliar with how the `go generate` command works in vendored projects its a blocker trying to follow the rest of this guide. It will be really nice to at least have a pointer in the guide for people to find a possible solution to the issue while going through the guide. I'm sure many folks have run into this issue given vendoring is now very popular with the latest go releases. - -
- -- 27a2b210 Downgrade to Go 1.16 (#1743) - -
14cfee70 Support for multiple @key](https://github.com/key) directives in federation (reworked) ([#1723) - -* address review comments - -- reworked code generation for federation.go -- better checking for missing/incorrect parameters to entity resolver functions -- better tests for generated entity resolvers - -Still missing: -- suggested test for autobind vs non-autobind generation -- could probably clean up generated code spacing, etc - -
- -- 2747bd5f Add CSV and PDF to common initialisms (#1741) - -
44beadc1 Fix list coercion when using graphql variables (#1740) - -* fix(codegen): support coercion of lists in graphql variables - -This was broken by an upstream dependency `gqlparser` coercing variables during validation. this has broken the existing coercion process withing `gqlgen` - -* test: add list coercion integration tests - -* chore: regenerate generated code - -* test: update expected schema for integration tests - -* chore: run goimports - -* chore: regenerate examples - -
- -
bd8938d8 fix: automatically register built-in directive goTag (#1737) - -* fix: automatically register built-in tag goTag - -* doc: add directive config documentation - -
- -
497227fa Close Websocket Connection on Context close/cancel (#1728) - -* Added code to the web socket so it closes when the context is cancelled (with an optional close reason). - -* Added a test. - -* go fmt - - -* Fix linter issues about the cancel function being thrown away. - -
- -- 4581fccd Don't loose field arguments when none match (#1725) - -
213ecd93 Add support for graphql-transport-ws with duplex ping-pong (#1578) - -* Add support for graphql-transport-ws with duplex ping-pong - -* Add tests for the duplex ping-pong - -
- -- ae92c83d add federation tests (#1719) - -- f591c8f7 Fix plugin addition (#1717) - -- 8fa6470f Fix #1704](https://github.com/99designs/gqlgen/issues/1704): handle [@required](https://github.com/required) nested fields as in [@key](https://github.com/key) ([#1706) - -
af33b7cd Cleaning up extra return in federation generated code (#1713) - -In PR 1709, I introduced GetMany semantics for resolving federated entities. But I left a couple of extra return statements in the generated code that are not necessary. So Im just cleaning those up here. - -Also added `go:generate` in federation entity resolver tests to make it simpler to test. - -To test: -``` -go generate ./... && cd example/ && go generate ./... && cd .. -go test -race ./... && cd example && go test -race ./... && cd .. -``` - -
- -
402a2259 Optimize performance for binder, imports and packages (Rebased from sbalabanov/master) (#1711) - -* Cache go.mod resolution for module name search - -* Optimize binder.FindObject() for performance by eliminating repeatitive constructs - -* Optimize allocations in packages.Load() function - -* Optimize binder.FindObject() by indexing object definitions for each loaded package - -* goimports to fix linting - -
- -- 237a7e6a Separate golangci-lint from other jobs (#1712) - -
50292e99 Resolve multiple federated entities in a single entityResolve call (#1709) - -* Resolve multiple federated entities in a single entityResolve call - -Entity resolver functions can only process one entity at a time. But often we want to resolve all the entities at once so that we can optimize things like database calls. And to do that you need to add you'd need to add batching with abstractions like dataloadgen or batchloader. The drawback here is that the resolver code (the domain logic) gets more complex to implement, test, and debug. - -An alternative is to have entity resolvers that can process all the representations in a single call so that domain logic can have access to all the representations up front, which is what Im adding in this PR. - -There are a few moving pieces here: -3. When that's configured, the federation plugin will create an entity resolver that will take a list of representations. - -Please note that this is very specific to federation and entity resolvers. This does not add support for resolving fields in an entity. - -Some of the implementation details worth noting. In order to efficiently process batches of entities, I group them by type so that we can process groups of entities at the same time. The resolution of groups of entities run concurrently in Go routines. If there is _only_ one type, then that's just processed without concurrency. Entities that don't have multiget enabled will still continue to resolve concurrently with Go routines, and entities that have multiget enabled just get the entire list of representations. - -The list of representations that are passed to entity resolvers are strongly types, and the type is generated for you. - -There are lots of new tests to ensure that there are no regressions and that the new functionality still functions as expected. To test: -1. Go to `plugin/federation` -2. Generate files with `go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml` -3. And run `go test ./...`. Verify they all pass. - -You can look at the federated code in `plugin/federation/testdata/entityresolver/gederated/federation.go` - -* Added `InputType` in entity to centralize logic for generating types for multiget resolvers. - -* reformat and regenerate - -
- -
80713b84 Adding entity resolver tests for errors, entities with different type… (#1708) - -* Adding entity resolver tests for errors, entities with different types, and requires - -The tests in this PR are for ensuring we get the expected errors from entity resolvers, that we also handle resolving entities where the representations are for different types, and that requires directive works correctly. - -To run tests: -1. Go to `plugin/federation` -2. Generate files with `go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml` -3. And run `go test ./...`. Verify they all pass. - -* Fixed test for errors - -
- -- ed2d6998 Replace ! with _ in root.generated file to avoid build conflicts (#1701) - -
828820af transport: implement `graphql-transport-ws` ws sub-protocol (#1507) - -* websocket: create `messageExchanger` to handle subprotocol messages - -* remove unused type - -* typo in comments - -* change `graphqlwsMessageType` type to string - -* add support for `graphql-transport-ws` subprotocol - -* fix chat app example - -* update example chat app dependencies - -* improve chat app exmaple to use the recommended ws library - -* add tests - -* removed unused const in tests - -* Update example/chat/readme.md - -
- -- 28caa6ce Ignore generated files from test coverage (#1699) - -- 7ac988de Fix linting issue - -
01d3c4f8 Entity resolver tests (#1697) - -* Moving federation tests to their own folders - -Reorganizing the tests in the federation plugin a little bit so make it simpler to add more safely without testdata colliding. This is in anticipation for a follow up PR for adding entity resolver tests. - -Run the tests with `go test ./plugin/federation/...` and verify they all pass. Also verify that the testdata/allthething directory has a `generated` directory specific to that test. - -NOTE: There is a catch all type of test that I moved to the directory `allthething`. Open to suggestions for a better name! One potential thing to considere here is to split up the tests that use that testdata and break them down into more specific tests. E.g. Add a multikey test in the testdata/entity. For now, Im leaving that as a TODO. - -* Adding entity resolver tests in the federation plugin - -The tests work by sending `_entities` queries with `representation` variables directly to the mocked server, which will allow us to test generated federation code end to end. For context, the format of the entity query is something like: - -``` -query($representations:[_Any!]!){_entities(representations:$representations){ ...on Hello{secondary} }} -``` - -And `representations` are the list of federated keys for the entities being resovled, and they look like - -``` -representations: [{ - "__typename": "Hello", - "name": "federated key value 1", -}, { - "__typename": "Hello", - "name": "federated key value 2", -}] -``` - -The entity resolver tests are in `plugin/federation/federation_entityresolver_test.go` and they rely on `plugin/federation/testdata/entityresolver`. - -To run the tests: -1. Build the entityresolver testdata - - From plugin/federation, run `go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml` -2. Run the tests with `go test ./...` or similar - -
- -
b7db36d3 Revert "Support for multiple @key](https://github.com/key) directives in federation ([#1684](https://github.com/99designs/gqlgen/issues/1684))" ([#1698) - -This reverts commit 47de912f56cd4bd6da9b74929cd67b8881617026. - -
- -- 4a4b5601 DOC: Fixed indention in example code. (#1693) - -
47de912f Support for multiple @key](https://github.com/key) directives in federation ([#1684) - -* add more unit test coverage to plugin/federation - -
- -
59a30919 Reimplement goTag using FieldMutateHook (#1682) - -* Reimplement goTag using a FieldMutateHook - -This change does not change the logic of goTag, merely reimplements it using a FieldMutateHook and sets it as the default FieldMutateHook for the modelgen plugin. - -* Add repeated tag test - -
- -
37a4e7ee Rename `@extraTag](https://github.com/extraTag)` directive to `[@goTag](https://github.com/goTag)` and make repeatable ([#1680) - -* Allow Repeatable `goTag` Directive - -* Default to field name if none provided - -* Update Docs - -
- -
87f9e436 Fix nil pointer dereference when an invalid import is bound to a model (#1676) - -* Fixes remaining Name field in singlefile test - -* Fixes nill pointer dereference when an invalid import is bound to a model - -* Only return error if we failed to find type - -* Revert "Fixes remaining Name field in singlefile test" - -This reverts commit e43ebf7aa80f884afdb3feca90867b1eff593f01. - -* Undo change of log.Println -> fmt.Println - -Totally accidental, sorry! - -
- -
6c65e8f1 Update getting-started.md (#1674) - -missing an 's' on quoted filename default - -
- -- 3bbc2a34 feat: generate resolvers for inputs if fields are missing (#1404) - -
7db941a5 Fix 1138: nested fieldset support (#1669) - -* formatting - -* update federation schema to latest Apollo spec - - -also: -handle extra spaces in FieldSet -upgrade deps in federation integration tests - -
- -
488a31fc ContextMarshaler (#1652) - -* Add interface and detection for ContextMarshaler - -* Test error on float marshalling - -* Revert prettier changes - -* Rename context test - -* Only use the erroring float printer - -* Test that context is passed to marshal functions - -* Update scalar docs to include the context - -* Generate the examples - -* Move ContextMarshaller test code to new followschema - -* Resolve conflict a little more - - -* Replicate sclar test for singlefile - -
- -- a626d9b4 Add ICMP to common initialisms (#1666) - -- db4b5eb7 Merge Inline Fragment Nested Interface Fields (#1663) - -
8b973717 Update directives doc page (#1660) - -* Update directives doc page - -* Add back one beloved piece of jargon - -
- -
1f500016 Add follow-schema layout for exec (#1309) (closes #1265) - -* Define ExecConfig separate from PackageConfig - -When support for writing generated code to a directory instead of -a single file is added, ExecConfig will need additional fields -that will not be relevant to other users of PackageConfig. - -* Add single-file, follow-schema layouts - -When `ExecLayout` is set to `follow-schema`, output generated code to a -directory instead of a single file. Each file in the output directory -will correspond to a single *.graphql schema file (plus a -root!.generated.go file containing top-level definitions that are not -specific to a single schema file). - -`ExecLayout` defaults to `single-file`, which is the current behavior, so -this new functionality is opt-in. - -These layouts expose similar functionality to the `ResolverLayout`s with -the same name, just applied to `exec` instead of `resolver`. - - -* Rebase, regenerate - -
- -
12978359 Update GQLgen test client to work with multipart form data (take 2) (#1661) - -* Update GQLgen test client to work with multipart form data - -Update the GQLgen to support multipart form data, like those present -within the fileupload examples. - -- Add missing space between "unsupported encoding " and failing - content-type header error - -(cherry picked from commit 101842f73fb79b10c1299bb40506080e08543ec6) - -* Add WithFiles client option for fileupload GQLgen client tests - -Add a `WithFiles` GQLgen client option to support the fileupload input -within tests, using the core Golang `os` package and File type, which -converts `os.File`s to their appropriate multipart form data within a -request. - -- If there are no files this should just simply convert a - `application/json` Content-Type to supported `multipart/form-data` - -(cherry picked from commit 08ef942416c98a2cadf61223308a3ff3c879d1c9) - -* Update fileupload test to use GQLgen test client - -Update the fileupload test to use the GQLgen test client and `WithFiles` -option to remove the need for `createUploadRequest` helper with raw http -posts - -- Fix setting the Content Type by using the appropriate `http` package - function to dectect it - - + https://godoc.org/net/http#DetectContentType - -(cherry picked from commit 5e573d51440eba9d457adb4186772577b28ef085) - -* Update WithFiles option test with multipart Reader - -(cherry picked from commit 6dfa3cbe0647138e80a59a0c1d55dd9c900f96f2) - -* Update file upload tests `WithFiles` option - -Update the file upload tests to use the GQL test client and its -`WithFiles` option to remove the need for a custom raw HTTP post request -builder `createUploadRequest`. - -- Also update `WithFiles` option to group & map identical files; e.g. - - ``` - { "0": ["variables.req.0.file", "variables.req.1.file"] } - ``` - -(cherry picked from commit 486d9f1b2b200701f9ce6b386736a633547c1441) - -* Make sure `WithFiles` does not add duplicates to multipart form data - -(cherry picked from commit 0c2364d8495553051d97ab805618b006fcd9eddb) - -* Fix use of byte vs string in `WithFiles` tests - -(cherry picked from commit ba10b5b1c52a74e63e825ee57c235254e8821e0d) - -* Fix strict withFiles option test for race conditions - -Fix a problem with how strict the test's expected response was for tests -with files in their request, since it always expected a strict order of -files input that is somewhat random or dependent on what OS it is -running the test on and/or race condition - -
- -
7435403c Adds RootFieldInterceptor to extension interfaces (#1647) - -* Adds RootFieldInterceptor to extension interfaces - - -* Regenerates example folder - - -* Re-generate after changes - -
- -- 8b25c9e0 Add a config option to skip running "go mod tidy" on code generation (#1644) - -
658195b7 Revert "Update GQLgen test client to work with multipart form data (#1418](https://github.com/99designs/gqlgen/issues/1418))" ([#1659) - -This reverts commit 1318f12792e86c76a2cdff9132ebac5b3e30e148. - -
- -- 41c86765 Revert 1595 (#1658) - -- 8359f974 Allow custom websocket upgrader (#1595) - -
1318f127 Update GQLgen test client to work with multipart form data (#1418) - -* Update GQLgen test client to work with multipart form data - -Update the GQLgen to support multipart form data, like those present -within the fileupload examples. - -- Add missing space between "unsupported encoding " and failing - content-type header error - -* Add WithFiles client option for fileupload GQLgen client tests - -Add a `WithFiles` GQLgen client option to support the fileupload input -within tests, using the core Golang `os` package and File type, which -converts `os.File`s to their appropriate multipart form data within a -request. - -- If there are no files this should just simply convert a - `application/json` Content-Type to supported `multipart/form-data` - -* Update fileupload test to use GQLgen test client - -Update the fileupload test to use the GQLgen test client and `WithFiles` -option to remove the need for `createUploadRequest` helper with raw http -posts - -- Fix setting the Content Type by using the appropriate `http` package - function to dectect it - - + https://godoc.org/net/http#DetectContentType - -* Update WithFiles option test with multipart Reader - -* Update file upload tests `WithFiles` option - -Update the file upload tests to use the GQL test client and its -`WithFiles` option to remove the need for a custom raw HTTP post request -builder `createUploadRequest`. - -- Also update `WithFiles` option to group & map identical files; e.g. - - ``` - { "0": ["variables.req.0.file", "variables.req.1.file"] } - ``` - -* Make sure `WithFiles` does not add duplicates to multipart form data - -* Fix use of byte vs string in `WithFiles` tests - -
- -- 6758654c raise panic when nested @requires](https://github.com/requires) are used on federation ([#1655) - -
f6c35be2 Add ReplacePlugin option to replace a specific plugin (#1657) - -* Add Helper Option for replacing plugins - -* Update recipe to use ReplacePlugin instead of NoPlugin and AddPlugin - -* fix linting issue on comment - -
- -
f8c46600 fix double indirect bug (#1604) (closes #1587) - -* invalid code generated - -* update code generation for pointer-to-pointer updating - -
- -- 629c91a2 remove extra WithOperationContext call (#1641) - -- 35199c49 codegen: ensure Elem present before using (#1317) - -
bfea93cd Reload config packages after generating models (#1491) - -If models are generated in a package that has already been loaded, and -that package refers to another package that has already been loaded, we -can find ourselves in a position where it appears that a GQL `union` is -not satisfied. - -For example, if we have: - -``` -union Subject = User -``` - -with this gqlgen.yml in github.com/wendorf/gqlgen-error/gql: - -``` -schema: -- schema.graphql -exec: - filename: generated.go -model: - - filename: models_gen.go -models: - User: - model: github.com/wendorf/gqlgen-error/gql.User - Subject: - model: github.com/wendorf/gqlgen-error/models.Subject -``` - -Note that our User model is in the github.com/wendorf/gqlgen-error.gql -package, and our models_gen.go will be generated in that same package. - -When we try to run gqlgen, we get this error: - -``` -merging type systems failed: unable to bind to interface: github.com/wendorf/gqlgen-error/gql.User does not satisfy the interface github.com/wendorf/gqlgen-error/models.Subject -``` - -Digging deeper, it's because we use types.Implements in -codegen/interface.go, which does a shallow object comparison. Because -the type has been reloaded, it refers to a _different_ interface type -object than the one we're comparing against, and get a false negative. - -By clearing the package cache and repopulating it, the whole package -cache is generated at the same time, and comparisons across packages -work. - -To see a demo of this, check out -https://github.com/wendorf/gqlgen-error and try the following: - -1. Checkout the works-with-v0.10.2 branch and `go generate ./...` to see - that it works -2. Checkout the breaks-with-v0.13.0 branch (or run go get - to see errors -3. Checkout the works-with-pull-request branch and `go generate ./...` - to see that it works again. This branch adds a go.mod replace - directive to use the gqlgen code in this PR. - -The demo starts at v0.10.2 since it is the last release without this -problem. https://github.com/99designs/gqlgen/pull/1020 introduces the -code that fails in this scenario. - -
- -
9e0817cd Add graphql schema aware field level hook to modelgen (#1650) - -* Add ast aware field level hook to modelgen - -Currently, the only mechanism for extending the model generation is to use a BuildMutateHook at the end of the model generation process. This can be quite limiting as the hook only has scope of the model build and not the graphql schema which has been parsed. - -This change adds a hook at the end of the field creation process which provides access to the parsed graphql type definition and field definition. This allows for more flexibility for example adding additional tags to the model based off custom directives - -* Add recipe for using the modelgen FieldMutateHook - -* fix goimport linting issue in models_test - -
- -
af2ac061 handling unconventional naming used in type names (#1549) - -* handling unconventional naming used in type names - -* Fix merge resolution mistake - -* Fix merge resolution mistake - -
- -- 393f7554 add extraTag directive (#1173) - -- fd1bd7c9 adding support for sending extension with gqlgen client (#1633) - -
589a7742 Enable lowercase type names in GraphQL schema to properly render (#1359) - -The difficulty with lowercased type names is that in go code any lowercased name is not exported. -This change makes the names title case for go code while preserving the proper case when interacting with the GraphQL schema. - -
- -- 50f6a2aa Fixes #1653](https://github.com/99designs/gqlgen/issues/1653): update docs and wrap error if not *gqlerror.Error ([#1654) - -
7081dedb Bump tmpl from 1.0.4 to 1.0.5 in /integration (#1627) - -Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5. -- [Release notes](https://github.com/daaku/nodejs-tmpl/releases) -- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5) - ---- -updated-dependencies: -- dependency-name: tmpl - dependency-type: indirect -... - -
- -
5287e4e5 Add QR and KVK to common initialisms (#1419) - -* Add QR and KVK to common initialisms - -* Update templates.go - -* Sort commonInitialisms - -
- -
f9df1a46 Update time format for `Time` scalar (#1648) - -* Use more precise time format - -* update test - -* update docs - -* Apply suggestions from code review - -* Update scalars.md - -
- -
77c757f0 Merge pull request #1640 from minus7/master - -Fix example run instructions - -
- -
e60dc7af Merge pull request #1619 from Khan/benkraft.mod-tidy-stdout - -Forward `go mod tidy` stdout/stderr - -
- -
0c63f1d1 Merge pull request #1515 from OpenSourceProjects/time - -Marshaling & Unmarshaling time return initial value - -
- -- a3d9e8ce Remove redundant favicon (#1638) - -- 210c1aa6 Appropriately Handle Falsy Default Field Values (#1623) - -
47ce074a Fix example run instructions (closes #1607) - -Making ./example a separate Go module [1] broke the `go run` invocations -listed in a few example readmes [2]. Using relative paths from the -respective example directory should be clear enough. - -[2]: -example/todo/server/server.go:10:2: no required module provides package github.com/99designs/gqlgen/example/todo; to add it: - go get github.com/99designs/gqlgen/example/todo - -
- -- 1a0b19fe Update README.md - -
d9998283 Merge pull request #1628 from robertmarsal/patch-1 - -Fix typo in the getting-started docs - -
- -- f93f73ac Fix typo in the getting-started docs - -
2f6919ff Merge pull request #1624 from FlymeDllVa/master - -Update disabling Introspection - -
- -- c53bc0e5 Update disabling Introspection - -- 880cd73d Update README.md - -- eec81df0 Update README.md - -
43b56cba Forward `go mod tidy` stdout/stderr - -This is a command that can fail (in my case I think for stupid reasons -in a hell of my own construction, but nonetheless). Right now we just -get -``` -$ go run github.com/Khan/webapp/dev/cmd/gqlgen -tidy failed: go mod tidy failed: exit status 1 -exit status 3 -``` -which is not the most informative. Now, instead, we'll forward its -output to our own stdout/stderr rather than devnull. - -
- -- ce7a8ee4 Fix link in docs - -- 488cf7e8 Update docs/content/getting-started.md - -- 73809f69 Update getting started - -- b938e558 Update README.md - -- cacd49a6 Update README.md - -
7d549d64 Merge pull request #1617 from 99designs/update-docs-for-go1.17 - -Update docs for getting started - -
- -- 5c52f27c Update docs for getting started - -- 41d6926f Replace gitter with discord in contributing.md - -- 24d4edcf Update README.md - -- 2272e05b Update README.md - -
ef4d4a38 Merge pull request #1614 from 99designs/go-1.16 - -Also test against 1.16 - -
- -- 00ed6fb1 Also test against 1.16 - -
473f0671 Merge pull request #1613 from 99designs/bump-non-module-deps - -Clean up non-module deps - -
- -- 6960c0c2 Bump non-module deps - -
bf9b34aa Merge pull request #1612 from 99designs/update-linter - -Update golangci linter - -
- -- 85e7a4a0 Linting fixes - -- 777dabde Update the linter - -
85dd47bb Merge pull request #1607 from 99designs/example-module - -[POC/RFC] Split examples into separate go module - -
- -- f93fb248 Split examples into separate go module - -
890f5f66 Merge pull request #1610 from 99designs/go-1.17 - -Update to go 1.17 - -
- -- 9162c53f Fix newlines in error messages - -- f67a5b26 Update github.com/urfave/cli/v2 - -
1116ea6c Merge pull request #1608 from jjmengze/patch-1 - -fix Options response header - -
- -- 71e57843 Simplify init - -- a8903ca2 Wrap errors - -- a644175b Update error checks for go 1.17 - -- c6b9f292 go mod tidy - -- 1c63cfff Add missing model package file - -- 59da23fe Create a temporary file on init so go recognises the directory as a package - -
682a7d66 fix Options response header - -operatee the header of ResponseWriter should before WriteHeader called - -
- -- ed8054b0 Update to a post-release version - -- 5216db58 Fix TestAutobinding test failure by checking the module - -- 90c5eb59 go generate - -- 402f4495 go fmt - -- 10bb1ef2 Go mod tidy - -- ed210385 Update to go 1.17 - -- 5c7acc1b Fix imports - -- d7473870 Update plugin/servergen/server.go - -- a6c6de6b Update plugin/resolvergen/resolver.go - -- de7d19c8 Update codegen/config/config_test.go - -- 60d80d4a Update cmd/gen.go - -- a991e3e7 Update errors to use go1.13 semantics - -
8f179be9 Merge pull request #1581 from tsh96/master - -Bypass complexity limit on __Schema queries. - -
- -
5048f992 Merge pull request #1525 from Code-Hex/fix/support-input-object - -support input object directive - -
- -
1e2b303a Merge pull request #1526 from epulze/fix/allow-more-types - -allow more than 10 different import sources with types - -
- -
e7df3e5c Merge pull request #1405 from alexsn/subsciption-complete-on-panic - -subscriptions: send complete message on resolver panic - -
- -
06e4fe88 Merge pull request #1529 from mathieupost/master - -Return type loading errors in config.Binder.FindObject - -
- -
a557c90c Merge pull request #1340 from bickyeric/master - -serialize ID just like String - -
- -
522cab59 Merge pull request #1285 from Khan/benkraft.federation - -Resolve requests for federation entities in parallel - -
- -- 5adb73bb add bypass __schema field test case - -- 54cef3dd Bypass complexity limit on __Schema queries. - -- f0ccab79 Return type loading errors in config.Binder.FindObject - -- 91b54787 generated go code - -- 1efc152e supported INPUT_OBJECT directive - -- e82b401d allow more than 10 different import sources with types - -
481a4e44 Marshaling & Unmarshaling time return initial value - -There was a lack of symmetry that would prevent times for being -symmetrical. That is because time.Parse actually parses an RFC3339Nano -implicitly, thereby allowing nanosecond resolution on unmarshaling a -time. Therefore we now marshal into nanoseconds, getting more -information into GraphQL times when querying for a time, and restoring -the symmetry - -
- -
95653193 Resolve requests for federation entities in parallel (closes #1278) - -In apollo federation, we may be asked for data about a list of entities. -These can typically be resolved in parallel, just as with sibling fields -in ordinary GraphQL queries. Now we do! - -I also changed the behavior such that if one lookup fails, we don't -cancel the others. This is more consistent with the behavior of other -resolvers, and is more natural now that they execute in parallel. This, -plus panic handling, required a little refactoring. - -The examples probably give the clearest picture of the changes. (And the -clearest test; the changed functionality is already exercised by -`integration-test.js` as watching the test server logs will attest.) - -
- -- f00e2c3f subscriptions: send complete message on resolver panic - -- fa371b9b serialize ID just like String - - - - - - -## [v0.14.0](https://github.com/99designs/gqlgen/compare/v0.13.0...v0.14.0) - 2021-09-08 -- 56451d92 release v0.14.0 - -
8e97969b Merge pull request #1358 from mtsmfm/patch-1 - -Create package declaration to run dataloaden - -
- -
b978593c Merge pull request #1387 from Khan/benkraft.config - -codegen/config: Add a new API to finish an already-validated config - -
- -
71507dfc Merge pull request #1408 from max107/patch-1 - -int64 support graphql/string.go - -
- -
23577b69 Merge pull request #1460 from snxk/edit-docs-recipe-gin - -Edited the Gin-Gonic Recipe Docs - -
- -- db6154b9 Update README.md - -
cecda160 Merge pull request #1464 from frederikhors/patch-1 - -Add goreportcard badge - -
- -- cc957171 Merge branch 'master' into patch-1 - -
023f66df Merge pull request #1465 from frederikhors/patch-2 - -Add coveralls badge - -
- -
50c2028a Merge pull request #1497 from polytomic/stable-introspection - -Return introspection document in stable order - -
- -
a0232dd2 Merge pull request #1603 from 99designs/dependabot/npm_and_yarn/integration/normalize-url-4.5.1 - -Bump normalize-url from 4.5.0 to 4.5.1 in /integration - -
- -
4e059eba Merge pull request #1602 from 99designs/dependabot/npm_and_yarn/integration/ini-1.3.8 - -Bump ini from 1.3.5 to 1.3.8 in /integration - -
- -
43705d45 Merge pull request #1601 from 99designs/dependabot/npm_and_yarn/integration/y18n-3.2.2 - -Bump y18n from 3.2.1 to 3.2.2 in /integration - -
- -
1f2465c6 Merge pull request #1600 from 99designs/dependabot/npm_and_yarn/integration/browserslist-4.17.0 - -Bump browserslist from 4.14.0 to 4.17.0 in /integration - -
- -
bbdebd4c Merge pull request #1599 from 99designs/dependabot/npm_and_yarn/integration/hosted-git-info-2.8.9 - -Bump hosted-git-info from 2.8.5 to 2.8.9 in /integration - -
- -
900a37af Merge pull request #1598 from 99designs/dependabot/npm_and_yarn/integration/node-fetch-2.6.1 - -Bump node-fetch from 2.6.0 to 2.6.1 in /integration - -
- -
9d334cdd Merge pull request #1597 from 99designs/dependabot/npm_and_yarn/integration/ws-7.4.6 - -Bump ws from 7.3.1 to 7.4.6 in /integration - -
- -
56181e8a Merge pull request #1365 from frederikhors/add-uint,-uint64,-uint32-types-in-graphql - -add uint, uint64, uint32 types in graphql pkg - -
- -
fd133c0b Bump normalize-url from 4.5.0 to 4.5.1 in /integration - -Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1. -- [Release notes](https://github.com/sindresorhus/normalize-url/releases) -- [Commits](https://github.com/sindresorhus/normalize-url/commits) - ---- -updated-dependencies: -- dependency-name: normalize-url - dependency-type: indirect -... - -
- -
24d8c703 Bump ini from 1.3.5 to 1.3.8 in /integration - -Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. -- [Release notes](https://github.com/isaacs/ini/releases) -- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) - ---- -updated-dependencies: -- dependency-name: ini - dependency-type: indirect -... - -
- -
de89d3a6 Bump y18n from 3.2.1 to 3.2.2 in /integration - -Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2. -- [Release notes](https://github.com/yargs/y18n/releases) -- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) -- [Commits](https://github.com/yargs/y18n/commits) - ---- -updated-dependencies: -- dependency-name: y18n - dependency-type: indirect -... - -
- -
13db6111 Bump browserslist from 4.14.0 to 4.17.0 in /integration - -Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.14.0 to 4.17.0. -- [Release notes](https://github.com/browserslist/browserslist/releases) -- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md) -- [Commits](https://github.com/browserslist/browserslist/compare/4.14.0...4.17.0) - ---- -updated-dependencies: -- dependency-name: browserslist - dependency-type: indirect -... - -
- -
94e9406e Bump hosted-git-info from 2.8.5 to 2.8.9 in /integration - -Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.5 to 2.8.9. -- [Release notes](https://github.com/npm/hosted-git-info/releases) -- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) -- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.5...v2.8.9) - ---- -updated-dependencies: -- dependency-name: hosted-git-info - dependency-type: indirect -... - -
- -
36be94ff Bump node-fetch from 2.6.0 to 2.6.1 in /integration - -Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.0 to 2.6.1. -- [Release notes](https://github.com/node-fetch/node-fetch/releases) -- [Changelog](https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md) -- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.0...v2.6.1) - ---- -updated-dependencies: -- dependency-name: node-fetch - dependency-type: direct:development -... - -
- -
721158f3 Bump ws from 7.3.1 to 7.4.6 in /integration - -Bumps [ws](https://github.com/websockets/ws) from 7.3.1 to 7.4.6. -- [Release notes](https://github.com/websockets/ws/releases) -- [Commits](https://github.com/websockets/ws/compare/7.3.1...7.4.6) - ---- -updated-dependencies: -- dependency-name: ws - dependency-type: direct:development -... - -
- -
2b3b7212 Merge pull request #1594 from 99designs/dependabot/npm_and_yarn/integration/tar-6.1.11 - -Bump tar from 6.0.5 to 6.1.11 in /integration - -
- -
5b43833d Merge pull request #1582 from 99designs/dependabot/npm_and_yarn/integration/path-parse-1.0.7 - -Bump path-parse from 1.0.6 to 1.0.7 in /integration - -
- -
55b028ca Merge pull request #1584 from nullism/patch-1 - -Fix spaces -> tabs typo in authentication.md - -
- -
edf630a3 Bump tar from 6.0.5 to 6.1.11 in /integration - -Bumps [tar](https://github.com/npm/node-tar) from 6.0.5 to 6.1.11. -- [Release notes](https://github.com/npm/node-tar/releases) -- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md) -- [Commits](https://github.com/npm/node-tar/compare/v6.0.5...v6.1.11) - ---- -updated-dependencies: -- dependency-name: tar - dependency-type: indirect -... - -
- -
29133c11 Fix spaces -> tabs typo in authentication.md - -The indentation here was supposed to be a tab rather than spaces so the readme was off. - -
- -
01b25c55 Bump path-parse from 1.0.6 to 1.0.7 in /integration - -Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7. -- [Release notes](https://github.com/jbgutierrez/path-parse/releases) -- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7) - ---- -updated-dependencies: -- dependency-name: path-parse - dependency-type: indirect -... - -
- -
9a214e80 Merge pull request #1451 from sanjeevchopra/patch-1 - -doc only change: updated sample code for disabling introspection - -
- -
01197437 Merge pull request #1417 from RicCu/patch-1 - -Use mutation instead of query in 'Changesets' doc example - -
- -
e3293b53 Merge pull request #1444 from lisowskibraeden/patch-1 - -Update cors.md - -
- -
a4d67855 Merge pull request #1517 from ShivangGoswami/patch-1 - -Update apq.md function definition mismatch - -
- -
eb36f04f Return introspection document in stable order - -This avoids spurious changes when generating client code using -something like graphql-codegen. - -
- -
7e38dd46 Merge pull request #1568 from DanyHenriquez/patch-1 - -Update apq.md - -
- -
88f2b8a7 Merge pull request #1572 from talhaguy/dataloaders-doc-casing - -Correct minor casing issue - -
- -- be9a0791 Update apq.md - -- 3e45ddc1 Correct minor casing issue - -- 145101e4 Update apq.md - -
843edd9e Update apq.md function definition mismatch - -line 67: cache, err := NewCache(cfg.RedisAddress, 24*time.Hour) -line 41: func NewCache(redisAddress string, password string,ttl time.Duration) (*Cache, error) - -either password should be removed from 41 or added in line 67 -Proposed the first one for now. - -
- -
5ad012e3 Revert "Merge pull request #1511 from a8m/a8m/restore-cwd" - -This reverts commit f4bf1f591b6a3884041876deb64ce0dd70c3c883, reversing -changes made to 3f68ea27a1a9fea2064caf877f7e24d00aa439e6. - -Reverting this because it will break existing setups, moving where -generated files get put. - -
- -- bb59cc43 Add a CHANGELOG.md (#1512) - -- 058a365a Merge pull request #1456 from skaji/issue-1455 - -
bf2fdf44 Merge pull request #1514 from 99designs/bump-gqlparser - -Bump gqlparser to v2.2.0 - -
- -- 4e881981 Bump to gqlparser v2.2.0 - -- 1d768a29 Add test covering single element -> slice coercion - -- f57d1a02 Bump gqlparser to master & support repeated directives - -
f4bf1f59 Merge pull request #1511 from a8m/a8m/restore-cwd - -codegen/config: restore current working directory after changing it - -
- -- 3f68ea27 Special handling for pointers to slices (#1363) - -
c920bdeb Merge pull request #1449 from steebchen/feat-prisma-compat - -feat(codegen): handle (v, ok) methods - -
- -
3cfc5b14 codegen/config: restore current working directory after changing it - -Before this commit, a call to config.LoadConfigFromDefaultLocations changed -the working directory to the directory that contains the gqlgen config -file. - -This commit changes the implementation to restore the working directory -after loading the config. - -
- -
35b80a72 Merge pull request #1495 from Niennienzz/improve-apq-doc - -Update apq.md - -
- -
463debae Merge pull request #1503 from nana4gonta/resolve-vulnerability - -Resolve indirect dependency vulnerability in example - -
- -
29e7bccb Merge pull request #1501 from 99designs/fix-init-1.16 - -Run go mod tidy after code generation - -
- -
9a4c80ab Merge pull request #1502 from 99designs/rm-chi - -Remove chi from dataloader example - -
- -- 5f21f9d9 Remove chi from dataloader example - -- e02db808 Run go mod tidy after code generation - -- 8c3e64e1 Improve APQ documentation - -- 03b57f3e Run go mod tidy - -- 54e387c4 Resolve indirect dependency vulnerability in example - -- 7985db44 Mention math.rand for the todo ID (#1489) - -- b995f7f1 Make spacing consistent (#1488) - -
52ded951 Merge pull request #1459 from aaronArinder/getting-started-server-section - -getting started: make running server own section - -
- -- 82a8e1bf Make it clearer what happened on init. (#1487) - -
7258af5f Merge pull request #1458 from aaronArinder/getting-started-wording - -getting started: making the resolver fn section clearer - -
- -
4fead489 Merge pull request #1452 from fmyd/fix/formatted-query-indent - -prettified some indentation - -
- -
58e3225e Merge pull request #1480 from wilhelmeek/double-bubble - -Bubble Null from List Element to Nearest Nullable Ancestor - -
- -- 1fac78e9 Add test case for nullable field - -- 469e31bd Fix bad test case - -- 635b1aef Add Test Case - -- 0b5da15c Check in generated code - -- 55b774ba Fix type ref - -- 45903a65 Handle nillable list elements - -- c4bf36c5 Add coveralls badge - -- 269a58ad Add goreportcard badge - -- 971da82c Updated gin.md - -- 41ad51ce Edited the Gin-Gonic Recipe Docs - -- 67e652ad getting started: separate example mutation/query - -- 31d339ab getting started: make running server own section - -- aa531ed8 getting started: more wording updates - -- 5b2531ae getting started: wording update - -- ada1b928 getting started: updating wording around implementing unimpl fns - -- 23eec791 go generate ./... - -
18678b15 Fix data race - -The argument of unmarshalInput may be the same for concurrent use if it pass as graphql "variables". -So we have to copy it before setting default values - -
- -- 02b14003 fomatted query indent - -- 0e9d9c3a updated sample code for disabling introspection - -- 478c3f08 feat(codegen): handle (v, ok) methods - -
5ef5d14f Update cors.md - -I had problems reading this page and applying it to my project. With these changes it worked on my end - -
- -
997da421 Merge pull request #1436 from ddouglas/patch-1 - -Upgrade graphql-playground to 1.7.26 - -
- -- be4514c6 Upgrade graphql-playground to 1.7.26 - -- 918801ea Change 'Changeset' doc example to mutation - -
862762c7 Merge pull request #1409 from zikaeroh/chi-mod - -Upgrade go-chi to v1.5.1 with module support - -
- -- c30ff3dd Upgrade go-chi to v1.5.1 with module support - -- a9c8fabf int64 support - -
b484fc27 Merge pull request #1401 from oseifrimpong/patch-1 - -fix typo - -
- -
4cc031af Merge pull request #1394 from j2gg0s/fix-default-recover-func - -bugfix: Default Recover func should return gqlerror.Error - -
- -
2af51336 Merge pull request #1400 from 99designs/sanstale - -Remove stale bot - -
- -
34a442c7 Merge pull request #1399 from 99designs/prevent-possible-error-deadlock - -Dont hold error lock when calling into error presenters - -
- -
1123ba0d Update gin.md - -Changed this: -`In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie then together in the Gin router: -` -to: -`In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie them together in the Gin router: -` - -
- -
89a9f743 Remove stale bot - -We tried it, but it's just causing more work both for maintainers and reporters of errors. - -
- -
4628ef84 Dont hold error lock when calling into error presenters - -This can result in a deadlock if error handling code calls GetErrors. - -
- -- d0d5f7db bugfix: Default Recover func should return gqlerror.Error - -
18b5df19 codegen/config: Add a new API to finish an already-validated config - -LoadConfig parses the config from yaml, but it does a bunch of other -things too. We want to parse the config ourselves, so that we can have -extra fields which will be passed to our plugins. Right now, that means -we either have to duplicate all of LoadConfig, or write the config back -to disk only to ask gqlgen re-parse it. - -In this commit, I expose a new function that does all the parts of -LoadConfig other than the actual YAML-reading: that way, a caller who -wants to parse the YAML themselves (or otherwise programmatically -compute the config) can do so without having to write it back to disk. - -An alternative would be to move all this logic to Config.Init(), but -that could break existing clients. Either way would work for us. - -
- -
0e12bfbf Merge pull request #1269 from dqn/new-line-at-the-end-of-file - -Add a new line to end of the file schema.graphqls - -
- -
22c5d1f5 Merge pull request #1303 from kunalpowar/inline-directives-doc - -Update README.md - -
- -
88cffee4 Merge pull request #1356 from maapteh/chore/chat-example-update - -Chore: update Chat example - -
- -- 1e8c34e5 Dont export Input - -
de8af66c Merge pull request #1360 from Captain-K-101/master - -Update introspection.md - -
- -- 09756915 Update introspection docs - -
651eda40 Merge pull request #1374 from rudylee/docs-file-upload-small-typo - -Fix small typo in file upload docs - -
- -- 94252e04 singleUpload consistency - -- c9d346f5 Fix small typo in file upload docs - -- 9f851619 add uint, uint64, uint32 types in graphql - -
0625525f Update introspection.md - -updated disabling interospect - -
- -- c6a93aa7 split layout components to their own part, makes sample more readable - -- 7904ef6f channel is switchable too - -- 13752055 add some layout for demo :) - -
82ca6e24 Create package declaration to run dataloaden - -ref: https://github.com/vektah/dataloaden/issues/35 - -
- -- bf549136 use Apollo docs styling for the gql var uppercase - -- 36045a37 do not autofocus - -- 0502228a chore: update example to React hooks and latest Apollo client - -- e6e64224 update deps - -
3a31a752 Merge pull request #1345 from abeltay/fix-alignment - -Fix tab spacing in cors.md - -
- -
0c68337c Merge pull request #1346 from abeltay/fix-typo - -Fix typo in migration guide - -
- -- 436a88ad Fix typo in migration guide - -- 3791f71d Fix tab spacing in cors.md - -
819e751c Merge pull request #1341 from dgraph-io/rajas/fix-gqlgen-1299 - -Rajas/fix gqlgen 1299 - -
- -- 789d02f5 Requested changes - -- 130ed3f7 Fix different alias with same name in inline fragment - -- f4669ba9 v0.13.0 postrelease bump - -- 07c06594 Update README.md - -- 1c9f24b2 remove triming space for schemaDefault - - - - - - -## [v0.13.0](https://github.com/99designs/gqlgen/compare/v0.12.2...v0.13.0) - 2020-09-21 -- 07c1f93b release v0.13.0 - -- 259f2711 Bump to gqlparser to v2.1.0 Error unwrapping release - -
669a1668 Merge pull request #1312 from 99designs/error-wrapping - -Always wrap user errors - -
- -
9b948a5f Merge pull request #1316 from skaji/is-resolver - -Add IsResolver to FieldContext - -
- -- 77aeb477 Point latest docs to v0.12.2 - -
e821b97b Always wrap user errors (closes #1305) - -Requires use of go 1.13 error unwrapping. - -On measure I think I prefer this approach, even though it's a bigger BC break: -- There's less mutex juggling -- It has never felt right to me that we make the user deal with path when overriding the error presenter -- The default error presenter is now incredibly simple - -Questions: -- Are we comfortable with supporting 1.13 and up? -- Should we change the signature of `ErrorPresenterFunc` to `func(ctx context.Context, err *gqlerror.Error) *gqlerror.Error`? - - It always is now, and breaking BC will force users to address the requirement for `errors.As` - -
- -
51b580de Merge pull request #1324 from bemasher/patch-1 - -Fix typos in README.md - -
- -- 8b2a023c Fix typos in README.md - -- 3e5dd956 add test for FieldContext.IsResolver - -- 1524989b go generate - -- 55951163 add IsResolver to FieldContext - -
622316e7 Merge pull request #1295 from a-oz/a-oz-patch-1 - -Update getting-started.md - -
- -
4c11d9fa Update getting-started.md - -fix typo - -
- -- b4375b04 v0.12.2 postrelease bump - - - - - - -## [v0.12.2](https://github.com/99designs/gqlgen/compare/v0.12.1...v0.12.2) - 2020-08-18 -- 03cebf20 release v0.12.2 - -
e3ce560d Merge pull request #1288 from alexsn/nopath-field-noerror - -avoid computing field path when getting field errors - -
- -
108975c3 Merge pull request #1284 from dgraph-io/jatin/sameFieldSameTypeGettingIgnored - -fix same field name in two different fragments - -
- -
eb424a22 Merge pull request #1294 from 99designs/fix-init - -Allow rewriter to work on empty but potentially importable packages - -
- -- a87c54ad Allow rewriter to work on empty but potentially importable ckages - -- 8a7f3e64 clean code - -- fd0f97ce avoid computing field path when getting field errors - -- 2d59b684 ran fmt on test - -- 3a153075 ran fmt - -- defd7119 added test - -- 9fcdbcd1 fix panic test - -- 473d63c0 change name to alias - -- 849e3eac added check for object defination name - -- 08eee0fc v0.12.1 postrelease bump - - - - - - -## [v0.12.1](https://github.com/99designs/gqlgen/compare/v0.12.0...v0.12.1) - 2020-08-14 -- 0d5f462b release v0.12.1 - -- e076b1b0 Regenerate test server - -- c952e0de v0.12.0 postrelease bump - - - - - - -## [v0.12.0](https://github.com/99designs/gqlgen/compare/v0.11.3...v0.12.0) - 2020-08-14 -- 70302123 Version 0.12.0 - -
3b633dfa Merge pull request #1267 from ImKcat/master - -Fixed transport not support issue - -
- -
c9a27ae3 Merge pull request #1255 from s-ichikawa/fix-object-directive-bug - -Fix bug about OBJECT directive - -
- -
e9863af1 Merge pull request #1276 from Ghvstcode/master - -Documentation Fixes - -
- -
04f6a691 Merge pull request #1277 from 99designs/direct-pointer-binding - -Support pointers in un/marshal functions - -
- -- bef9c8bf Add comments and docs for pointer scalars - -
997efd03 Reintroduce special cast case for string enums - -This reverts commit 89960664d05f0e93ed629a22753b9e30ced2698f. - -
- -- 8561c056 Replace awkward loop in buildTypes with recursion - -- d65b04f9 Clean up generated code - -- e1c463a4 Linting - -- 89960664 Remove unused special cast case for string enums - -- 196954bc Bind directly to pointer types when possible, instead of always binding to value types - -- 5b3d08db Update README.md - -- efd33dab Update README.md - -- f35b162f Fixed transport not support issue - -
39a12e0f Merge pull request #1134 from seriousben/fix-default-config-no-ast-sources - -Add LoadDefaultConfig to load the schema by default - -
- -
1b23cf15 Merge pull request #1264 from 99designs/go-1.14 - -Target multiple go versions for CI - -
- -- dbbda22e go 1.14 - -
ce964c1f Merge pull request #1115 from bowd/add-input-path-for-unmarshaling - -Add input path in unmarshaling errors - -
- -- bde4291c shadow context to ensure scoped context use - -- c43990a0 Merge remote-tracking branch 'origin/master' into HEAD - -- 6be2e9df fix fileupload example - -
ad675f00 Allow custom resolver filenames using `filename_template` option (closes #1085) - -resolve merge conflicts. - -
- -- fbfdd41c Merge pull request #1262 from sateeshpnv/gqlparser-alias (closes #1258) - -- 99fafc9f issue [#1258] explicitly add gqlparser alias to vektah/gqlparser/v2 import - -- 49291f23 fix bug in OBJECT directive - -
0fbf293f Merge pull request #1248 from sotoslammer/master - -close the connection when run returns - -
- -
d7eabafb Merge pull request #1246 from arkhvoid/master - -Fix typo cause memory problem on upload - -
- -- 21b223b8 Fix typo cause memory problem on upload - -- cc9c520f close the connection when run returns - -
8494028e Merge pull request #1243 from 99designs/nilable-nullable-unnmarshal - -Remove a bunch of unneeded nil checks from non-nullable graphql type unmarshalling - -
- -- b81138da Add test for nillable input slice - -- 14d1a4dc Only return nil for nilable types when the graphql spec would allow it - -
3e59a10d Merge pull request #1215 from ddouglas/master - -Adding Missing Header to response - -
- -
1650c499 Merge pull request #1242 from 99designs/named_map_references - -Do not use pointers on named map types - -
- -- d11f6021 Do not use pointers on named map types - -
acaee361 Merge pull request #1121 from Khan/extern-only - -Do not require a resolver for "empty" extended types. - -
- -
555db6d2 Merge pull request #1224 from frederikhors/patch-1 - -Indentation misprint - -
- -- 77b37bb2 Indentation misprint - -
a3c38c65 Merge pull request #1221 from longngn/patch-1 - -Update dataloaders.md - -
- -- 71182de8 Update dataloaders.md - -
d81baeed Merge pull request #1218 from StevenACoffman/patch-1 - -Update feature comparison for federation - -
- -- 2c1f2345 Update feature comparison for federation (closes #5) - -- e19d43bc Adding test - -- 4a62f012 Adding ContentType header to GET request responses - -- f5de4731 Add timeout to integration test - -
a21a6633 Merge pull request #1189 from RichardLindhout/patch-1 - -Upgrade to OperationContext and remove duplicate fields to fix https:… - -
- -
543317a2 Merge pull request #1170 from alexsn/apollotracing/nopanic - -apollotracing: skip field interceptor when on no tracing extension - -
- -- d347d972 Update stale.yml - -
032854bb Merge pull request #1154 from gsgalloway/master - -Add operation context when dispatching - -
- -
ccc4eb1d Merge pull request #1188 from k-yomo/update-errors-doc - -Update outdated examples in errors doc - -
- -
628b83c1 Merge pull request #1198 from ddevault/pgp - -codegen: add PGP to common initialisms - -
- -
d881559b Merge pull request #1202 from whereswaldon/patch-1 - -doc: fix typo in embedded struct example - -
- -
b6ce42a7 Merge pull request #1207 from k-yomo/update-gorilla-websocket - -Update gorilla/websocket to v1.4.2 to resolve vulnerability - -
- -- c5bfe9d3 Update gorilla/websocket to v1.4.2 to resolve vulnerability - -- 55c16e93 doc: fix typo in embedded struct example - -- 89eb1993 codegen: add PGP to common initialisms - -- 9ab7294d apollotracing: skip field interceptor when on no tracing extension - -
40570d1b Merge pull request #1163 from fwojciec/master - -fix redundant type warning - -
- -
3f7f60bf Merge pull request #1181 from tmc/patch-1 - -Update getting-started.md - -
- -- 6518d839 Upgrade to OperationContext and remove duplicate fields to fix https://github.com/99designs/gqlgen/pull/1161 - -- 632904ad Update outdated examples in errors doc - -- 0921915d Update getting-started.md - -
0a404813 Merge pull request #1117 from s-ichikawa/object-directive - -Add support for OBJECT directive - -
- -
90ee8ded Merge pull request #1137 from ddevault/master - -Replace ~ with א in package names - -
- -
e4c699dc Merge pull request #1147 from ddevault/docs - -Add links to godoc to the README and docsite - -
- -
73746621 Merge pull request #1131 from muraoka/fix-typo - -Fix typo in authentication docs - -
- -
ace558b4 Merge pull request #1124 from OpenSourceProjects/update-apq-documentation - -Update APQ example to reflect newer API - -
- -
3c126f9e Merge pull request #1119 from skaji/patch-1 - -type Person -> type Person struct - -
- -- 1610039e updated generated code - -- 905e1aad fix redundant type warning - -- 39ded924 fix ctx - -- e7798ff2 insert operation context - -- 6f78c6ac Add links to godoc to the README and docsite - -- 9b823a34 Replace ~ with א in package names (closes #1136) - -- 35a90482 Add LoadDefaultConfig to load the schema by default - -- 07a5494b Fix typo in docs - -
04b120c9 Update APQ example to reflect newer API - -The example in APQ relates to the old handlers. This brings it up to -show how extensions can be used - and uses the new API for registering -plugins that come in the graph. - -The cache example now implements the graphql.Cache interface - -
- -- 55e0f0db Check in a place where `Entity` might be nil now. - -
1ecd0749 Handle the case that all entities are "empty extend". - -In that case, there are no resolvers to write, so we shouldn't emit -any. - -
- -- 0e2666fb Run `go fmt` - -
36b5ed83 Actually, we need to check all-external, not all-key. - -We might well be defining our own type that has only key-fields, but -if they're not external then we're the primary provider of the type - -Test plan: -go test ./plugin/federation/ - -
- -
7e3f5844 Do not require a resolver for "empty" extended types. - -Summary: -If our schema has a field with a type defined in another service, then -we need to define an "empty extend" of that type in this service, so -this service knows what the type is like. But the graphql-server will -never ask us to actually resolve this "empty extend", so we don't -require a resolver function for it. Example: -``` - type MyType { - myvar: TypeDefinedInOtherService - } - - // Federation needs this type, but it doesn't need a resolver for - // it! graphql-server will never ask *us* to resolve a - // TypeDefinedInOtherService; it will ask the other service. - extend TypeDefinedInOtherService @key(fields: "id") { - id: ID @extends - } -``` - -Test Plan: -I manually tested this on a service (`assignments`) that we have that -fell afoul of this problem. But I had a hard time adding tests inside -gqlgen because the error happens at validation-time, and the -federation tests are not set up to go that far down the processing -path. - -Reviewers: benkraft, lizfaubell, dhruv - -Subscribers: #graphql - -Differential Revision: https://phabricator.khanacademy.org/D61883 - -
- -- 9c80bb5b type Person -> type Person struct - -- ea210929 add test for object directive - -- 5c3812cb merge object directives to field directives - -- 8ea5ba2b Fix additional missed tests - -- 65be2a6e Run generate - -- fd615cf6 Fix linting - -- 61fa9903 Add documentation for scalad error handling - -- 1aa20f25 Add test to highlight usecase - -- d98ff1b0 Modify templates to include deeper context nesting - -
a1a02615 Merge pull request #1104 from oshalygin/docs/update-query-complexity-initialization - -Update Query Complexity Documentation - -
- -
c68df3c6 Merge pull request #1112 from s-ichikawa/delete-unused-code - -delete unused code - -
- -
dfb6558a run CI on PRs - -PRs from outside the org arent running CI, hopefully this fixes it. - -
- -- 5149231c delete unused code - -
6f81ff92 Update Query Complexity Documentation - -- This pass at the documentation updates the - appropriate section regarding query complexity, - specifically in the way that the http.Handler - is created. -- The deprecated handler.GraphQL calls were replaced - with NewDefaultServer. -- Instead of passing along the fixed query complexity - as a second argument to the now deprecated handler.GraphQL - func, extension.FixedComplexityLimit is used instead. - -
- -- f0cd7a70 update doc site to point to latest version - -- 224ff345 v0.11.3 postrelease bump - - - - - - -## [v0.11.3](https://github.com/99designs/gqlgen/compare/v0.11.2...v0.11.3) - 2020-03-13 -- 4d735356 release v0.11.3 - -- 4b949f2e remove copyright notice at bottom of doc pages - -
c5039196 Merge pull request #1094 from 99designs/update-upload-docs - -Update file upload docs with Apollo client usage - -
- -- 5e3cef24 revert #1079 - -
793b0672 Merge pull request #1100 from sonatard/fast - -Gnerate to fast by exec codegen.GenerateCode before plugin GenerateCode - -
- -
6ac2d1cd Merge pull request #1097 from 86/86/update-federation-doc - -Add Enable federation section in federation doc - -
- -- 97896eeb exec codegen.GenerateCode before plugin GenerateCode to fast - -- 44f8ba9f Update licence - -- 94701fb7 add Enable federation section in federation doc - -- 64190309 Update upload docs with Apollo usage - -- a5381191 v0.11.2 postrelease bump - - - - - - -## [v0.11.2](https://github.com/99designs/gqlgen/compare/v0.11.1...v0.11.2) - 2020-03-05 -- 2ccc0aa6 release v0.11.2 - -
78f3da22 Merge pull request #1050 from technoweenie/executor - -Executor - -
- -- b82ee517 Fix CI badge - -
42eff5a9 Merge pull request #1057 from RichardLindhout/master - -Upgrade to github.com/urfave/cli/v2 - -
- -
bb5cb8a3 Merge pull request #1086 from 99designs/github-actions - -Use GitHub Actions - -
- -- cd2b53f2 remove os.Exits - -
587bc81c Merge pull request #1074 from yudppp/feature/add_contenttype_for_upload - -Add ContentType to graphql.Upload - -
- -- a84d6577 graphql/handler: revive the existing around func types - -- f9bb017b graphql/executor_test: ensure operation trace is started before every query - -- 57dd8d9c graphql/gqlgen: remove unnecessary convenience method - -- fb86f7b9 graphql/executor: remove the naked return - -- 9ae6bc0b graphql/executor: reinit all extension values on every Use() call - -- f3909a8a graphql/executor: make ext funcs private - -- df9e7ce3 Run CI on push only - -- ed76bc92 Update badge - -- 5a1a5446 Coveralls fixes - -- 41acc753 Fix windows line endings - -- 390cea4f Replace Appveyor with Github Actions - -- 85be072f Replace CircleCI with Github Actions - -- 8d540db3 fix: Add Upload.ContentType test - -- f21832af fix: Fixed Upload type document - -
b165568c Merge pull request #1071 from kandros/fix-server-path - -fix server path - -
- -
9d7648aa Merge pull request #1072 from wtask/patch-1 - -Fix a typo in sql example - -
- -
24400c9b Merge pull request #1079 from sonatard/remove-unused - -Remove unused code - -
- -
a7c79891 Merge pull request #1081 from sonatard/fix-plugin-test - -Fix unlink file path in resolvergen test - -
- -
e7bf7548 Merge pull request #1080 from sonatard/fix-testdata - -Fix test data - -
- -- 3a61dc00 Fix unlink file path in resolvergen test - -- df5ac929 Fix test data - -- b2843f67 Remove unused code - -- cff73f71 Add ContentType to Upload - -
f0ebc0df Fix a typo in sql example - -I think todo is referenced to user by user_id field, not by todo.id - -
- -- 22a43d77 fix server path - -
b788cce5 Merge pull request #1054 from 99designs/golint-free-resolvers - -suppress golint messages - -
- -
c515d403 Merge pull request #1053 from RichardLindhout/patch-3 - -Add practical example of getting all the requested fields - -
- -
e57cd445 Merge pull request #1061 from halvdan/patch-1 - -Fix mismatching documentation of Todo struct - -
- -
1388fa94 Fix mismatching documentation of Todo struct - -Mismatch between the code and the getting started documentation. - -
- -- 294884ad Rollback go.sum and go.mod as per feedback of [@vektah](https://github.com/vektah) - -- d8acf165 Upgrade to github.com/urfave/cli/v2 - -- 81bcbe75 suppress golint messages - -
24813079 Add practical example of getting all the requested fields - -Based on this https://github.com/99designs/gqlgen/issues/954 was tagged as 'need documentation' - -
- -
a53ce377 Merge pull request #1051 from 99designs/has-operation-context - -Add function to check presense of operation context - -
- -- 95e453bf Add function to check presense of operation context - -- 36365c41 graphql/executor: move setExtensions() - -- 3acc9421 graphql/executor: ensure Executor implements graphql.GraphExecutor. - -- f89b973b graphql/executor: merge ExtensionList into Executor - -- c16a77c3 graphql/handler: replace internal executor type - -- 8fa26cec graphql/executor: extract an Executor type from graphql/handler - -- d5d780c5 Point latest docs to 0.11.1 - -- abaa0a04 v0.11.1 postrelease bump - - - - - - -## [v0.11.1](https://github.com/99designs/gqlgen/compare/v0.11.0...v0.11.1) - 2020-02-19 -- 11af15a1 release v0.11.1 - -
bc07188c Merge pull request #1038 from 99designs/feat-check-len - -check slice length - -
- -- 2c3853c8 fix whitespace in comparison - -
07a13861 Merge pull request #1043 from 99designs/ensure-panic-handlers-get-applied - -Ensure panic handlers get applied - -
- -
156d306d Merge pull request #1046 from appleboy/patch - -docs(gin): missing import playground - -
- -- 26ee1aa1 docs(gin): missing import playground - -- 3abe5b32 add test - -- 6ecdb88d Merge branch 'master' into feat-check-len - -- 2340f7a7 Ensure panic handlers get applied - -
25d16761 Merge pull request #1039 from VitaliiLakusta/patch-1 - -Fix link to examples directory in Federation docs - -
- -- 4c47ad16 Fix link to examples directory in Federation docs - -- 2506dce0 check slice len - -- 1a68df34 fix origin/master reference in switcher - -- 199cfedf remove old docs that no longer run with new layout - -- 556c8484 fix paths - -- 282100c8 use current layout to build old doc content - -- 4c38b8b4 v0.11.0 postrelease bump - - - - - - -## [v0.11.0](https://github.com/99designs/gqlgen/compare/v0.10.2...v0.11.0) - 2020-02-17 -- 368597aa release v0.11.0 - -
e65d6228 Merge pull request #1036 from 99designs/update-v011-docs - -Update 0.11 migration docs - -
- -- 11f97936 Update 0.11 migration docs - -
2b3eed30 Merge pull request #1034 from 99designs/strip-underscores-from-entity-interfaces - -Trim underscores from around go identifiers - -
- -- b2d9bfcb Update stale.yml - -- 1ac8b5ae Update stale.yml - -- 4b9dfa61 trim underscores from around go identifiers - -
7cac3610 Merge pull request #1027 from sonatard/response-errors - -propagate resolver errors to response error in ResponseMiddleware - -
- -
14dccc57 Merge pull request #1022 from 99designs/feat-gqlparser-117 - -example about apply https://github.com/vektah/gqlparser/pull/117 - -
- -- cf6f7683 bump to gqlparser v2 - -
4ece3857 Merge pull request #1028 from abhimanyusinghgaur/master - -Respect includeDeprecated for EnumValues - -
- -- 9638ce0f Fix format - -- 51b921fa Fix format - -- 07ffcc82 Respect includeDeprecated for EnuValues - -- d58434c9 propagate resolver errors to response error in ResponseMiddleware - -- 59855925 go mod tidy - -- e4530da6 apply https://github.com/vektah/gqlparser/pull/117 - -
30e23757 Merge pull request #1020 from 99designs/handle-interfaces-implementing-interfaces - -Handle interfaces that implement interfaces - -
- -- b7a58a1c Handle interfaces that implement interfaces - -
ab8d62b6 Merge pull request #1019 from 99designs/remove-source-reprinting - -Remove source reprinting - -
- -- 2f0fa0ef handle schema loading error better - -- aacc9b1f Remove source reprinting - -
e289aaa0 Merge pull request #1018 from 99designs/federation-docs - -Federation docs and examples - -
- -- 3045b2cf Federation docs and examples - -
656a07d1 Merge pull request #1016 from 99designs/federation-entity-type - -Create a non generated federation _Entity type - -
- -- 8850a527 Create a non generated federation _Entity type - -
1d41c2eb Merge pull request #1012 from 99designs/federation-config - -Allow configuring the federation output file location - -
- -
afa9a150 Merge pull request #1013 from 99designs/feat-error-dispatch - -propagate errors to response context in DispatchError - -
- -- 652aa2fb propagate errors to response context in DispatchError - -
0fe1af8c Merge pull request #1011 from Khan/compound-keys - -Compound key support in federation - -
- -- ad3c1c81 Allow configuring the federation output file location - -
b4a00e6c Merge pull request #1010 from Khan/query-exists - -Make sure there's a Query node before trying to add a field to it. - -
- -
65401637 Adding type with multiple keys to federation test - -Summary: The current federation test schema only has types with single keys (or no keys). Adding a type with multiple keys, including one non-String key, to test compound key federation code gen. - -Test Plan: - go test - -Reviewers: csilvers, miguel - -Differential Revision: https://phabricator.khanacademy.org/D60715 - -
- -
3f714a46 Extending federation to support compound keys per Apollo spec - -Summary: -Compound keys are not yet supported for federation in gqlgen. This diff adds support by modifying the federation plugin to handle a list of key fields on an entity rather than a single top-level key field. It will now look for "findBy..." in the resolver, rather than the original "FindBy". The federation plugin does not yet support more complicated FieldSets in the key, such as nested selections. - -References: -- Apollo federation spec: https://www.apollographql.com/docs/apollo-server/federation/federation-spec/ -- Selection sets: https://graphql.github.io/graphql-spec/draft/#sec-Selection-Sets - -Will update https://phabricator.khanacademy.org/D59469 with multiple key changes. - -Test Plan: -- Tested Go GQL services using both single- and multiple-key federated types (assignments and content-library in webapp/services) -- Ran gqlgen on non-federated services in webapp to ensure regular generation still works (donations service) -- WIP: creating unit tests; will submit as separate diff - -Reviewers: briangenisio, dhruv, csilvers, O4 go-vernors - -Reviewed By: dhruv, csilvers, O4 go-vernors - -Differential Revision: https://phabricator.khanacademy.org/D59569 - -
- -
9f2a624b Make sure there's a Query node before trying to add a field to it. - -Federation adds some queries to the schema. There already existed -code to insert a Query node if none existed previously. But that code -was only put on addEntityToSchema(), and not the other place we update -the query, addServiceToSchema(). - -Almost always the old code was good enough, since we call -addEntityToSchema() before addServiceToSchema(). But there's on -addServiceToSchema(), so we need to do the query-existence check there -too. - -
- -
b941b970 Merge pull request #1007 from 99designs/handle-invalid-autoload-path - -Give an appropriate error message when autoload isnt a valid package - -
- -- 95b10809 bump appveyor go version for consistent behavour - -- 91a9ff97 fix bad copy from template - -- d5d6f830 Give an appropriate error message when autoload isnt a valid package - -
f7667e12 Merge pull request #1009 from 99designs/interface-regression - -Interface regression - -
- -- ffc419f3 Fix interfaces used as normal object types - -- 44cfb926 Test example for interface regression - -
0ddb3ef3 Merge pull request #1006 from ravisastryk/entity-directives-lookup - -skip searching directives when entity is found - -
- -- 395e1d73 skip searching directives when entity is found - -- e1f2282e bump to go 1.13 in ci - -
34c92eba Merge pull request #1003 from 99designs/fix-chat-example - -fix chat example - -
- -- 6bf88417 fix chat example - -
8ed2ec59 Merge pull request #988 from 99designs/package-cache - -Cache all packages.Load calls in a central object - -
- -- 9ccd7ed7 Cache all packages.Load calls in a central object - -
565619a8 Merge pull request #993 from 99designs/resolver-generator-v2 - -Resolver regenerator - -
- -- cf4a3eb4 keep imports when scattering resolvers between files - -- da7c1e45 Update getting started docs - -- c233876e fix windows test paths - -- 93713a29 Add tests for code persistence - -- 3e507e0d separate resolver stubs by 1 empty line - -- 8a208af5 add tests covering ResolverConfig - -- f8e61961 set init to use new resolvers by default - -- dbaf355d copy through any unknown data - -- e7255580 copy old imports through before gofmt prunes - -- 6ec36504 Copy existing resolver bodies when regenerating new resolvers - -- 9e3b399d add resolver layout = follow-schema - -- 8a18895e Update to latest golangci-lint - -- f7a67722 Merge pull request #985 from Khan/no-key-needed - -
fa884991 Correctly generate a federated schema when no entity has a `[@key](https://github.com/key)`. - -Normally, when a service is taking part in graphql federation, it will -services can link to (that is, have an edge pointing to) the type that -this service provides. The previous federation code assumed that was -the case. - -types. It might seem that would mean the service is unreachable, -since there is no possibility of edges into the service, but there are -and top level Mutation edges. That is, if a service only provides a -top-level query or top-level mutation, it might not need to define a - -This commit updates the federation code to support that use case. - -
- -
36aae4aa Merge pull request #994 from 99designs/feat-cache-ctx - -Add context.Context to graphql.Cache interface's methods - -
- -
61e060bd Merge pull request #995 from alexsn/directiveroot_empty_lines - -Remove empty lines on DirectiveRoot generation - -
- -- 30c295c4 Remove empty lines on DirectiveRoot generation - -- 85cfa8a3 Add context.Context to graphql.Cache interface's methods - -
a6c7aafb Merge pull request #931 from fridolin-koch/master - -Fix for Panic if only interfaces shall be generated - -
- -
ec4f6b15 Merge pull request #989 from 99designs/fix-intermittent-test-ka-failure - -Fix intermittent websocket ka test failure - -
- -- 76035df5 Fix intermittent websocket ka test failure - -
aa407b1f Merge pull request #979 from 99designs/capture-read-times - -Capture read times - -
- -- 4dd10086 fix test race by only stubbing now where we need to - -- 8dbce3cf Capture the time spent reading requests from the client - -
c6b3e2a1 Merge pull request #983 from vikstrous/name-for-package-global - -single packages.Load for NameForPackage - -
- -
ae79e75b Merge pull request #978 from 99designs/pluggable-error-code - -Allow customizing http and websocket status codes for errors - -
- -- 7f6f1667 bump x/tools for consistent import formatting - -- 842fcc11 review feedback - -- f0bea5ff Allow customizing http and websocket status codes for errors - -- bd50bbcb single packages.Load for NameForPackage - -
28c032d1 Merge pull request #982 from DavidJFelix/patch-1 - -fix: explicitly exclude trailing comma from link - -
- -
ac67050a fix: explicitly exclude trailing comma from link - -- this looks dumb, but when the page is rendered, the link resolves with the comma, despite the comma being excluded in github rendering. - -
- -- 4e95b363 fix some version switcher paths - -- 08369dfe add missing trailing slash on paths - -- ea347ca7 fetch all tags - -- 8c1a8f57 fix branch switching - -- 324efc5c add origin if missing - -- cfa2907a Generate docs for all tags - -
8218c734 Merge pull request #851 from marwan-at-work/federation - -Apollo Federation MVP - -
- -- 48dc29c1 go 1.12 generate, 1.14 failed - -- b2e81787 update gqlparse to v1.2.1 - -- d2a13d33 update go.mod - -
0eef2fe2 Merge pull request #970 from spiffyjr/master - -Fix extra trimspace on nillable Unmarshals - -
- -
56b8eef2 Merge pull request #974 from oshalygin/docs/gqlgen-pg-example-repo - -Add Link to Sample Project with GQLGen and Postgres - -
- -
f49936eb Add Link to Sample Project with GQLGen and Postgres - -This is a very straightforward project with numerous details in the README and the official -documentation, but questions continue to pop up around how to use this project, organize the files -and ultimately make data calls to some persistent layer. - -The `https://github.com/oshalygin/gqlgen-pg-todo-example` was built in order to show newcomers the -following: -- How to organize their graphql schema, resolvers, dataloaders and models -- How to create a new dataloader -- How to resolve with a dataloader and how to avoid some of the pitfalls(inconsistent db query to keys array order) -- How to map models from a gql schema to structs - -While the examples in this project are helpful, they could benefit from more elaborate explanations in the -code as well as the README to help newcomers get started. This PR is not intended to portray any of the examples -negatively and should not be interpreted as such. There are many findings/lessons learned from the work that folks -put together in those examples. - -README which covers a ton of the details on how to use this project: -- [README](https://github.com/oshalygin/gqlgen-pg-todo-example) - -
- -- db499561 force rebuild - -- 0985a78e remove debug comments - -- 7f648425 add preliminary test_data - -- c9d6d94b add preliminary tests - -- 2345936e fix integration - -- aae7486d go generate - -- 555a9546 go generate + remove directives nil check - -- 368d546d Apollo Federation MVP - -- 21e0e676 Fix extra trimspace on nillable Unmarshals - -- f869f5a8 remove deprected handler call - -- f0b83cb1 fix merge conflict - -- cdf96721 update generated code - -- 21356ce3 markdown cleanup - -
412a72fe Merge pull request #885 from 99designs/handler-refactor - -Refactor handler package - -
- -- bac79c54 force clean git checkout - -- dca9e4a5 Add migration docs - -
5106480b Merge pull request #947 from 99designs/handler-oc-handling - -always return OperationContext for postpone process - -
- -- 922db1e3 always return OperationContext for postpone process - -- 8794f03e v0.10.2 postrelease bump - -- 14dbf1aa use new handler package in new test - -- a339a042 panic if operation context is missing when requested - -- a13a0f5f add docs on extension name conventions - -- 458fa0de Add more interface assertions - -- d0836b72 Expose APQ stats - -- cf14cf10 fix: Fix no code generation for only interfaces - -- dc76d029 Merge remote-tracking branch 'origin/master' into handler-refactor - -- 572fb419 remove all references to deprecated handler package - -- dc622346 Tune allocs for benchmarks - -- a6f94626 Merge remote-tracking branch 'origin/master' into handler-refactor - -- c3f93810 fix benchmark - -- 631b48a5 remove automatic field stat collection to reduce time calls - -- a77d9fc2 Add generated stanzas back in - -- 0ee185b8 fix duplicate header sends - -- 7cbd75db fix APQ signature - -- 67fa2104 allow extensions to declare their own stats - -- e9502ae0 Make extensions validatable - -- fc727c9c Add a signpost method to handler extension interface - -- 0a39ae20 add fixed complexity limit - -- f2ef5ec3 more deprecations and more compat - -- 2898a622 rename ResolverContext to FieldContext - -- 092ed95f collect field timing in generated code - -- 848c627c remove DirectiveMiddleware - -- 40f08868 add NewDefaultServer - -- 1b57bc3e Rename RequestContext to OperationContext - -- 3476ac44 fix linting issues - -- 479abbef update generated code - -- bc981569 Combine root handlers in ExecutableSchema into a single Exec method - -- 473a0d25 Implement bc shim for old handler package - -- 631142cf move writer all the way back to the transport - -- c7bb03a8 merge executable schema entrypoints - -- e7e913d9 Remove remains of old handler package - -- 8c5340c1 Add complexity limit plugin - -- 0965420a Add query document caching - -- aede7d1c Add multipart from transport - -- 64cfc9ad extract shared handler test server stubs - -- a70e93bc consistently name transports - -- 9d1d77e6 split context.go into 3 files - -- 72c47c98 rename result handler to response handler - -- 4a69bcd0 Bring operation middleware inline with other handler interfaces - -- ab5665ad Add result context - -- c3dbcf83 Add apollo tracing - -- f00e5fa0 use plugins instead of middleware so multiple hooks can be configured - -- a7c5e660 build middleware graph once at startup - -- 2e0c9cab mark validation and parse errors separately to execution errors - -- cb99b42e Add websocket transport - -- eed1515c Split middlware out of handler package - -- b5089cac Split transports into subpackage - -- d0f68303 port json post - -- afe241b5 port over tracing - -- 311887d6 convert APQ to middleware - -- da986181 port over the setter request context middleware - -- 249b602d Start drafting new handler interfaces - - - - - - -## [v0.10.2](https://github.com/99designs/gqlgen/compare/v0.10.1...v0.10.2) - 2019-11-28 -- f276a4e6 release v0.10.2 - -
9e989d94 Merge pull request #929 from nmaquet/check-nil-interface-ptrs - -Don't crash when interface resolver returns a typed nil - -
- -
6f20101c Merge pull request #940 from vikstrous/optional-modelgen - -make model generation optional - -
- -
9b9dd562 Merge pull request #942 from vikstrous/disable-validation - -add skip_validation flag - -
- -
f9f2063a Merge pull request #941 from vikstrous/qualify-package-path-faster - -shortcut QualifyPackagePath in go module mode - -
- -- 4db0e6ec keep function private - -- c06f05b3 add doc - -- bd353b3e add skip_validation flag - -- b829628d shortcut QualifyPackagePath in go module mode - -- 3a05d2dd add mention in the docs - -- c2c2d7de make model generation optional - -
d3f63844 Merge pull request #939 from mjarkk/patch-1 - -(docs) graph-gophers now supports Struct Field resolving - -
- -- ba3d0189 graph-gophers now supports Struct Field resolvers - -
e747d923 Merge pull request #938 from lulucas/master - -modelgen hook docs fixed - -
- -
63be1d5e Merge pull request [#1](https://github.com/99designs/gqlgen/issues/1) from lulucas/modelgen-hook-patch-1 - -modelgen hook docs use plugin poitner - -
- -
33fc16b1 modelgen hook docs use plugin poitner - -and add modelgen package to ModelBuild type - -
- -- fcfe595e Add a comment - -
59946087 Add unit test for the interface resolver / typed nil interaction - -This added test shows that the `_Dog_species` automatically generated -resolver will crash unless the extra nil check is added in -`interface.gotpl`. - -
- -- 201768f0 Regenerate examples - -
85ca9efe Return graphql.Null in interface resolver when passed a typed nil - -Go's dreaded _typed nil_ strikes again. Nil pointers of struct types -aren't equal to nil interface pointers. - -See https://golang.org/doc/faq#nil_error - -
- -
15b30588 Merge pull request #894 from 99designs/enum-var-value-coercion - -Improve enum value (with vars) validation timing - -
- -- 568433a2 fix ci failed - -- 0ccfc7e0 Merge branch 'master' into enum-var-value-coercion - -
9cfd817e Merge pull request #897 from mskrip/modelgen-hook - -Add possibility to hook into modelgen plugin - -
- -- c1e64148 Merge pull request #900 from zannen/master (closes #896) - -- 8a8f0a0f Add autogenerated files (#896) - -- 531729df Move test schema file from example dir into codegen/testserver (#896) - -- 5144775f Add example to check for regression of #896 - -- 3b5df4ce Add check for obviously different TypeReferences (#896) - -- fb96756a Update generated content (#896) - -
fd201a8c Update UniquenessKey for when Element is/isn't nullable (#896) - -With a schema: -type Query { - things1: [Thing] # Note the lack of "!" -} - -type Subscription { - things2: [Thing!] # Note the "!" -} - -the UniquenessKey for the two lists is the same, which causes non-deterministic output. - -
- -- 2a269dd3 Add modelgen hook recipe - -- 6ceb76b6 Test tag generation only by looking up extected tag strings - -
1f272d1b Add possibility to hook into modelgen plugin (closes #876) - -This change introduces option to implement custom hook for model -generation plugin without the need to completly copy the whole `modelgen` plugin. - -that can be: - -```golang -func mutateHook(b *ModelBuild) *ModelBuild { - for _, model := range b.Models { - for _, field := range model.Fields { - field.Tag += ` orm_binding:"` + model.Name + `.` + field.Name + `"` - } - } - - return b -} - -... - -func main() { - p := modelgen.Plugin { - MutateHook: mutateHook, - } - - ... -} - -``` - -
- -
99a55da2 Merge pull request #927 from matiasanaya/feature/bind-to-embedded-interface - -Bind to embedded interface - -
- -- 70e860cc Bind to embedded interface method - -- a745dc78 Fixes #843: Bind to embedded struct method or field - -
f80cab06 Merge pull request #923 from 99designs/gqlparser-1.2.0 - -Update to gqlparser-1.2.0 - -
- -- 7508f4e5 Update to gqlparser-1.2.0 - -
7653a681 Merge pull request #916 from karthikraobr/patch-1 - -3->4 scalars - -
- -
8faa0e3a Merge pull request #917 from colelawrence/patch-1 - -docs: Fix typo in title of "Resolvers" - -
- -- f7d888f9 Merge branch 'master' into patch-1 - -- d722ac66 Update scalars.md - -
1172128c Merge pull request #904 from cfilby/fix-config-docs - -Minor Documentation Tweaks - -
- -- 935f11ed Fix typo in title - -- 026d029c 3->4 scalars - -- 5eb6bef6 Fix weird indending - -- 756dcf6b Merge pull request #907 from lian-yue/patch-1 (closes #860) - -- 2a943eed Update directive.go (closes #860) - -
adbceeea Merge pull request #902 from cfilby/fix-int64-marshalling - -Add support for int64 IDs - -
- -- 13c3d922 Update id function - -- 37191779 Add more tests - -- 0968e0cb Fix VSCode Weirdness, validate formatting - -- a20c96d5 More edits - -- e9e88b41 Stop double indending - -- 9f4df68e More minor doc fixes - -- 7abf0ac3 Fix documentation bug - -- e9730ab9 gofmt - -- c3930f57 Remove redundant paren, add test - -- 395fc85e Add support for int64 ids - -
dbc88428 Merge pull request #889 from thnt/fix-init-with-schema-arg - -fix init not use custom schema filename - -
- -- fc4e513f add test for https://github.com/vektah/gqlparser/pull/109 - -- dd98bb13 fix init not use custom schema - -
4c35356c Merge pull request #883 from 99designs/handle-invalid-types - -Gracefully handle invalid types from invalid go packages - -
- -- 25b70271 Gracefully handle invalid types from invalid go packages - -
046054db Merge pull request #882 from 99designs/testserver-autobind - -Use autobinding in testserver - -
- -- 12c963a4 Use autobinding in testserver - -
305116a0 Merge pull request #879 from coderste/patch-1 - -Fixed broken GitHub link within the APQ page - -
- -
b4867b3f Fixed broken GitHub link within the APQ page - -Small documentation change to fix a broken GitHub link. - -
- -- 9f6b0ee4 v0.10.1 postrelease bump - - - - - - -## [v0.10.1](https://github.com/99designs/gqlgen/compare/v0.10.0...v0.10.1) - 2019-09-25 -- efb6efe0 release v0.10.1 - -
955f3499 Merge pull request #877 from 99designs/fix-websocket-client - -Fix websocket connections on test client - -
- -- ef24a1cc Fix websocket connections on test client - -- c997ec0c v0.10.0 postrelease bump - - - - - - -## [v0.10.0](https://github.com/99designs/gqlgen/compare/v0.9.3...v0.10.0) - 2019-09-24 -- 75a83752 release v0.10.0 - -
0bc3cc86 Merge pull request #875 from 99designs/fix-clientwide-opts - -Fix client global options - -
- -
b43edf5d Merge pull request #874 from 99designs/configurable-slice-element-pointers - -Add config option to omit pointers to slice elements - -
- -- 921aa9cf Fix client global options - -- d0098e60 Add config option to omit pointers to slice elements - -
01893280 Merge pull request #819 from 99designs/fix-directive-interface-nils - -Fix directives returning nils from optional interfaces - -
- -- 34d10975 Fix directives returning nils from optional interfaces - -
eea38e55 Merge pull request #862 from qhenkart/fixes-shareable-link-setting - -fixes shareable link button in playground - -
- -
b5e78342 Merge pull request #870 from 99designs/ws-init-ctx - -Allow changing context in websocket init func - -
- -
034aa627 Merge pull request #871 from 99designs/subscription-middleware - -Call middleware and directives for subscriptions - -
- -
7b41ca3c Merge pull request #872 from 99designs/autobind-prefix - -Allow prefixes when using autobind - -
- -
de8e559f Merge pull request #854 from wabain/nested-map-interface - -Fix for nested fields backed by map or interface - -
- -
cc64f331 Merge pull request #828 from 99designs/feat-rc - -introduce RequestContext#Validate and use it instead of NewRequestContext function - -
- -- ed2a8536 Allow prefixes when using autobind - -- 819cc71b Call middleware and directives for subscriptions - -- 5a7c5903 Allow changing context in websocket init func - -
17f32d28 Merge pull request #861 from 99designs/refactor-test-client - -Refactor test client - -
- -
ed14cf04 Update playground.go - -fix formatting - -
- -
ee8d7a17 Update playground.go - -fix formatting - -
- -- 27389951 fixes shareable link button in playground - -- 4162d11e Refactor test client - -- 8ed6ffc7 Fix for nested fields backed by map or interface - -- 55b21442 Update stale.yml - -- feebee7d stalebot - -
7e643fdc Merge pull request #838 from 99designs/fix-directive-nil - -fix directives return nil handling - -
- -- f33e09e8 Merge branch 'master' into fix-directive-nil - -
8590edef Merge pull request #839 from 99designs/fix-nil-directive - -refactor unimplemented directive handling - -
- -- 1f7ed0d5 refactor unimplemented directive handling - -- 94ad3f2e fix directives return nil handling - -- 5c644a6f v0.9.3 postrelease bump - -- 82758be8 fix error - -- edde2d03 add OperationName field to RequestContext - -- 830e466e introduce RequestContext#Validate and use it instead of NewRequestContext function - - - - - - -## [v0.9.3](https://github.com/99designs/gqlgen/compare/v0.9.2...v0.9.3) - 2019-08-16 -- a7bc468c release v0.9.3 - -
fc02cfe8 Merge pull request #829 from 99designs/fix-2directives - -fix go syntax issue when field has 2 directives - -
- -
924f620c Merge pull request #831 from yudppp/patch-1 - -Fixed scalar reference documentation - -
- -- ca4cc732 Fixed scalar documents - -- cc9fe145 fix go syntax issue when field has 2 directives - -- 6b70be03 v0.9.2 postrelease bump - - - - - - -## [v0.9.2](https://github.com/99designs/gqlgen/compare/v0.9.1...v0.9.2) - 2019-08-08 -- 4eeacc6e release v0.9.2 - -
5628169d Merge pull request #822 from 99designs/windows-import-path-loop - -fix for windows infinite loop - -
- -- a861aa52 lint fix - -- 6348a563 fix for windows infinite loop - -
12893fa4 Merge pull request #821 from 99designs/fix-init - -Fix config loading during gqlgen init - -
- -- 5fafe79c Fix config loading during gqlgen init - -
2599f560 Merge pull request #820 from 99designs/keepalive-on-init - -send keepalive on init - -
- -- 139e4e8d More directive docs - -- f93df340 send keepalive on init - -
8f0d9b48 Merge pull request #816 from nii236/patch-1 - -Update cors.md to allow CORS for websockets - -
- -- 297e09c4 change origin check - -
410d8322 Merge pull request #805 from andrey1s/golangci - -enable-all linters on golangci-lint - -
- -- 504a96bc set enabled linters - -- 91966ef4 add example to lint - -- bcddd7aa fix typo in readme - -- cce06f1d update lint in circleci - -
da1c208e Merge pull request #795 from oshalygin/feature/issue-794-resolve-dead-readme-link - -Update GraphQL Reference Link - -
- -
8343c32c Merge pull request #784 from y15e/add-missing-header - -Add a missing "Upload" header - -
- -
8302463f Merge pull request #797 from muesli/format-fixes - -Format import order using goimports - -
- -
f2825e09 Merge pull request #801 from Schparky/patch-1 - -Documentation: getting-started edits - -
- -
3db5627f Merge pull request #807 from flrossetto/patch-1 - -Fix doc - -
- -- ab228f1b Update cors.md to allow CORS for websockets - -
c4ac9347 Fix doc - -map[string]{interface} -> map[string]interface{} - -
- -- fbbed5b8 use alias when invalid pkg name - -- 2591ea36 fix lint prealloc - -- 3b0e44fe fix lint misspell - -- 6ff62b61 fix lint gocritic - -- cb7f482b fix lint unparam - -- 620552be fix lint goimports - -- 477e804e update config golangci - -- 5b203bcc clarify where the go:generate line should be added - -- 2a3df24e Replace the -v flag as described below. - -- f3eeb639 Clarify that the schema file will be generated - -- 3ac17960 Missing '*' in Todos resolver example - -- bd598c2c Format import order using goimports - -
419f966d Update GraphQL Reference Link (closes #794) - -- The link in the readme has been updated to reference a post by - Iván Corrales Solera, "Dive into GraphQL". The previous link - does not resolve, likely because the personal site is no longer - hosted. - -
- -
373359de Merge pull request #781 from 99designs/fix-default-directives-init - -Set default directives after parsing config - -
- -- ca8b21e3 Add a missing header - -- 8cab5fba Set default directives after parsing config - -
d2c5bf2a Merge pull request #780 from zdebra/master - -fixed generating a description to golang comments for enum type - -
- -
bf2cc90e Merge pull request #768 from 99designs/fix-ptr-from-directive - -Fix pointer returns from directive - -
- -- 446c3df3 fixed generating a description to golang comments for enum type - -- 414a4d34 Merge pull request #771 from sunfmin/master - -- 4d1484b0 Fix doc for how to use [@goField](https://github.com/goField) directives forceResolver option - -- 6f3d7310 Fix pointer returns from directive - -- 21b65112 v0.9.1 postrelease bump - - - - - - -## [v0.9.1](https://github.com/99designs/gqlgen/compare/v0.9.0...v0.9.1) - 2019-06-27 -- b128a291 release v0.9.1 - -
1bbc0cd6 Update release process to keep tags on master - -this was affecting the version shown in go modules when using commits - -
- -
5ffc2975 Merge pull request #764 from 99designs/fix-field-directives-on-roots - -fix field schema directives applied to roots - -
- -- ef3830b5 fix field schema directives applied to roots - -
17ee40ba Merge pull request #761 from 99designs/autobinding - -Autobind models - -
- -- b716bfac Autobind models - -
fc3755f1 Merge pull request #732 from 99designs/schemaconfig-plugin - -Add a plugin for configuring gqlgen via directives - -
- -- c14f8650 Add docs - -- 64aca616 Merge remote-tracking branch 'origin/master' into schemaconfig-plugin - -
5e7e94c8 Merge pull request #756 from andrey1s/field - -generate field defenition and execute field directive - -
- -
ad2ca304 Merge pull request #759 from 99designs/circle-workflows - -CircleCI workflows - -
- -- 0fc822ca CircleCI workflows - -
2dc8423b Merge pull request #758 from franxois/patch-1 - -Update dataloaders.md - -
- -
d0db28ab Update dataloaders.md - -Make SQL request use requested IDs - -
- -- a58ecfe9 add example and test field directive - -- 526beecb update generate field - -- 6e9d7dab generate types directive by location - -- dfec7b68 define fieldDefinition template - -- be890ab9 use UnmarshalFunc in args directives implement - -- dd162f04 define implDirectives template - -
56f3f92b Merge pull request #755 from 99designs/fix-globbing-windows - -fix globbing on windows - -
- -- a4480fb0 fix globbing on windows - -
ba176e2e Merge pull request #754 from 99designs/coveralls - -Add coveralls - -
- -- f28ed264 Add coveralls - -
f4a69ab5 Merge pull request #744 from andrey1s/directive - -add Execute QUERY/MUTATION/SUBSCRIPTION Directives - -
- -- dbd2cc6e simplify resolver test - -
7fed71b6 Merge pull request #728 from fgallina/make-generated-resolver-dependent-types-follow-configured-type - -resolvergen: use the resolver type as base name for dependent types - -
- -
cb284c56 Merge pull request #734 from DBL-Lee/master - -Automatic Persisted Queries - -
- -
726a94f4 Merge pull request #750 from 99designs/ws-connection-param-check - -[websocket] Add a config to reject initial connection - -
- -- 69d7e282 move directive to directives.gotpl - -
090f0bd9 Merge pull request #722 from marwan-at-work/deps - -resolve all pkg dependencies - -
- -- c397be0c Update websocketInitFunc to return error instead of boolean - -- be18ae1f Add a test - -- a6508b6d Update typing, function name and small code refactor - -- e6d791a9 Add websocketOnConnectFunc as a config that can be used to validate websocket init requests - -
c5acbead resolvergen: use the resolver type as base name for dependent types - -The template was outputing invalid code since the resolver type was -not used in places like the embedding at {query,mutation}Resolver. - -This change also ensures that objects like {query,mutation}Resolver -also use the user provided type name as suffix. - -Here's the resulting diff on the code generation with `type: -GeneratedResolver` in the resolver config: - -``` -diff -u resolver.go resolvernew.go ---- resolver.go 2019-05-26 20:04:15.361969755 -0300 -+++ resolvernew.go 2019-05-26 20:04:54.170737786 -0300 -@@ -7,20 +7,20 @@ - type GeneratedResolver struct{} - - func (r *GeneratedResolver) Mutation() MutationResolver { -- return &mutationResolver{r} -+ return &mutationGeneratedResolver{r} - } - func (r *GeneratedResolver) Query() QueryResolver { -- return &queryResolver{r} -+ return &queryGeneratedResolver{r} - } - --type mutationResolver struct{ *Resolver } -+type mutationGeneratedResolver struct{ *GeneratedResolver } - --func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (*Todo, error) { -+func (r *mutationGeneratedResolver) CreateTodo(ctx context.Context, input NewTodo) (*Todo, error) { - panic("not implemented") - } - --type queryResolver struct{ *Resolver } -+type queryGeneratedResolver struct{ *GeneratedResolver } - --func (r *queryResolver) Todos(ctx context.Context) ([]*Todo, error) { -+func (r *queryGeneratedResolver) Todos(ctx context.Context) ([]*Todo, error) { - panic("not implemented") - } -``` - -
- -- cfdbc39a update QueryDirectives - -- f32571ee add SUBSCRIPTION Directive - -- 32462d0f update example todo add directive with location QUERY and MUTATION - -- 3eec887a add Execute QUERY/MUTATION/SUBSCRIPTION Directives - -- 8fcc1868 format - -
e0e1e318 Merge pull request [#1](https://github.com/99designs/gqlgen/issues/1) from radev/master - -Support for external APQ cache - -
- -- 9873d998 Add APQ documentation with example - -- 48292c10 Support pluggable APQ cache implementations. - -- 694f90aa Merge pull request #717 from cbelsole/schema_file_globbing (closes #631) - -- 9be5aad0 Don't inject builtins during schema config - -- 8dc17b47 support GET for apq - -- d36932c5 support automatic persisted query - -- de75743c Add plugin for providing config via schema directives - -- 17a82c37 Provide config to skip generating runtime for a directive - -
ba7092c5 Merge pull request #724 from saint1991/patch-1 - -added a missing close bracket - -
- -- 9c1f8f2a added a missing close bracket - -- 3dd8baf5 resolve all pkg dependencies - -- 1617ff28 Merge pull request #718 from hh/fix-docs (closes #714) - -- 9d332a7d Fixing getting-started documentation - -- 39db1477 updated docs - -- e32c82be cleanup - -- e9389ef8 added schema file globbing fixes #631 - -
4f163cbc Merge pull request #713 from 99designs/faq - -Add faq section - -
- -- 3a21b369 Add faq section - - - - - - -## [v0.9.0](https://github.com/99designs/gqlgen/compare/v0.8.3...v0.9.0) - 2019-05-15 -- ea4652d2 release v0.9.0 - -
f3c8406d Merge pull request #710 from 99designs/slice-pointers - -Use pointers to structs inside slices - -
- -- e669d476 fix imports for vendor based projects - -- 315141d9 Use pointers to structs inside slices - -
9a6a10ab Merge pull request #706 from 99designs/mapping-primitive - -Fix mapping object types onto go primitives - -
- -- a5120054 fix binding to primitive non leaf types - -- b0cd95a1 Test mapping object types onto go string - -
eaa61bb5 Merge pull request #707 from 99designs/gomodules-performance - -make gqlgen generate 10x faster in some projects - -
- -
ab961ce0 Merge pull request #705 from 99designs/fix-error-race - -Fix a data race when handling concurrent resolver errors - -
- -- 71cc8554 make gqlgen generate 10x faster in projects with cgo - -- cab4babe Test mapping object types onto go primitives - -- 962470de Fix a data race when handling concurrent resolver errors - -
9ca43ba9 Merge pull request #701 from 99designs/modelgen-pointers - -Use pointers when embedding structs in generated structs - -
- -- 4f5e9cf0 always use pointers when refering to structs in generated models - -
e2ac8480 Merge pull request #704 from tul/doc-typo - -Fix typo - -
- -- 80ebe644 Fix typo - -
0bd90809 Merge pull request #700 from 99designs/fix-interface-caseing - -Fix interface casing - -
- -
5586ee2c Merge pull request #702 from 99designs/drop-automatic-zeroisnull - -Drop automatic conversion of IsZero to null - -
- -- 75aa99ad Drop automatic conversion of IsZero to null - -- 46c40b74 Fix interface casing (closes #694) - -
e49d44f7 Merge pull request #689 from tgwizard/enforce-request-content-type - -Enforce content type for POST requests - -
- -- 78f277e9 run go generate - -- d4b3de3a Merge remote-tracking branch 'origin/master' into enforce-request-content-type - -
f8ef6d2e Merge pull request #668 from mbranch/complexity - -Fix: complexity case selection - -
- -
c4805049 Merge pull request #655 from hantonelli/file-upload - -File upload - -
- -- 5d1dea0a run go generate - -- 8a0c34a4 Merge branch 'master' into file-upload - -
4e359aa2 Merge pull request #686 from qhenkart/master - -Adds default custom scalar of interface{} - -
- -- aeccbce0 Update test include an example that uses io.Read interface directly - -- d9dca642 Improve documentation - -- f30f1c31 Fix fmt - -- 54226cdb Add bytesReader to reuse read byte array - -
02e9dd8e Fix complexity case selection - -Use the GraphQL field name rather than the Go field name in the generated -`Complexity` func. - -Before this patch, overloading complexity funcs was ineffective because they -were never executed. - -It also ensures that overlapping fields are now generated; mapping all possible -field names to the associated complexity func. - -
- -- bf2d07a4 moves naming convention to a non-go standard - -
d1e8acda Merge pull request #687 from stereosteve/fix-includeDeprecated - -Fix: omit deprecated fields when includeDeprecated=false - -
- -- f7d0b9c8 Enforce content type for POST requests - -- 7d0b8eec Fix: omit deprecated fields when includeDeprecated=false - -- 89c87345 fix grammar in docs - -- 85643f5d fix import - -- ca96a155 update docs - -- 1de25d0c adds interface scalar type - -- 43fc53f9 Improve variable name - -- b961d34e Remove wrapper that is now not required - -- bb023476 Lint code - -- f8484159 Modify graphql.Upload to use io.ReadCloser. Change the way upload files are managed. - -
0306783e Revert "Change graphql.Upload File field to FileData." - -This reverts commit 7ade7c2 - -
- -
afe33f73 Merge pull request #680 from asp24/collect-fields-performance - -Better CollectFields performance - -
- -- 7ba1b3b2 graphql.CollectFields now accept *RequestContext as first arg It was done because RequestContext is a part of executionContext and can be passed directly without extraction from ctx. This is increasing performance when model depth is high - -- 5dfa2285 Pre-allocate mem for collectFields() method result slice - -- 88cdbdf1 Rename getOrCreateField to getOrCreateAndAppendField to describe behaviour - -- a74abc47 Early return in shouldIncludeNode if directives empty - -- 7ade7c21 Change graphql.Upload File field to FileData. - -- da52e810 Extend test and don't close form file. - -
1c95d42a Merge pull request #678 from jonatasbaldin/gin-context-recipe - -Fix unset key and comment block at Gin recipe docs - -
- -- 0b39c445 Fix unset key and comment block - -
5aa6a20b Merge pull request #673 from marwan-at-work/tpl - -codegen/templates: allow templates to be passed in options instead of… - -
- -- 37fd067e fix typo - -- e69b7399 add docs to the templates package - -
8cae895b Merge pull request #676 from jonatasbaldin/gin-context-recipe - -Add recipe to use gin.Context - -
- -- 40c7b952 update test name - -- 5418a290 Add recipe to use gin.Context - -- 16f392ee add unit test - -- a0ee7172 codegen/templates: allow templates to be passed in options instead of os files - -- 2cf7f452 Fix comments (add request size limit, remove useless comments, improve decoding and function signature, improve documentation) - -
5ff60925 Merge pull request #665 from ezeql/patch-1 - -update README.md - -
- -
b42e1ba6 update README.md - -fix link - -
- -- d3770395 Fix tests. - -- 2c1f8573 Fix lint errors. - -- 73b3a536 Fmt graphql.go - -- 83cde4b6 Fix tests. Improve code format. - -- 425849a6 Improve fileupload example readme. Update scalars.md. Add file-upload.md - -- 849d4b1e Make uploadMaxMemory configurable - -- fc318364 Improve format, inline const. - -- 662dc337 Move Upload to injected if defined in the schema as scalars - -- f244442e Fix merge. Remove regexp check. - -
bf79bc92 Merge branch 'master' into next - -# Conflicts: -# codegen/config/config.go -# handler/graphql.go -# handler/graphql_test.go - -
- -- bd4aeaa6 Merge remote-tracking branch 'upstream/master' - -- 3a6f2fb7 Improve test code - -- 239bc46f Add comments - -- be8d6d12 Improve test - -- 4d92696b Clean up code and add tests - -- 2c414edc Improve and add tests - -- 68446e17 Revert change to websocket_test - -- 61c1cb9c Improve examples - -- 493d9375 Improve examples - -- 3c5f8bb9 Improve some examples - -- db7a03b1 Improve tests and names - -- c493d1b9 Revert changing to websocket_test - -- 998f7674 Revert changing the stub file - -- a7e95c59 Fix tests. Improve file generation - -- 10beedb3 Remove not required file - -- 5afb6b40 Add file upload to default schema - -- 9c17ce33 Add file upload - -- b454621d Add support to upload files. - - - - - - -## [v0.8.3](https://github.com/99designs/gqlgen/compare/v0.8.2...v0.8.3) - 2019-04-03 -- 010a79b6 release v0.8.3 - -
3623f7fc Merge pull request #650 from andcan/plugin-funcmap - -Allow plugins to provide additional template funcs - -
- -
a2e59362 Merge pull request #652 from andrey1s/extraBuiltins - -add extra builtins types when no type exists - -
- -
c93d92ba Merge pull request #654 from sharkyze/fix-introscpetion-doc - -doc: fix mistake on introspection doc page - -
- -- 93e72b58 doc: fix error on introspection doc page - -
ef2e51ba Merge pull request #637 from 99designs/fix-is-slice - -Fix Mapping Custom Scalar to Slice - -
- -- e5ff6bc2 add extra builtins types when no type exists - -- 8225f63a Allow plugins to provide additional template funcs - -- 7b533df1 Update ISSUE_TEMPLATE.md - -- 055157f9 Update ISSUE_TEMPLATE.md - -
a148229c Merge pull request #644 from Sauraus/master - -Fix Gin installation instruction - -
- -
52624e53 Fix Gin installation instruction - -Current `go get gin` instruction results in an error from Go: `package gin: unrecognized import path "gin" (import path does not begin with hostname)` - -
- -- 515f2254 Add test case for custom scalar to slice - -
2284a3eb Improve IsSlice logic to check GQL def - -Currently TypeReference.IsSlice only looks at the Go type to decide. -This should also take into account the GraphQL type as well, to cover -cases such as a scalar mapping to []byte - -
- - - - - - -## [v0.8.2](https://github.com/99designs/gqlgen/compare/v0.8.1...v0.8.2) - 2019-03-18 -- ee06517c release v0.8.2 - -
8ac8a1f8 Merge pull request #635 from 99designs/fix-inject-builtin-scalars - -Only Inject Builtin Scalars if Defined in Schema - -
- -- d10e048e Add docs for built-in scalar implementations - -- d27e6eb6 Add example case for object type overriding builtin scalar - -- d567d5c8 Inject non-spec builtin values only if defined - -
3e39b57a Merge pull request #634 from 99designs/fallback-to-string - -Use graphql.String for types wrapping a basic string - -
- -- a2cce0d1 Use graphql.String for types wrapping a basic string - -
fc05501b Merge pull request #633 from 99designs/fix-union-pointers - -Fix Having Pointers to Union Types - -
- -- f02dabb7 Add test case for union pointer - -
8257d423 Check Go type rather than GQL type for ptr - -This is probably a more correct way to check whether we should wrap the -type in a pointer or not, rather than looking at the GrapQL definition. -There may be use-cases where a GraphQL interface/union might be mapped -to a Go stuct. - -
- -
5df0938f Merge pull request #628 from 99designs/fix-ambient-imports - -Move ambient imports into cmd package - -
- -
8e1590d7 Move ambient imports into cmd package - -The getting started docs for dep suggest creating a local gqlgen script, -however these ambient import are in the root, so dep misses them. - -This was changed in 0.8 but the ambient imports weren't moved. - -
- -
58744de9 Merge pull request #622 from 99designs/handle-complexity-root-collisions - -Handle colliding fields in complexity root gracefully - -
- -- c889b314 Handle colliding fields in complexity root gracefully - -
26c395b0 Merge pull request #620 from codyleyhan/cl/error - -Allow user to supply path to gqlerror - -
- -- 12cf01aa Allow user to supply path to gqlerror - -
932322b6 Merge pull request #619 from 99designs/nil-slices - -Support returning nulls from slices - -
- -- a48c55b2 Support returning nulls from slices - -
2b270e4d Merge pull request #618 from codyleyhan/cl/method - -Adds way to determine if a resolver is a function call or value - -
- -- af6dc16d Add test for IsMethod in resolver - -- 27e97535 Expose IsMethod to resolver context - -- f52726de Update README.md - -
ac2422e3 Merge pull request #614 from wesovilabs/master - -Adding entry for workshop - -
- -
db4f7255 Merge pull request #613 from icco/patch-2 - -Upgrade graphql-playground to 1.7.20 - -
- -
163bfc76 Merge pull request #612 from 99designs/maps-changesets - -Maps as changesets - -
- -- 6aa9dfc6 Adding entry for workshop - -
08f936e1 Upgrade graphql-playground to 1.7.20 - -CSS didn't change but js did. - -
- -
8fb1fafd Merge pull request #611 from 99designs/gqlparser-1.1.2 - -Bump gqlparser to 1.1.2 - -
- -- 37983a5f remove some invalid test schema - -- 765ff738 Add some docs on maps - -- 0a92ca46 Support map[string]interface{} in return types - -
ac56112b Merge pull request #610 from tgwizard/dynamic-complexity - -Allow configuring the complexity limit dynamically per request - -
- -- a89050aa Bump gqlparser to 1.1.2 - -- dd288145 Allow configuring the complexity limit dynamically per request - -
485ddf30 Merge pull request #605 from 99designs/fix-default-scalars - -Fix default scalars - -
- -
3ca2599a Merge pull request #606 from jonatasbaldin/add-gin-recipe - -Add Gin recipe - -
- -- 386eede9 Add Gin recipe - -
22be59d1 Merge pull request #604 from cevou/arg-scalar - -Fix directives on args with custom type - -
- -- d02736dc Added test for fix directives on args with custom type - -- 30d235bc Fix default scalars - -
d7b5dc28 Merge pull request #591 from 99designs/fix-577 - -Fix mixed case name handling in ToGo, ToGoPrivate - -
- -- bef6c0a9 Fix directives on args with custom type - -- bc386d79 Fix mixed case name handling in ToGo, ToGoPrivate - - - - - - -## [v0.8.1](https://github.com/99designs/gqlgen/compare/v0.8.0...v0.8.1) - 2019-03-07 -- 229185e4 release v0.8.1 - -
d872af63 Merge pull request #582 from demdxx/master - -Load the playground sources from HTTPS by default - -
- -
8e66832f Merge pull request #589 from 99designs/fix-autocasing-modelgen-bugs - -Fix autocasing modelgen bugs - -
- -- de3b7cb8 Fix autocasing modelgen bugs - -
8e00703e Merge pull request #588 from 99designs/fix-default-scalar-implementation-regression - -Fix default scalar implementation regression - -
- -- b27139ed Fix default scalar implementation regression - -
737a59a3 Merge pull request #579 from 99designs/fix-camelcase - -Take care about commonInitialisms in ToGo - -
- -- 52838cca fix ci - -- 2c3783f1 some refactoring - -- eb453674 address comment - -- dcd208d9 Merge pull request #584 from 99designs/fix-deprecated-directive - -
5ba8c8ea Add builtin flag for build directives - -These have an internal implementation and should be excluded from the -DirectiveRoot. In the future this may be a func that plugins could use -to add custom implementations. - -
- -
b8526698 Load the playground sources from HTTPS by default - -For some browsers on non-secure domains resources from CDN doesn't loads, so I made all cdn.jsdelivr.net resources of the playground by HTTPS by default - -
- -- 6ea48ff6 Take care about commonInitialisms in ToCamel - -
1968a7bc Merge pull request #576 from jflam/patch-1 - -Update README.md - -
- -
44becbbe Update README.md - -Fixed typo in MD link ttps -> https - -
- - - - - - -## [v0.8.0](https://github.com/99designs/gqlgen/compare/v0.7.2...v0.8.0) - 2019-03-04 -- f24e79d0 release v0.8.0 - -
55df9b8d Merge pull request #574 from 99designs/next - -v0.8.0 - -
- -
aedcc68a Merge pull request #573 from 99designs/plugin-docs - -Very rough first pass at plugin docs - -
- -- 8f91cf56 Very rough first pass at plugin docs - -
3d9ad75e Merge pull request #572 from 99designs/handle-nonexistant-directories-when-genreating-packagenames - -Handle non-existant directories when generating default package names - -
- -- 08923334 Handle non-existant directories when generating default package names - -
2ef4b443 Merge pull request #571 from 99designs/automatically-bind-to-int32-int64 - -Automatically bind to int32 and int64 - -
- -
2888e96c Merge pull request #570 from 99designs/vendor-packages-workaround - -Workaround for using packages with vendored code - -
- -- fb87dc39 Automatically bind to int32 and int64 - -
f2d9c3f7 Merge pull request #569 from 99designs/improve-introduction - -Introduction Improvements - -
- -- 1e7aab63 Workaround for using packages with vendored code - -- 5c692e29 User README as canonical introduction - -- 25bdf3d6 Consolidate Introduction documents - -- d81670d8 Add initial contributing guidelines - -- d9a9a532 playground: secure CDN resources with Subresource Integrity - -
cb38b4be Merge pull request #568 from MichaelMure/secured-playground - -playground: secure CDN resources with Subresource Integrity - -
- -
0258e1a2 Merge pull request #565 from steebchen/next - -Fix cli config getters - -
- -- 6ad1d97e Move feature comparison - -- 37cbbd6d playground: secure CDN resources with Subresource Integrity - -- da12fd11 Fix cli config getters - -
51266b8f Merge pull request #554 from 99designs/fix-missing-recover - -Recover from panics in unlikly places - -
- -- 67795c95 Recover from panics in unlikly places - -
56163b45 Merge pull request #553 from 99designs/getting-started-0.8 - -Update Getting Started for 0.8 and Go Modules - -
- -- 0bd120b5 Update dep code as well - -- 6c576032 Update getting started with 0.8 generated code - -- ba761dcf Reintroduce main package in root - -- cdc575a2 Update getting started with Go Modules support - -- 378510e5 Move Getting Started above Configuration - -- d261b3fb Fix navigation font weights - -
327a1a34 Merge pull request #551 from 99designs/improved-collect-fields-api - -Improved Collect Fields API and Documentation - -
- -
6439f197 Merge pull request #552 from 99designs/always-return-struct-pointers - -Always return *Thing from resolvers for structs - -
- -- 318639bb Always return *Thing from resolvers for structs - -- e61b3e0b Add Field Collection docs - -
ef0223cf Merge pull request #541 from 99designs/fix-underscore-only-fields - -Allow underscore only fields and naming collisions to be aliased explicitly - -
- -- 58b2c74f drive by config fix - -- f6c52666 Add a test for aliasing different cases (closes #376) - -- 8c2d15ee Fix underscore only fields (closes #473) - -- 0eb8b5c1 Merge remote-tracking branch 'origin/master' into HEAD - -
015d02eb Merge pull request #542 from Elgarni/add-more-validation-checks-on-yml-config-file - -Add more validation checks on .yml config file - -
- -
647c62a5 Merge pull request #550 from 99designs/fix-unstable-marshaler-func - -Fix unstable external marshaler funcs with same name as type - -
- -- 3a8bf33f Add CollectAllFields test cases - -- 9ebe7717 Fix unstable external marshaler funcs with same name as type - -
a1195843 Merge pull request #544 from enjoylife/fix-directive - -Fix directives on fields with custom scalars - -
- -- dc925c46 Added a test for config checking - -- b56cb659 Refactored config check so that it runs after being normalized - -- dc6a7a36 Add CollectAllFields helper method - -
a2e61b3d Added a model and used directive on an input field within the integration schema - -Added to the integration schema such that the build will catch the directive bug in question. - -
- -- 0b0e4a91 Fix directives on fields with custom scalars - -- 8ac0f6e4 Removed redundant semicolons - -- 3645cd3e Add more validation checks on .yml config file - -
1b8b1ea1 Fix typo in README - -Fix typo in README in selection example directory to point to the selection example, not the todo example. - -
- -
66120d8f Merge pull request #535 from awiede/master - -Fix typo in README - -
- -- fcacf200 Merge remote-tracking branch 'origin/master' into HEAD - -
b9819b21 Merge pull request #540 from 99designs/check-is-zero - -Automatically convert IsZero to null - -
- -
03a655dc Merge pull request #526 from 99designs/union-fragment-bug - -Union Fragment Bug Fix - -
- -- 99e9f41f Use Implements for type Implementors in codegen - -
ccca823f Separate out conditionals in collect fields - -These conditions are not really related, and I missed the second -conditional when reading through the first time. - -
- -- efe8b026 Add reproducable test cases - -- 306da15f Automatically convert IsZero to null - -- f81c61d3 Merge pull request #539 from 99designs/test-nullable-interface-pointers (closes #484) - -
f5200c80 Merge pull request #498 from vilterp/playground-content-type - -add `content-type: text/html` header to playground handler - -
- -- de148d13 Test for #484 - -- 9a48a007 Merge pull request #538 from 99designs/test-input-marshalling (closes #487) - -- 7a82ab43 Test for #487 - -
48a7e07f Merge pull request #537 from 99designs/stub-generation - -Stub generation - -
- -- 787b38d8 Break testserver tests down into smaller files using stubs - -- c5e3dd44 add stub generation plugin - -
43db679a Merge pull request #534 from 99designs/multiple-bind-types - -Multiple bind types - -
- -- b26b915e Move input validation into gqlparser see https://github.com/vektah/gqlparser/pull/96 - -
7d394222 Fix typo in README - -Fix typo in README in selection example directory to point to the selection example, not the todo example. - -
- -- 42131868 Linting fixes - -- 956d0306 Arg type binding - -- 6af3d85d Allow multiple field bind types - -- 3015624b Regen dataloader with correct version - -- 50f7d9c8 Add input field directives back in - -- 8047b82a Fix nullability checks in new marshalling - -- b3f139c9 Cleanup field/method bind code - -- cf94d3ba Removed named types - -
82ded321 Merge pull request #532 from 99designs/fix-missing-json-content-type - -Fix set header to JSON earlier in GraphQL response - -Update the GraphQL handler to set the Response Header to JSON earlier for -error messages to be returned as JSON and not text/html. - -Fixes https://github.com/99designs/gqlgen/issues/519 - -## Notes: -- Add checks for JSON Content-Type checks in decode bad queries tests - -
- -
b4c5a074 Fix set header to JSON earlier in GraphQL response - -Update the GraphQL handler to set the Response Header to JSON earlier for -error messages to be returned as JSON and not text/html. - -Fixes https://github.com/99designs/gqlgen/issues/519 - -== Notes: -- Add checks for JSON Content-Type checks in decode bad queries tests - -
- -- 533b08b6 remove wonky input directives - -- 60473555 Shared arg unmarshaling logic - -
a7c8abe6 Merge pull request #529 from 99designs/websocket-keepalive - -Add websocket keepalive support - -
- -- 555d7468 Remove TypeDefinition from interface building - -- cfa012de Enable websocket connection keepalive by default - -
c5b9b5a8 Use constant tick rate for websocket keepalive - -Some clients (e.g. apollographql/subscriptions-transport-ws) expect a -constant tick rate for the keepalive, not just a keepalive after x -duration of inactivity. - -
- -- 693753fc Add websocket keepalive support - -- 162afad7 enums dont exist in runtime - -
d0b6485b Merge pull request #525 from 99designs/stop-grc-panic - -Stop GetResolverContext from panicking when missing - -
- -
78cfff48 Merge pull request #528 from 99designs/fix-todo-directive - -Fix Todo Example Directive - -
- -
5e1bcfaf Remove parent check in directive - -This should always be true, and currently has a bug when comparing -pointers to structs. Can just be removed. - -
- -- c1b50cec Stop GetResolverContext from panicking when missing - -- 44aabbd3 Move all build steps back into file containing defs - -- 4e49d489 Merge object build and bind - -- 97764aec move generated gotpl to top - -- d380eccf promote args partial to full template - -- 1bc51010 Everything is a plugin - -
055fb4bc Merge pull request #514 from 99designs/gomod - -Add support for go modules - -
- -- 48eb6c52 Update appveyor - -- 9e02a977 fix integration test - -- 251e8514 Add support for go modules - -
62175eab Merge pull request #502 from 99designs/model-plugin - -Model plugin - -
- -- 0f884493 linting fixes - -- c6eb1a85 Extract model generation into a plugin - -
d3f1195c add `content-type: text/html` header to playground handler - -This ensures that the browser doesn't think it should download the page -instead of rendering it, if the handler goes through a gzipping -middleware. - -
- -
f94b4b78 Merge pull request #497 from azavorotnii/small_fixes - -Small fixes - -
- -- 21769d93 Ensure no side affect from preceding tests in wont_leak_goroutines test - -- 10f4ccde newRequestContext: remove redundant else part - -- a76e0228 Add cache usage for websocket connection - -- 940db1f9 Fix cacheSize usage in handler - -
fba9a378 Merge pull request #492 from 99designs/unified-merge-pass - -Unified merge pass - -
- -- a7f719a3 update appveyour to not rely on main - -- f46b7c8e Reclaim main package for public interface to code generator - -- 6b829037 Extract builder object - -- 87b37b0c Replace string based type comparisons with recursive types.Type check - -
82b1917d Merge pull request #490 from 99designs/bind-directly-to-types - -Bind directly to AST types, instead of copying out random bits - -
- -- 1d86f988 extract argument construction - -- 4b85d1b0 Merge buildInput into buildObject - -- db33d7b7 Extract graphql go merge into its own package - -- afc773b1 Use ast definition directly, instead of copying - -- 8298acb0 bind to types.Types in field / arg references too - -- 38add2c2 Remove definition embedding, use normal field instead - -- 950ff42c Bind to types.Type directly to remove TypeImplementation - -- 70c852eb Add lookup by go type to import collection - -- eb101161 Remove aliased types, to be replaced by allowing multiple backing types - -
e79252b0 Merge pull request #488 from 99designs/refactor-config - -Refactor config - -
- -- 4138a372 rename generator receiver - -- bec38c7e Extract config into its own package - -- 34b87871 Rename core types to have clearer meanings - -- f10fc649 Merge remote-tracking branch 'origin/next' into HEAD - -
dd972081 Merge pull request #486 from nicovogelaar/feature/list-of-enums - -add list of enums - -
- -- 1140dd85 add unit test for list of enums - -- 1e3e5e9b add list of enums - -- f87ea6e8 Merge remote-tracking branch 'origin/master' into HEAD - -
473f4f0c Merge pull request #465 from 99designs/performance-improvments - -Performance improvments - -
- -- f9ee6ce0 return arg in middleware - -
5c8b1e24 Avoid unnessicary goroutines - -goos: linux -goarch: amd64 -pkg: github.com/99designs/gqlgen/example/starwars -BenchmarkSimpleQueryNoArgs-8 300000 25093 ns/op 6453 B/op 114 allocs/op -PASS -ok github.com/99designs/gqlgen/example/starwars 10.807s - -
- -
b0ffa22a Remove strconv.Quote call in hot path to avoid some allocs - -go test -benchtime=5s -bench=. -benchmem -goos: linux -goarch: amd64 -pkg: github.com/99designs/gqlgen/example/starwars -BenchmarkSimpleQueryNoArgs-8 200000 32125 ns/op 6277 B/op 118 allocs/op -PASS -ok github.com/99designs/gqlgen/example/starwars 9.768s - -
- -
2cf5a5b8 Add a benchmark - -go test -benchtime=5s -bench=. -benchmem -goos: linux -goarch: amd64 -pkg: github.com/99designs/gqlgen/example/starwars -BenchmarkSimpleQueryNoArgs-8 200000 32680 ns/op 6357 B/op 126 allocs/op -PASS -ok github.com/99designs/gqlgen/example/starwars 9.901s - -
- -- 5e0456fe fix fmt anf metalint generated code - -- b32ebe14 check nullable value for go1.10 - -- d586bb61 use arg value for the ResolveArgs - -- e201bcb5 set default nil arg to ResolverContext - -- 6fa63640 remove empty line in generated files - -- 139ed9fb fix go10 assign exist variable by eq - -- 428c6300 add nullable argument to directives - -- 74096033 move chainFieldMiddleware to generate code for BC - -- be51904c check nullable arguments - -- 6b005094 add test directives generate - -- 047f2ebc update inline template - -- a13b31e9 metalinter - -- 526bef0b generate servers and add path to error - -- 29770d64 resolve = in template - -- 3a729cc3 update recursive middleware - -- 8b3e634e update tempate and set Dump public - -- e268bb75 Merge remote-tracking branch 'upstream/master' into directives - -- e8f0578d add execute ARGUMENT_DEFINITION and INPUT_FIELD_DEFINITION directive - - - - - - -## [v0.7.2](https://github.com/99designs/gqlgen/compare/v0.7.1...v0.7.2) - 2019-02-05 -- da1e07f5 release v0.7.2 - -
8c0562c1 Merge pull request #530 from 99designs/websocket-keepalive-master - -Add websocket keepalive support - -
- -- 43fdb7da Suppress staticcheck lint check on circleci - -
9c4b877a Use constant tick rate for websocket keepalive - -Some clients (e.g. apollographql/subscriptions-transport-ws) expect a -constant tick rate for the keepalive, not just a keepalive after x -duration of inactivity. - -
- -- d36d3dc5 Add websocket keepalive support - -
39216361 Merge pull request #476 from svanburen/patch-1 - -Update config.md - -
- -
9f6f2bb8 Update config.md - -Add a missed word and add an apostrophe - -
- -- c033f5fc Fix edit link positioning - -- b3f163d8 Add not about relative generate path - -- 675ba773 Update errors.md - -
5c870a48 Merge pull request #461 from ryota548/patch-1 - -Update getting-started.md - -
- -
9bcd27c1 Update getting-started.md - -modify `graph/graph.go` to `resolver.go` - -
- - - - - - -## [v0.7.1](https://github.com/99designs/gqlgen/compare/v0.7.0...v0.7.1) - 2018-11-29 -
3a7f37c7 Merge pull request #455 from 99designs/fix-deprecated-fields - -Fix deprecated fields - -
- -- b365333b Fix graphiql deprecating all fields - -- 99610be9 Get chat example up to date - - - - - - -## [v0.7.0](https://github.com/99designs/gqlgen/compare/v0.6.0...v0.7.0) - 2018-11-28 -- a81fe503 release v0.7.0 - -
4bfc82d7 Merge pull request #453 from 99designs/deprecate-binary - -Add Deprecation Warning to Binary - -
- -
8dd29b85 Merge pull request #454 from 99designs/update-gqlparser - -Update gqlparser to latest - -
- -- 747c3f9c Update gqlparser to latest - -
d6d9885f Merge pull request #416 from 99designs/improved-getting-started - -Improve Getting Started Documentation — No Binary Approach - -
- -- d22f03c6 Add deprecation warning - -- 878f3945 Minor fixes to getting started code examples - -
6a02657c Merge pull request #447 from 99designs/disable-introspection - -Add config option to disable introspection - -
- -- b9fbb642 Mention recursive-ness of generate ./... - -- e236d8f3 Remove generate command from resolver.go - -- 04a72430 Re-add final touches section to getting started - -- 3a7a5062 Add handler import to root cmd - -- 9dba96d5 Fix GraphQL capitalisation - -- 1dfaf637 Minor updates to getting started from feedback - -- 94b95d97 Some CSS fixes - -- a36fffd2 Updated getting started with new no-binary approach - -- 601354b3 Add blockquote breakout style - -
6bea1d88 Merge remote-tracking branch 'origin/master' into disable-introspection - -Regenerate - -
- -
e4bad0e6 Merge pull request #449 from 99designs/increase-float-precision - -Increase float precision - -
- -
c5589792 Merge pull request #450 from 99designs/import-refactor - -Refactor import handling - -
- -- 62f0d085 Edit copy for introspection docs - -
63fc2753 Merge pull request #452 from cemremengu/patch-1 - -Fix typo in directives.md - -
- -
da31e8ed Update directives.md - -Fix small typo - -
- -- 83e33c13 Remove a debug print - -- 6c575914 fix doc indentation - -- f03b32d3 Use new import handling code - -- c45546e5 Increase float precision - -- 77f2e284 Start moving import management to templates - -- c114346d Decouple loader creation from schema - -
9d636e78 Merge pull request #448 from 99designs/update-gqlparser - -Update to latest gqlparser - -
- -- d6ce42df Update to latest gqlparser - -- b0acd078 Add config option to disable introspection - -
f9c880b6 Merge pull request #446 from 99designs/fix-flakey-test - -Fix flakey goroutine test - -
- -
5461e967 Merge pull request #445 from 99designs/remove-graphqlgen - -Remove graphqlgen link - -
- -- 8a5039d8 Fix flakey goroutine test - -
4b082518 Merge pull request #439 from snormore/pointer-slice - -Fix type binding validation for slices of pointers like []*foo - -
- -- 293b9eaf Remove graphqlgen link - -
77b27884 Merge pull request #443 from mgutz/patch-1 - -fix generate stubs sentence - -
- -- ae1c7732 fix generate stubs sentence - -- 827dac5e Fix type binding validation for slices of pointers like []*foo - -
f7932b40 Merge pull request #435 from matiasanaya/update-readme - -Update README.md comparison with graph-gophers - -
- -- a816208b Update README.md comparison with graph-gophers - -
d25e3b4b Merge pull request #422 from gracenoah/model-method-context - -accept an optional ctx parameter on model methods - -
- -
0ac6fa57 Merge pull request #434 from urakozz/patch-1 - -Tracer: fixed nil pointer issue - -
- -- d4f7c954 Update context.go - -
4c4ccf47 Update context.go - -Right now code generated with latest master fails since there are usages of Trace but there is no any single write to this variable - -
- -- 5faf3a2b re-generate - -- 6fed8947 rebase fixes - -- 4c10ba55 fix generated code - -- 8066edb7 add tests - -- 9862c30f mention contexts on model methods in docs - -- 602a83d6 make ctx method resolvers concurrent - -- 49755120 accept an optional ctx parameter on model methods - -
02a19352 Merge pull request #429 from 99designs/refactor-gofmt - -apply go fmt ./... - -
- -- 6a77af13 apply gofmt on ./.circleci/test.sh - -- c656dc31 apply go fmt ./... - -
3f598bdc Merge pull request #427 from anurag/patch-1 - -Fix docs typo - -
- -- cac61bb2 Fix docs typo - -
9f4afe3a Merge pull request #425 from 99designs/render - -Switch to hosting docs on render.com - -
- -
9875e74b Switch to hosting docs on render.com - -Render.com has offered to host our static site for free, and have -a pretty simple setup for rebuilding on merge to master. I've -switched the DNS records and updated the docs. - -
- -
981fd10a Merge pull request #419 from 99designs/fix-capture-ctx - -fix unexpected ctx variable capture on Tracing - -
- -- 027803d2 address comment - -- 2b090de9 address comment - -- d3238d54 chore - -- a2c33f13 write ctx behavior test & refactoring tracer test - -- 5c28d011 fix unexpected ctx variable capture on Tracing - -
4bda3bc1 Merge pull request #411 from 99designs/feat-geterrors - -add GetErrors to RequestContext - -
- -- a4eaa400 add tests for RequestContext#GetErrors - -
53f33f77 Merge pull request #410 from 99designs/move-tracing-to-contrib - -Move tracing to contrib - -
- -- 19403832 add GetErrors to RequestContext - -- f0dbce5a Move tracing to contrib - -
a3a92775 Merge pull request #409 from 99designs/graphql-playground-1.7.8 - -Bump to the latest version of graphql-playground - -
- -
d2648580 Merge pull request #402 from 99designs/feat-opencensus - -add Tracer for OpenCensus - -
- -- 7286e244 fix shadowing - -- af38cc5a Bump to the latest version of graphql-playground - -- 8bbb5eb7 fix some tests - -- 256e741f add complexityLimit and operationComplexity to StartOperationExecution - -- 4e7e6a1c Merge branch 'master' into feat-opencensus - -
926ad17a Merge pull request #403 from 99designs/feat-complexity - -copy complexity to RequestContext - -
- -- 2d3026cb Merge branch 'master' into feat-complexity - -- 59ef91ad merge master - -- c9368904 Merge branch 'master' into feat-opencensus - -
b26ee6b4 Merge pull request #404 from 99designs/feat-apollo-tracing - -add apollo-tracing support - -
- -- fd4f5587 fix timing issue - -- 91e3e88d address comment - -- a905efa8 fix lint warning - -- b2ba5f86 address comment - -- 561be1c0 add Apollo Tracing sample implementation - -- 83c7b2cb add Start/EndOperationParsing & Start/EndOperationValidation methods to Tracer - -- b5305d75 address comment - -- 784dc01f oops... - -- a027ac21 copy complexity to RequestContext - -- ececa23c add Tracer for OpenCensus - -
0d5c65b6 Merge pull request #400 from 99designs/fix-ci - -fix Circle CI test - -
- -- 00d11794 add mutex to logger - -- 884d35c6 fix race condition - -- f70cedc2 fix Circle CI test - -
1b17b5a2 Merge pull request #392 from 99designs/feat-tracer - -Add Tracer layer - -
- -
184e48cb Merge pull request #396 from 99designs/remove-ci-exclusion - -Run generate ./... and test ./... in circle - -
- -
fd5d9eca Merge pull request #395 from 99designs/feat-extension-example - -add Type System Extension syntax example - -
- -- 686c71a4 Run generate ./... and test ./... in circle - -- 304d3495 fix https://github.com/99designs/gqlgen - -- 85322586 address comment - -
195f952b fix CI failed - -AppVeyor handle this test, But Circle CI is not - -
- -- b5b767c4 address comment - -- d723844b add Type System Extension syntax example - -- df685ef7 change timing of EndFieldExecution calling - -- 94b7ab02 refactor Tracer interface signature that fit to apollo-tracing specs - -
8eb2675a Revert "change field marshaler return process that make it easy to insert other processing" - -This reverts commit 583f98047f5d1b6604d87e7b8d6f8fd38082d459. - -
- -- c8af48cd rename Tracer method name - -- a3060e80 refactor Tracer signature - -- d319afe6 add support request level tracer - -- 1c5aedde add support field level tracer - -- 583f9804 change field marshaler return process that make it easy to insert other processing - -- ab4752c2 Update README.md - -
3447dd2d Merge pull request #389 from 99designs/multiple-schemas - -Support multiple schemas - -
- -- a230eb04 Support multiple schemas - -
20a5b6c7 Merge pull request #369 from vetcher/master - -reverse errors and data order in response - -
- -- f1f043b9 reverse 'data' and 'error' fields order in failure tests - -
3eab22a3 Merge pull request #370 from rodrigo-brito/fix-underscore - -Underscore on field name finder - -
- -- 0ad3d3ce fix on struct name finder - -- 42e11045 reverse errors and data order in response - - - - - - -## [v0.6.0](https://github.com/99designs/gqlgen/compare/v0.5.1...v0.6.0) - 2018-10-03 -- 6f486bde release v0.6.0 - -
7833d0cb Merge pull request #365 from 99designs/dont-guess-imports - -Don't let goimports guess import paths - -
- -- 732be395 Don't let goimports guess import paths - -
926eb9d8 Merge pull request #364 from 99designs/query-cache-test - -Add a stress test on query cache - -
- -- bab70df5 Add a stress test on query cache - -
84481761 Merge pull request #362 from 99designs/fix-error-docs - -fix error docs - -
- -- 23b58f6d fix error docs - -
8f0ef777 Merge pull request #361 from 99designs/revert-360-revert-335-typed-interfaces - -Revert "Revert "Generate typed interfaces for gql interfaces & unions"" - -
- -- 77257d1e Revert "Revert "Generate typed interfaces for gql interfaces & unions"" - -
1cae19bb Merge pull request #359 from 99designs/fix-null-arg-error - -Fix Issue With Argument Pointer Type - -
- -
ee862717 Merge pull request #360 from 99designs/revert-335-typed-interfaces - -Revert "Generate typed interfaces for gql interfaces & unions" - -
- -- 02658647 Revert "Generate typed interfaces for gql interfaces & unions" - -
bc35d730 Merge pull request #335 from 99designs/typed-interfaces - -Generate typed interfaces for gql interfaces & unions - -
- -- 48724dea Removed redundant file - -- 2432ab3c Fix other tests with pointer change - -- 20add126 Fix test case - -
f5c03401 Do not strip ptr for args with defaults - -This fails if a client still sends a null value. If an arg is nullable -but has a default, then null is still a valid value to send through. - -
- -- 0c399270 Add test case - -
b836a976 Merge pull request #358 from 99designs/fix-embedded-pointer - -Fix Embedded Pointer - -
- -- d3e27553 Bump gqlparser to latest master - -- b8af0c81 Use types.Implements to check if an interface implementor accepts value recievers - -
2ab05daf Merge pull request #353 from 99designs/resolver-ctx-parenting - -Parent middleware generated contexts - -
- -- faf0416b Parent resolver generated contexts - -- caa474c6 Check for embedded pointer when finding field on struct - -- f302b408 Added reproduce test case - -
14cf46bc Merge pull request #348 from gissleh/feat-websocket-initpayload - -Added parsing of the websocket init message payload - -
- -- 3147d914 Updated example in docs to use handler.GetInitPayload instead of graphql.GetInitPayload - -- 32f0b843 Moved InitPayload from graphql to handler package, updated test to import it from there. - -- 01923de6 Moved initPayload to wsConnection member, changed wsConnection.init to return false on invalid payload - -- 25268ef9 Added information about it under recipes/authentication doc - -- 575f28e0 Fixed graphql.GetInitPayload panic if payload is nil. - -
380828fa Added parsing of the websocket init message payload, and making it available via the context passed to resolvers. - -* Added GetInitPayload(ctx) function to graphql -* Added WithInitPayload(ctx) function to graphql -* Added WebsocketWithPayload method to client.Client (Websocket calls it with a nil payload for backwards compability) -* Added tests for these changes in codegen/testserver/generated_test - -
- -
2bd1cc2e Merge pull request #334 from 99designs/support-response-extensions - -Support Extensions in Response - -
- -- 8fdf4fbb Add test case for extension response - -- 60196b87 Add extensions to response struct - -- cbde0ea9 Generate typed interfaces for gql interfaces & unions - - - - - - -## [v0.5.1](https://github.com/99designs/gqlgen/compare/v0.5.0...v0.5.1) - 2018-09-13 -- 636435b6 release v0.5.1 - -- bfb48f2f Update README.md - -
869215a7 Merge pull request #339 from 99designs/fix-subscription-goroutine-leak - -Fix gouroutine leak when using subscriptions - -
- -
535dd24b Merge pull request #338 from codyleyhan/cl/docs - -Adds docs for how resolvers are bound - -
- -- baa99fc5 cleaned up resolver doc - -
647fbbc9 Merge pull request #340 from chris-ramon/patch-1 - -README.md: Updates `graphql-go/graphql` features. - -
- -
729e09c8 README.md: Updates `graphql-go/graphql` features. - -- Subscription support: https://github.com/graphql-go/graphql/issues/49#issuecomment-404909227 -- Concurrency support: https://github.com/graphql-go/graphql/issues/389 -- Dataloading support: https://github.com/graphql-go/graphql/pull/388 - -
- -- 229a81be Fix gouroutine leak when using subscriptions - -- c15a70ff Adds docs for how resolvers are bound - -- 35c15c94 Add link to talk by Christopher Biscardi - -
72edf98a Merge pull request #331 from edsrzf/arg-refactor - -Refactor arg codegen - -
- -- 31505ff4 Use arg function for generated Complexity method - -- ebdbeba0 Just realized "if not" is allow in templates - -- 861a805c Regenerate code - -
639727b6 Refactor arg codegen - -Now a function is generated for each field and directive that has -arguments. This function can be used by both field methods as well as -the `Complexity` method. - -The `args.gotpl` template now generates the code for this function, so -its purpose is a little different than it used to be. - -
- -
8026e63b Merge pull request #330 from edsrzf/string-compare - -Use built-in less than operator instead of strings.Compare - -
- -- c770b4e7 Use built-in less than operator instead of strings.Compare - - - - - - -## [v0.5.0](https://github.com/99designs/gqlgen/compare/v0.4.4...v0.5.0) - 2018-08-31 -- 5bc4665f release v0.5.0 - -
b48c6b92 Merge pull request #326 from 99designs/version - -Add version const - -
- -- 14587a5f Add version const - -
7d44dd6b Merge pull request #315 from edsrzf/query-complexity - -Query complexity calculation and limits - -
- -- 2ab857ee Merge branch 'master' into query-complexity - -- 6e408d5d Interfaces take max complexity of implementors - -
d08b9c4a Merge pull request #325 from edsrzf/no-get-mutations - -Only allow query operations on GET requests - -
- -
82a28b57 Only allow query operations on GET requests (closes #317) - -This mitigates the risk of CSRF attacks. - -
- -- 239b1d22 Don't emit complexity fields for reserved objects - -- 8da5d61b Generate complexity for all fields. Fix bugs. Re-generate examples. - -
40943c6d Merge pull request #322 from 99designs/drop-old-flags - -Drop old cli flags - -
- -
8c17eea9 Merge pull request #320 from andrioid/master - -Description added to generated Model code - -
- -
988b367a Merge pull request #316 from 99designs/feat-concurrent-each-element - -use goroutine about processing each array elements - -
- -- e5265ac2 Fix complexity template bug - -- 7c040045 now with field values - -- 08ab33be starting to look better - -- e834f6b9 Query complexity docs - -- a0158a4e Drop old cli flags - -- bb78d2fa go generate ./.. - -- 2488e1b3 Merge branch 'master' of https://github.com/99designs/gqlgen - -
f6a733ae Merge pull request #308 from codyleyhan/tags - -Finds fields by configurable struct tag - -
- -
f7aeb88a Merge pull request #321 from 99designs/remove-typemap - -Remove support for the old json typemap - -
- -- d63449b9 Remove support for the old json typemap - -- fce4c722 address comment - -- 8c3aed7d Merge branch 'master' into query-complexity - -
cecd84c6 Add complexity package tests - -Also some small behavior fixes to complexity calculations. - -
- -
002ea476 Merge pull request #318 from edsrzf/query-cache - -Add query cache - -
- -- fcd700b6 Panic on lru cache creation error - -
78c57079 Add query cache - -This commit adds a query cache with a configurable maximum size. -Past this size, queries are evicted from the cache on an LRU basis. - -The default cache size is 1000, chosen fairly arbitrarily. If the size -is configured with a non-positive value, then the cache is disabled. - -Also ran `dep ensure` to add the new dependency to `Gopkg.lock`. - -
- -- 076f9eac removed dirt - -- 6ae82383 trying to get description with generated models - -- 7d6f8ed4 fixes case where embeded structs would cause no field to be found - -- 02873495 use goroutine about processing each array elements - -- 40f904a6 Merge branch 'master' of github.com:99designs/gqlgen into tags - -- 56768d6b adds tests for findField - -- 556b93ac Run go generate ./... - -
2dcb2dd8 Merge pull request #314 from 99designs/directive-obj - -Add obj to Directives - -
- -- 0e2aaa9e Merge branch 'master' of github.com:99designs/gqlgen into tags - -- 7cfd9772 fixes field selection priority - -- 238a7e2f Add complexity support to codegen, handler - -- 95ed529b New complexity package - -- 1fda3ede Add obj to Directives - -
9b247102 Merge pull request #301 from 99designs/feat-directive-parent - -add Result field to ResolverContext - -
- -- 9ec385d1 Merge branch 'tags' of github.com:codyleyhan/gqlgen into tags - -- c5849929 adds binding by passed tag - -- 6ef2035b refactor set Result timing - -- 568a72e9 add some refactor - -
50588a8a Merge pull request #299 from 99designs/test-init-on-windows - -Test gqlgen init on windows - -
- -- 9148adfc Test gqlgen init on windows - -- c7fd8416 Merge branch 'master' into feat-directive-parent - -
3f8a601b Merge pull request #312 from 99designs/validate-gopath - -Validate gopath when running gqlgen - -
- -
77e69552 Merge pull request #310 from 99designs/sitemap-404s - -Remove 404s from sitemap - -
- -
0b6cedfb Merge pull request #311 from jekaspekas/fix-mapstructure-err - -fix mapstructure unit test error - -
- -- b07736ef Validate gopath when running gqlgen - -
b082227d fix mapstructure unit test error - -fix unit test error "mapstructure: result must be a pointer". It appears instead of resolver returned error. - -
- -- 25b12cb6 Remove 404s from sitemap - -
4a6f505d Merge pull request #309 from 99designs/pr-template - -Add a PR template - -
- -- 64f3518e run generate - -- a81147df Add a PR template - -- 15d8d4ad Merge branch 'introspection-directive-args' into HEAD - -- 12efa2d5 add tests - -- 95b6f323 finds fields by json struct tag - -- 07ee49f3 Added args to introspection scheme directives. - -- e57464fe refactor ResolverContext#indicies and suppress lint error - -- 09e4bf8c add Result field instead of ParentObject field - -
b8695fb5 Merge pull request #304 from 99designs/newline-for-init-response - -Put newline at end of `gqlgen init` output - -
- -- fabc6f8f Merge branch 'master' into feat-directive-parent - -- e53d224e Merge branch 'master' into feat-directive-parent - -
de750645 Merge pull request #298 from 99designs/handle-response-nulls - -Nulls in required fields should cause errors and bubble - -
- -- c8552729 Put newline at end of gqlgen init output - -- 072363c7 add ParentObject field to ResolverContext - -
e15d7890 Merge pull request #300 from 99designs/fix-starwars-connection-example - -fix connection example - -
- -- d6acec16 fix connection example - -- 7d1cdaca Nulls in required fields should cause errors and bubble - -
2c4e6cbf Merge pull request #294 from 99designs/simplfy-concurrent-resolvers - -Simplfy concurrent resolver logic - -
- -- 7926c688 Simplfy concurrent resolver logic - - - - - - -## [v0.4.4](https://github.com/99designs/gqlgen/compare/0.4.3...v0.4.4) - 2018-08-21 -- 6f6622c6 Bump gqlparser to latest version - -
72659af4 Merge pull request #297 from 99designs/fix-dep-pruning - -Explicitly import ambient imports so dep doesn't prune them - -
- -- cac3c729 Explicitly import ambient imports so dep doesn't prune them - -
e6af26e0 Merge pull request #296 from heww/master - -sort directives by name when gen - -
- -- fd09cd99 sort directives by name when gen - -
71917267 Merge pull request #292 from m4ppi/fix-doc - -Fix broken links in docs - -
- -- 05c73d9f Fix broken links in docs - -
5a0b56aa Merge pull request #285 from 99designs/fix-force-type - -Stop force resolver from picking up types from matching fields - -
- -- 31478cf4 Stop force resolver from picking up types from matching fields - -
ebdcf740 Merge pull request #283 from 99designs/speed-up-tests - -Speed up tests - -
- -- 36e84073 Speed up tests - - - - - - -## [0.4.3](https://github.com/99designs/gqlgen/compare/0.4.2...0.4.3) - 2018-08-10 -
3575c289 Merge pull request #281 from 99designs/introspection-default-args - -Fix missing default args on types - -
- -- b808253f Fix missing default args on types - -
bf235296 Merge pull request #282 from 99designs/flakey-tests - -Remove sleeps in tests - -
- -- e9c68f08 make appveyor less flakey - - - - - - -## [0.4.2](https://github.com/99designs/gqlgen/compare/0.4.1...0.4.2) - 2018-08-10 -- 06b00d45 Update README.md - -
5c379a33 Merge pull request #279 from 99designs/integration-tests - -Integration tests - -
- -- 7f20bdef disable tty for jest - -- bb0a89a0 exclude generated code from tests - -- c2bcff79 regenerate - -- 45e22cb1 Add introspection schema check - -
53109cd0 Merge pull request #270 from 99designs/feat-handlers - -stop pickup "github.com/vektah/gqlgen/handler" from GOPATH - -
- -- ae82b94a convert existing tests to jest - -- f04820b1 address comment - -- 88730e2c Convert test directory into integration test server - -- f372b1c9 Use docker in docker for the existing testsuite - -
0eb08ab9 Merge pull request #274 from 99designs/fix-variable-validation-data - -Prevent executing queries on variable validation failures - -
- -- 47a7ac35 Prevent executing queries on variable validation failures - -- e6e323d0 stop pickup "github.com/vektah/gqlgen/handler" from GOPATH - -- e6005f6b fix mobile nav - -
5cdbc975 Merge pull request #267 from 99designs/authentication-docs - -Authentication docs - -
- -- 1871c4ce Add bold variant of Roboto to docs - -- fc9fba09 Some minor edits to authentication docs - -- d151ec8d Add docs on user authentication - -- 8db3c143 Add structure to menu - -
c57619e0 Merge pull request #260 from 99designs/init-improvements - -Init Config Improvement - -
- -
336b62ec Merge pull request #266 from 99designs/lint-friendly-decollision - -Make keyword decollision more lint friendly - -
- -- 2acbc245 Make keyword decollision more lint friendly - -
f12f08a7 Merge pull request #264 from 99designs/docs - -CORS docs - -
- -- a2a7c0e7 Eliminate font resize popin - -- 8a7ed618 Fix errors docs - -- 96e6aab2 Add CORS docs - -
0ab1c685 Merge pull request #263 from 99designs/add-logo - -Add logo to doc site - -
- -- 6d39f868 Add logo to doc site - -- d7241728 Better error on init if file exists - -- fb03bad9 Run init even if config is found - -- 52b78793 Fix hard-coded server filename in init - - - - - - -## [0.4.1](https://github.com/99designs/gqlgen/compare/0.4.0...0.4.1) - 2018-08-04 -
42f10ec9 Merge pull request #255 from 99designs/introspection-fixes - -Fix introspection api - -
- -- 7400221c Fix introspection api - -
b35804ba Merge pull request #254 from oskanberg/patch-1 - -Fix typo in introduction docs - -
- -- 84552437 Fix typo in introduction docs - -- b5a48e3e Update README.md - -- c20bb134 update badges - - - - - - -## [0.4.0](https://github.com/99designs/gqlgen/compare/0.3.0...0.4.0) - 2018-08-03 -
7b5a3d74 Merge pull request #247 from 99designs/next - -0.4.0 Release - -
- -
c0be9c99 Merge pull request #251 from 99designs/rewrite-imports - -Rewrite import paths - -
- -- 4361401a Rewrite import paths - -
f042328a Merge pull request #252 from 99designs/move-doc-site - -Move doc site - -
- -- 658a24d9 Move doc site - -
07b7e6ca Merge pull request #248 from 99designs/json-usenumber - -use json.Decoder.UseNumber() when unmarshalling vars - -
- -- 95fe07fe use json.Decoder.UseNumber() when unmarshalling vars - -
c555f54c Merge pull request #245 from vektah/new-feature-docs - -New feature docs - -
- -
825840aa Merge pull request #244 from vektah/array-coercion - -Add implicit value to array coercion - -
- -
90b40769 Merge pull request #246 from vektah/fix-introspection - -Fix introspection - -
- -- ef208c76 add docs for resolver generation - -- e44d798d Add directives docs - -- 62d4c8aa Ignore __ fields in instrospection - -- bc204c64 Update getting started guide - -- b38c580a Return the correct mutation & subscription type - -- 9397920c Add field name config docs - -- d2265f3d Add implicit value to array coercion - -
191c8ba0 Merge pull request #239 from vektah/directive-args - -Directive args - -
- -- 3bef596d regenerate - -- 4f37d170 Add directive args - -
f78a6046 Merge pull request #241 from vektah/feat-lintfree - -Make more golint free generated code - -
- -- 19b58175 Merge remote-tracking branch 'origin/master' into HEAD - -- c3fa1a55 Merge branch 'next' into feat-lintfree - -
17bfa2cb Merge pull request #240 from vektah/doc-fonts - -Use fonts from golang styleguide - -
- -- 64ef0571 Use fonts from golang styleguide - -
6b532383 Merge pull request #237 from vektah/feat-fieldmapping - -Add model field mapping - -
- -- 4fb721ae address comment - -- bf43ab3d Merge branch 'next' into feat-fieldmapping - -- 353319ca Refactor GoVarName and GoMethodName to GoFieldName etc... - -- d7e24664 Add method support - -
17bcb322 Merge pull request #236 from vektah/generate-handler-on-init - -Generate server on running init - -
- -
600f4675 Merge pull request #238 from vektah/variable-validation - -Add missing variable validation - -
- -- d6a76254 Add missing variable validation - -- 121e8db4 Generate server on running init - -- 108bb6b4 Rename govarname to modelField - -- f7f6f916 Make more lint friendly - -- 69eab938 Add model field mapping - -
ffee020c Merge pull request #235 from vektah/generate-resolver-on-init - -Generate resolver on init - -
- -- df95f003 Generate code after init - -- 58831ac1 Generate resolver if configured - -
7031264d Merge pull request #229 from vektah/fix-init-command - -Fixing init command - -
- -
078bc985 Fixing init command - -The init command always return file already exists if there are no -configFilename specified - -This is caused by codegen.LoadDefaultConfig() hiding the loading details -and always return the default config with no error while the init -command code expects it to tell us if config exists in default -locations. - -To avoid confusion I have splitted the loading config from default -locations out into its own method so we can handle different cases -better. - -Additionally I also moved default config into a method so we always -generating new a config instead of passing it around and potentially -mutating the default config. - -
- -
803711e9 Merge pull request #221 from vektah/middleware-stack - -Implement FieldMiddleware Stack - -
- -- 0ec918bf Switch GoName to Name|ucFirst - -- 5dc104eb Add middleware example for Todo - -- 73a8e3a3 Fix some issues with directive middlewares - -- 84163247 Regenerate - -
0e16f1fc Generate FieldMiddleware - -Moves it off of RequestContext and into generated land. This change -has a basic implementation of how directive middlewares might work. - -
- -- 2748a19b Require Config object into NewExecutableSchema - -- 09242061 Add Directives to Build - -
69e790c2 Add *Field to CollectedField - -We need the Field Definition so that we can run directive middlewares -for this field. - -
- -- d6813f6d Generarte - -
764c6fda Refactor ResolverMiddleware to FieldMiddleware - -This will allow us to include DirectiveMiddleware in the same middleware -setup, that will run after Resolver middlewares. - -
- -
7226e573 Merge pull request #225 from rongfengliang/patch-1 - -Update getting-started.md - -
- -- 66593ffe Merge remote-tracking branch 'origin/master' into HEAD - -- 8714f7fb hush metalinter - -
0dfb92a7 Update getting-started.md - -CreateTodo UserID input should be UserId not User - -
- -
0fa7977f Merge pull request #217 from vektah/resolver-middleware-all - -Run Resolver Middleware For All Fields - -
- -
7292be78 Rename CastType to AliasedType - -This field stores a Ref if a type is a builtin that has been aliased. In -most cases if this is set, we want to use this as the type signature -instead of the named type resolved from the schema. - -
- -- ec928cad Regenerate examples - -
97f13184 Remove comment about ResolverMiddleware - -Not true anymore! - -
- -- b512176c Run resolver middleware for all fields - -
f67f8390 Merge pull request #218 from vektah/remove-old-resolvers - -Remove old resolvers - -
- -
1a3e4e99 Merge pull request #220 from vektah/feat-race - -turn back -race option - -
- -- 40989b19 turn back -race option - -
1ba61fcb Update test & examples to use new resolver pattern - -* chat -* dataloader -* scalar -* selection -* starwars -* todo - -
- -
38708961 Stop generating two types of resolvers - -In recent refactor we introduced a new pattern of resolvers which is -better structured and more readable. To keep Gqlgen backward compatible -we started generate two styles of resolvers side by side. - -It is now time to sunset the old resolver. This commit removes the old -resolver and update the generation code to use the new resolver -directly. - -
- -- ffe42658 Merge pull request #208 from vektah/directives-skip-include - -
a69071e3 Pass context to CollectFields instead of RequestContext - -Internally it can still get to RequestContext as required. - -
- -- d02d17ae Add method for generating method name from field - -- c7ff3208 Update gqlparser version to include default resolution - -- ce17cd90 Add default value test case - -
cbfae3d3 Add skip/include test cases - -Adds a set of test cases for skip and include directives to the todo -example. Also now conforms to spec if both are included. - -
- -
ea0f821c Add skip/include directive implementation - -This is a snowflake implementation for skip/include directives based on -the graphql-js implementation. Skip takes precedence here. - -
- -- ebfde103 Pass request context through to CollectFields - -
bab7abb2 Merge pull request #210 from vektah/feat-init - -introduce gen & init subcommand - -
- -
6ba508f9 Merge pull request #214 from vektah/gqlparser-schema-validation - -Bump gqlparser to get schema validation - -
- -- 138b4cea Bump gqlparser to get schema validation - -- 08d7f7d0 Merge branch 'next' into feat-init - -- 39f9dbf6 fix error from breaking change - -- 41147f6f update Gopkg.lock - -- 87d8fbea remove unused flag - -- eff49d04 support init subcommand - -- c5810170 introduce cobra library - -- c3c20f8f Merge remote-tracking branch 'origin/master' into HEAD - -
90df37f6 Merge pull request #205 from vektah/forward-credential-to-graphql-endpoint - -Use original credential for query request in playground - -
- -
52343745 Merge pull request #206 from vektah/validation-locations - -Update gqlparser for validation locations - -
- -- f4d31aa4 Update gqlparser for validation locations - -
9d473f8b Merge pull request #203 from vektah/99designs-announcement - -Announcement: 99designs is now sponsoring gqlgen - -
- -
c2f1570d Merge pull request #204 from vektah/gqlparser-prelude - -Use shared prelude - -
- -- 004ec6a9 Add 99designs sponsorship news - -- 548aed14 Use shared prelude - -
edb3ea4e Use original credential for query request in playg - -Currently the playground doesn't forward any credentials when making -query calls. This can cause problems if your playground requires -credential logins. - -
- -
f855a89c Merge pull request #201 from cocorambo/remove-trailing-println - -Remove trailing Println - -
- -- c41a6c36 Remove trailing Println - -
2692d3e0 Merge pull request #197 from vektah/new-parser - -Integrate gqlparser - -
- -- 5796d47d Integrate gqlparser - -- 55179a61 Update badges - -
01a4c677 Merge pull request #195 from jonstaryuk/master - -Update playground version - -
- -- c52f24af Update playground version to 1.6.2 - - - - - - -## [0.3.0](https://github.com/99designs/gqlgen/compare/0.2.5...0.3.0) - 2018-07-14 -
381b3469 Merge pull request #194 from vektah/multiline-comments - -Fix multiline comments - -
- -- 112d68a6 only build master branch - -- 4b3778e3 Fix multiline comments - -
eb44925c Merge pull request #193 from vektah/validate-method-returns - -validate method return types - -
- -- 164acaed validate method return types - -
f478f816 Merge pull request #192 from vektah/strict-config - -Strict config - -
- -- a1c02e7b Strict config - -
533dcba7 Merge pull request #191 from vektah/nullable-list-elements - -Support nullable list elements - -
- -- e0bf6afd Support nullable list elements - -
0780bf2e Merge pull request #190 from vektah/generated-forced-resolvers - -Allow forcing resolvers on generated types - -
- -- bf1823cd Allow forcing resolvers on generated types - -
febd0358 Merge pull request #186 from vektah/error-redux - -Error redux - -
- -- b884239a clarify error response ordering - -- 58e32bbf Drop custom graphql error methods - -- d390f9c6 Errors redux - - - - - - -## [0.2.5](https://github.com/99designs/gqlgen/compare/0.2.4...0.2.5) - 2018-07-13 -
0a9709db Merge pull request #188 from vektah/fix-windows-gopath - -Fix windows gopath issue - -
- -- ea4f26c6 more fixes - -- 1066953d Appveyor config - -- f08d8b61 Fix windows gopath issue - -- 9ade6b7a Update gettingstarted to use new resolvers - - - - - - -## [0.2.4](https://github.com/99designs/gqlgen/compare/0.2.3...0.2.4) - 2018-07-10 -
ac9e5a66 Merge pull request #180 from vektah/import-alias-before-finalize - -Fix a bug custom scalar marshallers in external packages - -
- -- 160ebab5 Fix a bug custom scalar marshallers in external packages - -
43212c04 Merge pull request #179 from vektah/models-config-error - -Improve Output Filename and Package Handling - -
- -- 936bc76e Better handling of generated package name - -- 5d3c8ed2 Inline ImportPath strings - -- fc43a92a Check that exec and model filenames end in *.go - -- 6d38f77d Handle package name mismatch with dirname - -- ebf1b2a5 Add error message when specifying path in package name - -- c8355f48 Check models config for package-only specs - - - - - - -## [0.2.3](https://github.com/99designs/gqlgen/compare/0.2.2...0.2.3) - 2018-07-08 -- 6391596d Add some basic docs on the new config file - -
a9c3af86 Merge pull request #176 from vektah/config-search-paths - -Search for config - -
- -- 25cfbf08 Search for config - -
bff3356b Merge pull request #175 from vektah/lint-all-packages - -gometalinter should cover all packages - -
- -- 61f37173 gometalinter should cover all packages - -
ce657044 Merge pull request #173 from vvakame/feat-resolver-hint - -add resolver option support to field - -
- -
57b8279e Merge pull request #172 from vvakame/feat-newconfig - -switch to .gqlgen.yml - -
- -- fcfceefb add resolver option support to field - -- c7ce1cbb update docs - -- 42948153 move to .gqlgen.yml - -
325c45a4 Merge pull request #171 from vvakame/add-gitignore - -add .idea/ to .gitignore - -
- -- aa4cec9b add .idea/ to .gitignore - - - - - - -## [0.2.2](https://github.com/99designs/gqlgen/compare/0.2.1...0.2.2) - 2018-07-05 -- f79b6a52 cleanup new config - -
f0a08617 Merge pull request #163 from vvakame/feat-types-json - -support .gqlgen.yml - -
- -
faf095fc Merge pull request #166 from vektah/validate-at-end - -Validate at end - -
- -- fca1e08e shh errcheck - -- cc78971e Dont show compilation errors until after codegen - -- 9f6ff0cf Convert todo example to new resolver syntax - -- 8577ceab address comment - -- 86dcce73 Add format check to -typemap argument - -- 5debbc6a Implement types.yaml parsing - -- ecf56003 Refactor types.json parsing - -
b16e8429 Merge pull request #159 from vektah/enum-only-generation - -Dont skip model generation if there are enums defined - -
- -- 3f751a40 Dont skip model generation if there are enums defined - -- 588aeacb more tutorial fixes - -
dc472965 Merge pull request #157 from johncurley/fix-docs-argument - -Updated mutation to take correct argument - -
- -- 88a84f83 Updated mutation to take correct argument - -
404f0b0d Merge pull request #151 from qdentity/fix-longer-gopath - -Fix bug with multiple GOPATH full package name resolving - -
- -
f66e2b3b Fix bug with multiple GOPATH full package name resolving - -This commit fixes the bug where GOPATH values that are longer than the input package name cause 'slice bounds out of range' errors. - -
- - - - - - -## [0.2.1](https://github.com/99designs/gqlgen/compare/0.2.0...0.2.1) - 2018-06-26 -
cb87a2cb Merge pull request #147 from vektah/import-overhaul - -Improve import handling - -
- -
9fa3f0fb Merge pull request #134 from mastercactapus/small-interfaces - -add lint-friendly small interfaces option for resolvers - -
- -
e8c30acd fix template error on generated defaults (#146) - -* fix template error on generated defaults - -* go fmt - -* add test for default fix - -* . - -* add key sort for default values - -
- -- 769a97e2 fix race in chat example test - t.Parallel() doesn't guarantee parallel execution - moved goroutine so the test can execute independently - -- 5b77e4c2 remove deprecation warning for now - -- 59a5d752 remove trailing S - -- b04846f6 fix time race in scalar test - -- a80b720f name updates, deprecation, some code comments - -- 2bbbe054 Merge branch 'master' into small-interfaces - -- 4ffa2b24 case insensitive compare to determine self package - -- c0158f54 make sure colliding imports are stable - -- abf85a10 get package name from package source - -- a39c63a5 remove a random json tag from tutorial - -- f48cbf03 tutorial fixes - -
0a85d4f2 Update generated headers to match convention. (#139) - -* Update generated.gotpl - -* Update models.gotpl - -* Update data.go - -* update go generate - -* revert code changes - -
- -- 4a6827bd Update getting started guide - -- a21f3273 Use recognized `Code generated` header - -- 038c6fd2 change from `ShortResolver` to `ShortResolvers` - prevents possible collision with an object type named `Short` - -- 0bc592cd run go generate - -- db2cec07 fix template formatting - -- 59ee1b5c from probably makes more sense - -- 620f7fb4 add "short" resolver interface - - - - - - -## [0.2.0](https://github.com/99designs/gqlgen/releases/tag/0.2.0) - 2018-06-21 -
d26ef2a2 Merge pull request #136 from tianhai82/master - -fix GOPATH case mismatch issue - -
- -
a34b4de4 Merge pull request #137 from appleboy/patch-1 - -fix example links - -
- -
c1cde36c Merge pull request #133 from mastercactapus/skip-type-mismatch - -skip struct fields with incompatible types - -
- -- c1b4574c fix example links - -- 63976d5f fix GOPATH case mismatch issue - -- 8771065f skip fields with incompatible types - -
40d9a11b Merge pull request #127 from jon-walton/windows-path-slash - -convert windows input path separators to slash - -
- -- 7db9d122 convert windows input path separators to slash - -
a5f72601 Merge pull request #122 from vektah/json-encoding-fixes - -Fix json string encoding - -
- -- f207c62c review feedback - -- 578d8415 Fix json string encoding - -
e9b40666 Merge pull request #123 from vektah/drop-fk-generation - -BC Break: Stop generating foreign keys in models - -
- -
a8419e20 Merge pull request #124 from vektah/fix-backtick-escaping - -Fix backtick escaping - -
- -- 47eaff4d Fix backtick escaping - -- a5c02e6c BC Break: Stop generating foreign keys in models - -
94d5c89e Merge pull request #120 from andrewmunro/bugfix/fix-panic-on-invalid-array-type - -Fixing panic when non array value is passed to array type - -
- -- 5680ee49 Adding dataloader test to confirm no panic on malformed array query - -- 55cc161f Fixing panic when non array value is passed to array type - -- 6b3b338d Add gitter link to readme - -- 6c823beb add doc publish script - -
a25232d8 Merge pull request #113 from mikeifomin/patch-1 - -Fix typo in url dataloaden - -
- -- 3a129c77 Fix typo in url dataloaden - -- e1fd79fe Merge pull request #111 from imiskolee/master (closes #110) - -- e38cb497 1. fix bug: #110 - -
3990eacf Merge pull request #108 from imiskolee/master - -generate json tag to model field by gql name. - -
- -- abb7502a 1. run go generate - -- e1f90946 1. add json tag in models_gen.go 2. use gqlname to model filed json tag. - -
35e09717 Merge pull request #107 from vektah/fix-vendor-normalization - -Fix vendor normalization - -
- -
63ee4199 Fix vendor normalization - -When refering to vendored types in fields a type assertion would fail. This -PR makes sure that both paths are normalized to not include the vendor -directory. - -
- -
2a437c23 Merge pull request #105 from vektah/keyword-input-args - -Automatically add a _ suffix to reserved words - -
- -
26ac13ff Merge pull request #104 from vektah/new-request-context - -Add a NewRequestContext method - -
- -- 309e5c6d Automatically add a _ suffix to reserved words - -- a2fb1421 Add a NewRequestContext method - -
ab6e65bd Merge pull request #97 from vektah/add-input-defaults - -Default values for input unmarshalers - -
- -- 1cd80c4a Default values for input unmarshalers - -
79c69d15 Merge pull request #96 from vektah/refactor-tests - -Refactor tests - -
- -- 7b1c8198 Refactor tests - -
0c7bdfc6 Merge pull request #95 from vektah/custom-error-types - -Custom error types - -
- -- 4bdc1e1f regenerate - -- 20250f18 Add fully customizable resolver errors - -- a0f66c88 Update README.md - -- 8f62d505 Update README.md - -- a1043da6 Add feature comparison table to readme - -
22128e0e Merge pull request #93 from vektah/input-type-error-handling - -Input type error handling - -
- -- e7539f11 Add an error message when using types inside inputs - -- a780ce69 Add a better error message when passing a type into an input - -- 0424f043 Refactor main so tests can execute the generator - -
ab3803a6 Merge pull request #89 from vektah/opentracing-parent-span - -Add parent opentracing span around root query/mutation/resolvers - -
- -
d157ac35 Add context to recover func - -This makes the request and resolver contexts available during panic -so that you can log the incoming query, user info etc with your bug -tracker - -
- -- 3ceaa189 add request middleware - -- 877f75a0 remove debugging trace (closes #81) - -
091d25ab Merge pull request #87 from jon-walton/windows-paths - -fix package paths on windows - -
- -- 53a6e814 fix package paths on windows - -
546b7b76 Merge pull request #84 from yamitzky/master - -Fix collectFields to handle aliased fields properly - -
- -- ba2ecb16 Add test case for aliased field - -- 78f3a56c Fix collectFields to handle aliased fields - -
4d2eece0 Merge pull request #77 from vektah/opentracing - -Add resolver middleware Add opentracing support - -
- -- f0def668 better opentracing tags - -- 600bff7a bump metalinter deadline - -- 2e32c121 regenerate code - -- 5b908507 opentracing middleware - -- 57adb244 Add resolver middleware - -- 28d0c81f capture args in map - -
e266fab9 Merge pull request #75 from mathewbyrne/fix-import-dash - -Replace Invalid Characters in Package Name with an Underscore - -
- -
b0d79115 Replace invalid package characters with an underscore - -This will sanatise local import names to a valid go identifier by -replacing any non-word characters with an underscore. - -
- -
66a91503 Merge pull request #72 from vektah/custom-enum - -Add support for custom enums - -
- -- 61a34a74 Add support for custom enums - -- 74ac827a move docs to new domain - -
ebcc94d1 Merge pull request #70 from vektah/models-in-separate-package - -Allow generated models to go into their own package - -
- -- 9a532131 Allow generated models to go into their own package - -
6129fd26 Merge pull request #69 from vektah/support-options - -Support OPTIONS requests - -
- -- af38cf05 Support OPTIONS requests - -
893ead12 Merge pull request #67 from vektah/raw-schema-string - -Use a raw string for schema - -
- -- af6178a7 Use a raw string for schema - -
c0753bed Merge pull request #66 from vektah/generate-enums - -Generate enums - -
- -- 85a51268 Generate enums - -
71c4e265 Merge pull request #65 from vektah/context - -Make field selections available in context - -
- -- c60336bf regenerate - -- c5ccfe4e Add an example for getting the selection sets from ctx - -- e7007746 add fields to resolver context - -- 40918d52 move request scoped data into context - -
4e13262e Merge pull request #64 from vektah/vendor-gen-path - -Fix vendored import paths in generated models - -
- -- 2ff9f32f Fix vendored import paths - -- 630a3cfc failing test - -- 99dec54c fix missing deps - -- 652c567e Remove missing field warning and add test for scalar resolvers (closes #63) - -- 3dc87e1b gtm - -- c76c3434 Add dataloader tutorial - -- 449fe8f8 Optimize frontmatter - -- b90ae60e flatten menus - -
a508ecb0 Merge pull request #45 from dvic/fix-resolver-public-errors - -Retain orignal resolver error and support overriding error message - -
- -- ab4e7010 Retain orignal resolver error and support overriding error message (closes #38) - -
a05a18d5 Merge pull request #61 from vektah/import-resolver-collisions - -Deal with import collisions better - -
- -- d81ea2c2 Deal with import collisions better - -
fb131a94 Merge pull request #59 from vektah/map-support - -Add map[string]interface{} escape hatch - -
- -- 49d92164 Add map[string]interface{} escape hatch - -
5abdba16 Merge pull request #57 from vektah/null-input-fields - -Null input fields - -
- -- f8add9d2 remove more unneeded whitespace - -- 84b06617 Allow nulls in input fields - -
54fbe16a Merge pull request #56 from vektah/getting-started-fixes - -Getting started fixes - -
- -- 17fd17a4 Update the tutorial - -- e65d2a5a detect correct FK type - -- b66cfa03 small fixes to entry point - -- 0b62315a Create ISSUE_TEMPLATE.md - -
f3a70dac Merge pull request #55 from vektah/fix-input-ptr-unpacking - -Fix ptr unpacking in input fields - -
- -- 10541f19 Fix ptr unpacking in input fields - -
15b3af2d Fix value receivers for unions too - -fixes 42 - -
- -
46103bdc Merge pull request #53 from vektah/docs - -Docs - -
- -- d0211a0a Custom scalar docs - -- e6ed4de5 Update readme link - -- 51f08a9e start of docs - -
ac832dea Merge pull request #51 from vektah/support-embedding - -Support embedding in models - -
- -- 9d710712 add embedding support - -- 0980df0e Embedding example - -
cb34e6db Merge pull request #50 from vektah/valuer-receiver - -Don't generate value receivers for types that cant fit the interface - -
- -- ec5f5e66 check for valuer receivers before generating type switch - -- dc898409 add test case - -
8ef253cb Merge pull request #49 from vektah/default-entrypoints - -default to Query / Mutation / Subscription if no entry points are specified - -
- -- 302058a7 Use default entry points for Query/Mutation/Subscription - -
13949fdf Merge pull request #37 from vektah/generate-interfaces - -generate interfaces - -
- -- acc45bf0 generate interfaces - -
e47d5038 Merge pull request #34 from vektah/root-types-only - -Only bind to types in the root package scope - -
- -- ffe972a8 Only bind to types in the root package scope - -
0e78c0ae Merge pull request #33 from vektah/unset-arguments - -Allow unset arguments - -
- -- bc9e0e54 Allow unset arguments - -
94718351 Merge pull request #31 from vektah/recover-handler - -Customizable recover func - -
- -- e4e249ea Customizable recover func - -
69277045 Merge pull request #30 from vektah/complex-input-types - -Fix complex input types - -
- -- 9b64dd22 Fix complex input types - -
1d074b89 Merge pull request #29 from vektah/multi-stage-model-build - -Split model generation into its own stage - -
- -- cf580c24 Split model generation into its own stage - -
926384db Merge pull request #28 from vektah/default-args - -add default args - -
- -- 68c54a14 add default args - -- d63128f6 appease the linting gods - -
7b6b124e Merge pull request #20 from vektah/codegen-cleanup - -Codegen cleanup - -
- -- 78c34cb3 regenerate - -- 5ebd157c Only use one gofunc per subscription - -- 79a70376 Move generated field resolvers into separate methods - -
e676abe4 Merge pull request #19 from vektah/generate-input-types - -Generate input models too - -
- -- f094e79c Generate input models too - -- 1634f088 Add a missed error check - -
4feb1689 Merge pull request #18 from vektah/array-input-args - -Fix input array processing - -
- -- 98176297 Fix input array processing - -
4880497f Merge pull request #16 from vektah/better-templates - -Better templates - -
- -- 278df9de Better templates - -
f3731c73 Merge pull request #14 from vektah/autogenerate-models - -Autogenerate models - -
- -- cfe902a0 Autogenerate models - -- 287bf7f4 more docs - -
9d896f40 Merge pull request #13 from vektah/autocast - -Automatically add type conversions around wrapped types - -
- -- 85fa63b9 Automatically add type conversions around wrapped types - -
c8c2e40f Merge pull request #11 from vektah/subscriptions - -Add support for subscriptions - -
- -- d514b829 Add some go tests to the chat app - -- ec2916d9 chat example for subscriptions using CRA+apollo - -- 8f93bf8d get arg errors working in both contexts - -- 62a18ff1 Update generator to build a new ExecutableSchema interface - -- c082c3a4 prevent concurrent writes in subscriptions - -- f555aec6 switch to graphql playground for better subscription support - -- 18219541 add websocket support to the handler - -- d4c7f3b9 update resolver definition to use channels for subscriptions - -
d0244d24 Merge pull request #10 from vektah/newtypes - -User defined custom types - -
- -- 5d86eeb6 fix jsonw test - -- 944ee088 regenerate - -- 4722a855 add scalar example - -- 83b001ae rename marshaler methods - -- e0b7c25f move collectFields out of generated code - -- 146c6538 generate input object unpackers - -- d94cfb1f allow primitive scalars to be redefined - -- 402e0730 rename jsonw to graphql - -- 3e7d80df Update README.md - -- 9c77e7a0 Update dataloaden dep - -- 530f7895 Make gql client work with older versions of mapstructure - -- 5c04d1ad __typename support - -
51292db9 Merge pull request [#4](https://github.com/99designs/gqlgen/issues/4) from vektah/cleanup-type-binding - -Cleanup schema binding code - -
- -- c89a8774 Cleanup schema binding code - -
030954a5 Merge pull request [#2](https://github.com/99designs/gqlgen/issues/2) from ulrikstrid/patch-1 - -Fix typo in README - -
- -- cb507bd0 Fix typo in README - -- e3167785 Fix template loading from inside vendor - -- 261b52ce fix an error handling bug - -- 1da57f59 Split starwars models out from resolvers - -- 743b2cf9 fix indenting - -- fb2d5817 use gorunpkg to vendor go generate binaries - -- 7f4d0405 encourage dep use - -- 3276c782 Do not bind to unexported vars or methods - -- 5fabffaf heading tweaks - -- e032c1d5 Prior art - -- 45b79a1e Add a test for multidimensional arrays - -- ec73a50a fix race - -- 75a3a05c Dont execute mutations concurrently - -- 3900a41d tidy up json writing - -- 0dcf7f6b add circle ci badge - -- 2c9bf21c get dataloaden - -- 4fff3241 install dataloaden in ci - -- 951f41b2 circle ci - -- 8fa5f628 less whitespace - -- c76f3b98 clean up template layout - -- 4a6cea5e readme fixes - -- b814ad52 rename repo - -- 9c79a37a Cleanup and add tests - -- 5afb5caa update dataloaden - -- d00fae08 Add dataloader example - -- 86cdf3a0 Fix package resolution - -- 41306cba Better readme - -- ce5e38ed Add GET query param support to handler - -- dd9a8e4d parallel execution - -- 4468127e pointer juggling - -- 9e99c149 Use go templates to generate code - -- 41f74970 Support go versions earlier than 1.9 - -- c20ef3d0 add missing nulls - -- bb753776 Use goimports instead of gofmt on generated code - -- c2cf3835 coerce types between similar types - -- 5297dd40 Add support for RFC3339 formatted Time as time.Time - -- 61291ce9 support vendor - -- 6d437d7e allow map[string]interface{} arg types - -- 39a8090a cleanup - -- a9352e32 gometalinter pass - -- 9ab81d67 Finish fleshing out the connection example - -- e04b1e50 inline supporting runtime funcs - -- 9cedf012 complex arg handling - -- 0c9c009f Clean up json writer - -- e7e18c40 much cleaner generated code - -- 6a76bbf6 Interfaces and starwars example - -- 29110e76 Generate ESS to remove it interface{} casts completly - -- 2f358e7d graphiql autocomplete working - -- 2e2c3135 create separate type objects in prep for fragment support - -- 22c0ad0a Add basic introspection support - -- c1c2cb64 Code generation - -- 4be5ac84 args - -- bde800e1 imports - -- 596554da start of code generator - -- 62fa8184 split generated vs exec code - -- 0ea104cd remove internal package - -- f81371e8 Args - -- 01896b3b Hand written codegen example - -- 5a756bda Rewrite paths and add readme - -
b4663703 trace: Log graphql.variables rather than tag - -According to the OT documentation tag values can be numeric types, strings, or -bools. The behavior of other tag value types is undefined at the OpenTracing -level. For example `github.com/lightstep/lightstep-tracer-go` generates error -events. - -
- -- 5d3b13f2 Support context injection in testing - -
beff0841 Separate literal arg parsing cases (int, float) - -This change allows the ID scalar implementation to more semantically -handle the case for unmarshalling integer IDs. - -
- -
ab1dd4b5 Add tests for ID scalar input - -This commit adds two tests cases for ID scalar input: -- a string literal -- an integer literal - -Both of these literal types are covered by the GraphQL specification as -valid input for the ID scalar. - -Reference the ID section of the spec for more information: -http://facebook.github.io/graphql/October2016/#sec-ID - -
- -
d8c57437 Extract ID scalar implmentation - -This change moves the ID scalar implementation out of `graphql.go` and -into its own file `id.go` for consistency with the Time scalar -implementation. - -
- -- 10eb949b cleaned up example to use MustParseSchema - -
52080e1f Rename friendsConenctionArgs to friendsConnectionArgs - -Fix spelling error in friendsConnectionArgs type - -
- -- 3965041f Update GraphiQL interface (add history) - -
6b9bc3e2 Add `(*Schema).Validate` (#99) - -* Add `(*Schema).Validate` - -This adds a `Validate` method to the schema, which allows you to find out if a query is valid without actually running it. This is valuable when you have a client with static queries and want to statically determine whether they are valid. - -* Fix Validate doc string - -
- -- 7f3f7120 Set content-type header to `application/json` - -- c76ff4d8 moved packer into separate package - -- 073edccd updated tests from graphql-js - -- 3a9ac368 validation: improved overlap check - -- f86c8b01 allow multiple schemas in tests - -- 77750960 validation: OverlappingFieldsCanBeMerged - -- e7ca4fde refactor: remove SelectionSet type - -- 7aad6ba7 refactor: use schema.NamedType - -- fddcbcb7 resolves #92: fix processing of negative scalars during parse literals - -- 48c1a0fb Small fix based on feedback. - -- e90d1089 allow custom types as input arguments - -- dd3d39e2 fix panic when variable name not declared - -- c2bc105f validation: NoUnusedVariables - -- 4aff2976 refactor - -- 0933d241 validation: VariablesInAllowedPosition - -- 83e2f31a validation: NoUndefinedVariables - -- c39ffeca validation: PossibleFragmentSpreads - -- 47c5cde7 validation: UniqueInputFieldNames - -- 94cb2918 big refactoring around literals - -- 3d63ae80 some refactoring - -- 969dab9d merged lexer into package "common" - -- a9de6171 renamed lexer.Literal to lexer.BasicLit - -- 88c492bb validation: NoFragmentCycles (closes #38) - -- d39712c8 refactor addErrMultiLoc - -- ee5e1c3b validation: updated tests - -- 490ad6b2 validation: NoUnusedFragments - -- da85f09d add path to errors on resolver error or panic (closes #86) - -- 04cb2550 allow structs without pointers (closes #78) - -- 4c40b305 show all locations in error string - -- 5c26f320 fix limiter - -- dbc3f0a0 fix composing of fragments (closes #75) - -
213a5d01 Warn if an interface's resolver has a ToTYPE implementation that does not return two values. - -Currently this instead crashes fairly inscrutably at runtime here: https://github.com/neelance/graphql-go/blob/master/internal/exec/exec.go#L117 - -An alternate fix would be to check len(out) there and perhaps rely on out[0] being nil to continue if there's only one return value. - -
- -- 00c4c574 Fix panic when resolver is not a pointer - -- d0df6d8a small cleanup - -- 036945e2 fix hang on panic (fixes #82) - -- 01ab5128 Add supports for snake case (#77) - -
67e6f91d use encoding/json to encode scalars - -There are some edge cases that are better handled by the proven encoder of encoding/json, for example special characters in strings. - -
- -- 3f1cb6f8 implement user defined logger (with sensible defaults) - -- b357f464 built-in json encoding - -- 2d828770 refactor: collect fields to resolve - -- 32f8b6ba refactor: replaced MetaField - -- b95c566e simplify schema introspection - -- 4200a584 split internal/exec into multiple packages - -- c11687a7 refactored internal/exec - -- bd742d84 WIP - -- d09dd543 added SchemaOpt - -- 1dcc5753 fix Schema.ToJSON - -- 4f07e397 pass variable types to tracer - -- 36e6c97e readme: remove outdated section about opentracing - -- 0b143cca refactor: apply before exec - -
a9920602 pluggable tracer - -Improved performance while keeping flexibility. - -
- -- 58d3d5b8 refactored exec.Request - -- 9dd714ec refactored execField some more - -- a43ef241 refactor: meta fields - -- 48931d17 refactor fieldExec - -- ee95710d small cleanup - -- 84baade5 perf: create span label only once - -- a16ed600 improved concurrency architecture - -
aef3d9cf Add testing.go into its own package (gqltesting) - -This is done so that "testing" (and especially its registered cli flags) -aren't included in any production builds. - -
- -- f78108a3 validation: meta fields - -- c6ab2374 added empty file to make CI happy - -- d59c1709 fix introspection of default value - -- 42608a03 clean up now unnecessary check - -- e45f26dd validation: UniqueDirectivesPerLocation - -- dcf7e59f validation: UniqueFragmentNames - -- eeaa510b validation: UniqueOperationNames - -- a5a11604 refactor: Loc on Field - -- b5919db4 validation: UniqueVariableNames - -- 8632753a validation: ScalarLeafs - -- 45844984 validation: ProvidedNonNullArguments - -- c741ea84 validation: VariablesAreInputTypes - -- 0875d74f validation: UniqueArgumentNames - -- 1fdab07f validation: LoneAnonymousOperation - -- 090df527 validation: KnownTypeNames - -- f99ca95e refactor: validation context - -- 8aac2817 validation: KnownFragmentNames - -- eae3efc9 validation: KnownDirectives - -- 70581168 refactor: separate InlineFragment and FragmentSpread - -- d6aec0d6 renamed schema.Directive to DirectiveDecl - -- b616eeca validation: KnownArgumentNames - -- 885af607 refactor: Location without pointer - -- 5a40251c tests: filter errors to currently tested rule - -- 9c054f53 refactor: lexer.Ident - -- 254afa8a validation: fragment type - -- b6ef81af added test export script - -- 95a4ecd8 validation: fields - -- c387449f validation: default values - -- 44c6e634 validation: arguments - -- 30dcc339 directive arguments as slice - -- d331ac27 input values as slice - -- 615afd61 fields as slice - -- 60759904 arguments as slice - -- f7d9ff4e refactor literals - -- 2e1fef01 keep track of location of arguments - -- 29e0b375 added EnumValue type - -- aa868e8d resolve fragments early - -- adeb53d6 remove resolver from query package - -- 2e23573f parse directive decl without arguments - -- 36f8ba8b fix introspection of default value (closes #65) - -- e06f5855 support for "deprecated" directive on enum values - -- 498fe396 support for @deprecated](https://github.com/deprecated) directive on fields (fixes [#64) - -- 93ddece9 refactor: DirectiveArgs - -- 8f5605a1 refactor directives - -- faf5384a simplify parseArguments - -- b2c2e906 some more docs - -- f4516523 added some method documentations - -- 91bd7f88 improved meta schema - -- 10dc8ee6 added support for directive declarations in schema - -- 28028f66 readme: more info on current project status - -- e9afca38 hint in error if method only exists on pointer type (fixes #60) - -- 356ebd93 nicer error messages (fixes #56) - -- e413f4ed make gocyclo happy - -- 6e92795e fix spelling - -- 306e27ef gofmt -s - -- 612317b2 fix ToJSON - -- 728e57a9 improved doc for MaxParallelism - -- e8590a10 don't execute any further resolvers after context got cancelled - -- 644435cc added MaxParallelism - -- 21802a33 readme: add Sourcegraph badge - -- 5b2978fc added support for recursive input values - -- 8c84afb1 improved structure of "make exec" code - -- d5a6ca49 make sure internal types don't get exposed - -- c9d4d865 fixed some null handling - -- a336dd4b added request.resolveVar - -- 943f80f4 added unmarshalerPacker type - -- f77f7339 refactored non-null handling in packer - -- ae0f1689 remove hasDefault flag from makePacker - -- 9cbad485 allow Unmarshaler for all types, not just scalars - -- f565a119 refactored "make exec" code - -- 07a09e5d properly check scalar types of result values - -- ecceddec Add ResolverError field to QueryError for post processing - -- b7c59ab9 renamed type - -- 5817d300 moved some introspection code into new package, added Schema.Introspect - -
cdef8563 removed SchemaBuilder - -It is not necessary any more. Simpler API wins. - -
- -
518a5fe7 Merge pull request #45 from nicksrandall/master - -fix wrong import statement - -
- -- 8112e719 fix wrong import statement - -- 7fafcc6e allow single value as implicit list (fixes #41) - -- 2b513d7e improved custom types - -- 191422c4 merged code for value coercion and packing - -- 232356b3 introspection for "skip" and "include" directives (fixes #30) - -- 2e10f7b8 readme: spec version and link (fixes #35) - -- 61eca4c7 pretty print SchemaBuilder.ToJSON - -- 5e09ced1 fix "null" value for empty descriptions of types - -- 33cd194f SchemaBuilder.ToJSON instead of SchemaToJSON (fixes #29) - -- fff173bc proper error message when using non-input type as input (#19) - -- b94f2afe improved support for null - -- 4130d540 added support for input object literals - -- 663e466f moved some code into separate file - -- 728e071e added support for lists as input values (fixes #19) - -- 86f0f145 fix Float literals - -- b07f277b raise error on unexported input field (fixes #24) - -- 4838c6f3 fix optional input fields (fixes #25) - -- a15deed4 better way to implement GraphQL interfaces (#23) - -- 7a66d0e0 add support for description comments (fixes #20) - -- 0b3be40c improved tracing - -- da879f4f small improvements to readme - -- f3f24cf6 added some documentation - -- 38598d83 added CI badge to readme - -- bab81332 starwars example: fix pagination panic (#12) - -- 5ce3ca69 testing: proper error on invalid ExpectedResult - -- 8f7d2b1e added relay.Handler - -- fce75a50 properly coerce Int input values ([#8](https://github.com/99designs/gqlgen/issues/8)) - -- 0dd38747 star wars example: pass operation name and variables ([#8](https://github.com/99designs/gqlgen/issues/8)) - -- 3b7efd5c fix __typename for concrete object types (fixes [#9](https://github.com/99designs/gqlgen/issues/9)) - -- 35667eda testing tools - -- 84571820 only create schema once for tests - -- de113f96 added MustParseSchema - -- d5e5f609 improved structure for tests - -- 947a1a3a added package with tools for Relay - -- 65f3e2b1 fix SchemaToJSON - -- cec7cea1 better error handling - -- e3386b06 improved type coercion and explicit ID type - -- 2ab9d765 support for custom scalars (fixes [#3](https://github.com/99designs/gqlgen/issues/3)) - -- bdfd5ce3 use custom error type less - -- 0a7a37d1 more flexible API for creating a schema - -- bd20a165 improved type handling - -- ffa9fea4 renamed GraphQLError to QueryError - -- fcfa135a refactor - -- c28891d8 added support for OpenTracing - -- 2cf7fcc8 added SchemaToJSON - -- f6b498ac stricter type mapping for input values - -- 3c15e177 execute mutations serially - -- 1faf6661 fix missing error - -- de9b7fed add support for mutations - -- 094061d8 improved error handling a bit - -- cdb088d6 refactor: args as input object - -- b06d3941 refactor: values - -- 4fd33958 refactor: improved type system - -
1d03e667 refactor: new package "common" - -package "query" does not depend on "schema" any more - -
- -- 1a959516 refactor - -- f8cb11c1 example/starwars: use interface base type to make type assertions nicer - -- 746da4b8 star wars example: friendsConnection - -- bec45364 parse type in query - -- be87a8fa remove unused code - -- 042e306a simpler way to resolve type refs in schema - -- 7cbf85fb improved type checking of arguments - -- 2b6460ae type check for scalars - -- 17034fe7 improved null handling - -- e6b6fbca small cleanup - -- 7b8cd1bc meta schema from graphql-js - -- 9333c0b3 introspection: inputFields - -- c4faac56 introspection: ofType - -- 86da8492 introspection: interfaces and possibleTypes - -- 20dbb845 proper nil support for lists - -- 2e3369ae resolve types in schema package - -- 7da95f4a introspection: enum values - -- cb423e6e improved handling of scalar types - -- 5b07780f introspection: original order for fields and args - -- 1e2d180c introspection: arguments - -- f21131bb refactored schema to be more in line with introspection - -- 0152d4f2 introspection: currently no descriptions and deprecations - -- ad5689bb field introspection - -- 2749d814 removed query.TypeReference - -
2eb105ec Revert "resolve scalar types in exec" - -This reverts commit fb3a6fc969b0c8c286c7d024a108f5696627639c. - -
- -- 40682d68 removed exec.typeRefExec - -- 64ea90fe makeWithType - -- 2966f213 added nonNilExec - -- c12a8ad3 added support for ints and floats in query - -- 0f85412b improved example - -- 22ce46d1 support for optional error result - -- 0fe56128 optional context parameter - -- f1bc9b21 syntax errors with proper line and column - -- ae299efc proper response format - -- 9619721b added support for contexts - -- 267fc631 refactor - -- 2e56e7ea renamed NewSchema to ParseSchema - -- 356b6e6b added godoc badge - -- 03f2e72d added README.md - -- 1134562a added non-null type - -- 8fa41551 renamed Input to InputObject - -- 6f2399aa introspection: type kind - -- e2c58f2f refactor: schema types for interface and input - -- 0c8c9436 introspection: __type - -- 99a37521 refactoring: calculate "implemented by" in schema package - -- 1cac7e56 introspection: queryType - -- cc348faf first bit of introspection - -- fb3a6fc9 resolve scalar types in exec - -- 4cb8dcc0 panic handlers - -- c7a528d4 proper error handling when creating schema - -- ae37381c add support for __typename - -- 4057080f add support for union types - -- d304a418 attribute source of star wars schema - -- 0fcab871 added LICENSE - -- 0dc0116d support for inline fragments - -- f5e7d070 support for type assertions - -- fcb853c6 refactoring: addResultFn - -- 741343f8 explicit fragment spread exec - -- 73759258 all missing stubs for star wars example - -- edc78e2b parallelism - -- fb633714 collect fields - -- 08f02a2b execs - -- d70d16c4 added server example - -- 6f9a89db separate example/starwars package - -- e4060db5 added support for directives - -- 89b06652 added support for variables - -- 78065ecb added support for enums - -- 18645e60 added support for query fragments - -- 84f532b9 added support for aliases - -- 59d2a619 improved support for arguments - -- edce4ec8 proper star wars data - -- d6ffc01d syntax support for full star wars schema - -- b5824104 support for comments - -- 2f9ce9b4 support for entry points - -- 0b3d1038 support for arguments - -- cff8b302 support for arrays - -- 565e59f5 schema package - -- 1ae71ba2 query package - -- 42c13e7a named types, complex objects - -- bf64e5da initial commit - - - - - - - diff --git a/vendor/github.com/99designs/gqlgen/CONTRIBUTING.md b/vendor/github.com/99designs/gqlgen/CONTRIBUTING.md deleted file mode 100644 index 3919b2a4b83..00000000000 --- a/vendor/github.com/99designs/gqlgen/CONTRIBUTING.md +++ /dev/null @@ -1,27 +0,0 @@ -# Contribution Guidelines - -Want to contribute to gqlgen? Here are some guidelines for how we accept help. - -## Getting in Touch - -Our [discord](https://discord.gg/DYEq3EMs4U) server is the best place to ask questions or get advice on using gqlgen. - -## Reporting Bugs and Issues - - We use [GitHub Issues](https://github.com/99designs/gqlgen/issues) to track bugs, so please do a search before submitting to ensure your problem isn't already tracked. - -### New Issues - -Please provide the expected and observed behaviours in your issue. A minimal GraphQL schema or configuration file should be provided where appropriate. - -## Proposing a Change - -If you intend to implement a feature for gqlgen, or make a non-trivial change to the current implementation, we recommend [first filing an issue](https://github.com/99designs/gqlgen/issues/new) marked with the `proposal` tag, so that the engineering team can provide guidance and feedback on the direction of an implementation. This also help ensure that other people aren't also working on the same thing. - -Bug fixes are welcome and should come with appropriate test coverage. - -New features should be made against the `next` branch. - -### License - -By contributing to gqlgen, you agree that your contributions will be licensed under its MIT license. diff --git a/vendor/github.com/99designs/gqlgen/LICENSE b/vendor/github.com/99designs/gqlgen/LICENSE deleted file mode 100644 index 10bb21c07e7..00000000000 --- a/vendor/github.com/99designs/gqlgen/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2020 gqlgen authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/99designs/gqlgen/README.md b/vendor/github.com/99designs/gqlgen/README.md deleted file mode 100644 index 0621c55bfe6..00000000000 --- a/vendor/github.com/99designs/gqlgen/README.md +++ /dev/null @@ -1,150 +0,0 @@ -![gqlgen](https://user-images.githubusercontent.com/980499/133180111-d064b38c-6eb9-444b-a60f-7005a6e68222.png) - - -# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![Go Reference](https://pkg.go.dev/badge/github.com/99designs/gqlgen.svg)](https://pkg.go.dev/github.com/99designs/gqlgen) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) - -## What is gqlgen? - -[gqlgen](https://github.com/99designs/gqlgen) is a Go library for building GraphQL servers without any fuss.
- -- **gqlgen is based on a Schema first approach** — You get to Define your API using the GraphQL [Schema Definition Language](http://graphql.org/learn/schema/). -- **gqlgen prioritizes Type safety** — You should never see `map[string]interface{}` here. -- **gqlgen enables Codegen** — We generate the boring bits, so you can focus on building your app quickly. - -Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go graphql [implementations](https://gqlgen.com/feature-comparison/) - -## Quick start -1. [Initialise a new go module](https://golang.org/doc/tutorial/create-module) - - mkdir example - cd example - go mod init example - -2. Add `github.com/99designs/gqlgen` to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) - - printf '// +build tools\npackage tools\nimport _ "github.com/99designs/gqlgen"' | gofmt > tools.go - go mod tidy - -3. Initialise gqlgen config and generate models - - go run github.com/99designs/gqlgen init - -4. Start the graphql server - - go run server.go - -More help to get started: - - [Getting started tutorial](https://gqlgen.com/getting-started/) - a comprehensive guide to help you get started - - [Real-world examples](https://github.com/99designs/gqlgen/tree/master/_examples) show how to create GraphQL applications - - [Reference docs](https://pkg.go.dev/github.com/99designs/gqlgen) for the APIs - -## Reporting Issues - -If you think you've found a bug, or something isn't behaving the way you think it should, please raise an [issue](https://github.com/99designs/gqlgen/issues) on GitHub. - -## Contributing - -We welcome contributions, Read our [Contribution Guidelines](https://github.com/99designs/gqlgen/blob/master/CONTRIBUTING.md) to learn more about contributing to **gqlgen** -## Frequently asked questions - -### How do I prevent fetching child objects that might not be used? - -When you have nested or recursive schema like this: - -```graphql -type User { - id: ID! - name: String! - friends: [User!]! -} -``` - -You need to tell gqlgen that it should only fetch friends if the user requested it. There are two ways to do this; - -- #### Using Custom Models - -Write a custom model that omits the friends field: - -```go -type User struct { - ID int - Name string -} -``` - -And reference the model in `gqlgen.yml`: - -```yaml -# gqlgen.yml -models: - User: - model: github.com/you/pkg/model.User # go import path to the User struct above -``` - -- #### Using Explicit Resolvers - -If you want to Keep using the generated model, mark the field as requiring a resolver explicitly in `gqlgen.yml` like this: - -```yaml -# gqlgen.yml -models: - User: - fields: - friends: - resolver: true # force a resolver to be generated -``` - -After doing either of the above and running generate we will need to provide a resolver for friends: - -```go -func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) { - // select * from user where friendid = obj.ID - return friends, nil -} -``` - -You can also use inline config with directives to achieve the same result - -```graphql -directive @goModel(model: String, models: [String!]) on OBJECT - | INPUT_OBJECT - | SCALAR - | ENUM - | INTERFACE - | UNION - -directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION - | FIELD_DEFINITION - -type User @goModel(model: "github.com/you/pkg/model.User") { - id: ID! @goField(name: "todoId") - friends: [User!]! @goField(forceResolver: true) -} -``` - -### Can I change the type of the ID from type String to Type Int? - -Yes! You can by remapping it in config as seen below: - -```yaml -models: - ID: # The GraphQL type ID is backed by - model: - - github.com/99designs/gqlgen/graphql.IntID # a go integer - - github.com/99designs/gqlgen/graphql.ID # or a go string -``` - -This means gqlgen will be able to automatically bind to strings or ints for models you have written yourself, but the -first model in this list is used as the default type and it will always be used when: - -- Generating models based on schema -- As arguments in resolvers - -There isn't any way around this, gqlgen has no way to know what you want in a given context. - -## Other Resources - -- [Christopher Biscardi @ Gophercon UK 2018](https://youtu.be/FdURVezcdcw) -- [Introducing gqlgen: a GraphQL Server Generator for Go](https://99designs.com.au/blog/engineering/gqlgen-a-graphql-server-generator-for-go/) -- [Dive into GraphQL by Iván Corrales Solera](https://medium.com/@ivan.corrales.solera/dive-into-graphql-9bfedf22e1a) -- [Sample Project built on gqlgen with Postgres by Oleg Shalygin](https://github.com/oshalygin/gqlgen-pg-todo-example) diff --git a/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md b/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md deleted file mode 100644 index 86c2f3776fc..00000000000 --- a/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md +++ /dev/null @@ -1,14 +0,0 @@ -# When gqlgen gets released, the following things need to happen -Assuming the next version is $NEW_VERSION=v0.16.0 or something like that. - -1. Run the https://github.com/99designs/gqlgen/blob/master/bin/release: -``` -./bin/release $NEW_VERSION -``` -2. git-chglog -o CHANGELOG.md -3. git commit and push the CHANGELOG.md -4. Go to https://github.com/99designs/gqlgen/releases and draft new release, autogenerate the release notes, and Create a discussion for this release -5. Comment on the release discussion with any really important notes (breaking changes) - -I used https://github.com/git-chglog/git-chglog to automate the changelog maintenance process for now. We could just as easily use go releaser to make the whole thing automated. - diff --git a/vendor/github.com/99designs/gqlgen/TESTING.md b/vendor/github.com/99designs/gqlgen/TESTING.md deleted file mode 100644 index e5d49e8a9f3..00000000000 --- a/vendor/github.com/99designs/gqlgen/TESTING.md +++ /dev/null @@ -1,40 +0,0 @@ -How to write tests for gqlgen -=== - -Testing generated code is a little tricky, heres how its currently set up. - -### Testing responses from a server - -There is a server in `codegen/testserver` that is generated as part -of `go generate ./...`, and tests written against it. - -There are also a bunch of tests in against the examples, feel free to take examples from there. - - -### Testing the errors generated by the binary - -These tests are **really** slow, because they need to run the whole codegen step. Use them very sparingly. If you can, find a way to unit test it instead. - -Take a look at `codegen/testserver/input_test.go` for an example. - -### Testing introspection - -Introspection is tested by diffing the output of `graphql get-schema` against an expected output. - -Setting up the integration environment is a little tricky: -```bash -cd integration -go generate ./... -go run ./server/server.go -``` -in another terminal -```bash -cd integration -npm install -./node_modules/.bin/graphql-codegen -``` - -will write the schema to `integration/schema-fetched.graphql`, compare that with `schema-expected.graphql` - -CI will run this and fail the build if the two files dont match. - diff --git a/vendor/github.com/99designs/gqlgen/api/generate.go b/vendor/github.com/99designs/gqlgen/api/generate.go deleted file mode 100644 index 6a85cd941ac..00000000000 --- a/vendor/github.com/99designs/gqlgen/api/generate.go +++ /dev/null @@ -1,125 +0,0 @@ -package api - -import ( - "fmt" - "syscall" - - "github.com/99designs/gqlgen/codegen" - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/plugin" - "github.com/99designs/gqlgen/plugin/federation" - "github.com/99designs/gqlgen/plugin/modelgen" - "github.com/99designs/gqlgen/plugin/resolvergen" -) - -func Generate(cfg *config.Config, option ...Option) error { - _ = syscall.Unlink(cfg.Exec.Filename) - if cfg.Model.IsDefined() { - _ = syscall.Unlink(cfg.Model.Filename) - } - - plugins := []plugin.Plugin{} - if cfg.Model.IsDefined() { - plugins = append(plugins, modelgen.New()) - } - plugins = append(plugins, resolvergen.New()) - if cfg.Federation.IsDefined() { - plugins = append([]plugin.Plugin{federation.New()}, plugins...) - } - - for _, o := range option { - o(cfg, &plugins) - } - - for _, p := range plugins { - if inj, ok := p.(plugin.EarlySourceInjector); ok { - if s := inj.InjectSourceEarly(); s != nil { - cfg.Sources = append(cfg.Sources, s) - } - } - } - - if err := cfg.LoadSchema(); err != nil { - return fmt.Errorf("failed to load schema: %w", err) - } - - for _, p := range plugins { - if inj, ok := p.(plugin.LateSourceInjector); ok { - if s := inj.InjectSourceLate(cfg.Schema); s != nil { - cfg.Sources = append(cfg.Sources, s) - } - } - } - - // LoadSchema again now we have everything - if err := cfg.LoadSchema(); err != nil { - return fmt.Errorf("failed to load schema: %w", err) - } - - if err := cfg.Init(); err != nil { - return fmt.Errorf("generating core failed: %w", err) - } - - for _, p := range plugins { - if mut, ok := p.(plugin.ConfigMutator); ok { - err := mut.MutateConfig(cfg) - if err != nil { - return fmt.Errorf("%s: %w", p.Name(), err) - } - } - } - // Merge again now that the generated models have been injected into the typemap - data, err := codegen.BuildData(cfg) - if err != nil { - return fmt.Errorf("merging type systems failed: %w", err) - } - - if err = codegen.GenerateCode(data); err != nil { - return fmt.Errorf("generating core failed: %w", err) - } - - if !cfg.SkipModTidy { - if err = cfg.Packages.ModTidy(); err != nil { - return fmt.Errorf("tidy failed: %w", err) - } - } - - for _, p := range plugins { - if mut, ok := p.(plugin.CodeGenerator); ok { - err := mut.GenerateCode(data) - if err != nil { - return fmt.Errorf("%s: %w", p.Name(), err) - } - } - } - - if err = codegen.GenerateCode(data); err != nil { - return fmt.Errorf("generating core failed: %w", err) - } - - if !cfg.SkipValidation { - if err := validate(cfg); err != nil { - return fmt.Errorf("validation failed: %w", err) - } - } - - return nil -} - -func validate(cfg *config.Config) error { - roots := []string{cfg.Exec.ImportPath()} - if cfg.Model.IsDefined() { - roots = append(roots, cfg.Model.ImportPath()) - } - - if cfg.Resolver.IsDefined() { - roots = append(roots, cfg.Resolver.ImportPath()) - } - - cfg.Packages.LoadAll(roots...) - errs := cfg.Packages.Errors() - if len(errs) > 0 { - return errs - } - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/api/option.go b/vendor/github.com/99designs/gqlgen/api/option.go deleted file mode 100644 index d376193dfef..00000000000 --- a/vendor/github.com/99designs/gqlgen/api/option.go +++ /dev/null @@ -1,47 +0,0 @@ -package api - -import ( - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/plugin" -) - -type Option func(cfg *config.Config, plugins *[]plugin.Plugin) - -func NoPlugins() Option { - return func(cfg *config.Config, plugins *[]plugin.Plugin) { - *plugins = nil - } -} - -func AddPlugin(p plugin.Plugin) Option { - return func(cfg *config.Config, plugins *[]plugin.Plugin) { - *plugins = append(*plugins, p) - } -} - -// PrependPlugin prepends plugin any existing plugins -func PrependPlugin(p plugin.Plugin) Option { - return func(cfg *config.Config, plugins *[]plugin.Plugin) { - *plugins = append([]plugin.Plugin{p}, *plugins...) - } -} - -// ReplacePlugin replaces any existing plugin with a matching plugin name -func ReplacePlugin(p plugin.Plugin) Option { - return func(cfg *config.Config, plugins *[]plugin.Plugin) { - if plugins != nil { - found := false - ps := *plugins - for i, o := range ps { - if p.Name() == o.Name() { - ps[i] = p - found = true - } - } - if !found { - ps = append(ps, p) - } - *plugins = ps - } - } -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/args.go b/vendor/github.com/99designs/gqlgen/codegen/args.go deleted file mode 100644 index 8c08d924fb7..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/args.go +++ /dev/null @@ -1,118 +0,0 @@ -package codegen - -import ( - "fmt" - "go/types" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -type ArgSet struct { - Args []*FieldArgument - FuncDecl string -} - -type FieldArgument struct { - *ast.ArgumentDefinition - TypeReference *config.TypeReference - VarName string // The name of the var in go - Object *Object // A link back to the parent object - Default interface{} // The default value - Directives []*Directive - Value interface{} // value set in Data -} - -// ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive -func (f *FieldArgument) ImplDirectives() []*Directive { - d := make([]*Directive, 0) - for i := range f.Directives { - if !f.Directives[i].Builtin && f.Directives[i].IsLocation(ast.LocationArgumentDefinition) { - d = append(d, f.Directives[i]) - } - } - - return d -} - -func (f *FieldArgument) DirectiveObjName() string { - return "rawArgs" -} - -func (f *FieldArgument) Stream() bool { - return f.Object != nil && f.Object.Stream -} - -func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) { - tr, err := b.Binder.TypeReference(arg.Type, nil) - if err != nil { - return nil, err - } - - argDirs, err := b.getDirectives(arg.Directives) - if err != nil { - return nil, err - } - newArg := FieldArgument{ - ArgumentDefinition: arg, - TypeReference: tr, - Object: obj, - VarName: templates.ToGoPrivate(arg.Name), - Directives: argDirs, - } - - if arg.DefaultValue != nil { - newArg.Default, err = arg.DefaultValue.Value(nil) - if err != nil { - return nil, fmt.Errorf("default value is not valid: %w", err) - } - } - - return &newArg, nil -} - -func (b *builder) bindArgs(field *Field, params *types.Tuple) ([]*FieldArgument, error) { - var newArgs []*FieldArgument - -nextArg: - for j := 0; j < params.Len(); j++ { - param := params.At(j) - for _, oldArg := range field.Args { - if strings.EqualFold(oldArg.Name, param.Name()) { - tr, err := b.Binder.TypeReference(oldArg.Type, param.Type()) - if err != nil { - return nil, err - } - oldArg.TypeReference = tr - - newArgs = append(newArgs, oldArg) - continue nextArg - } - } - - // no matching arg found, abort - return nil, fmt.Errorf("arg %s not in schema", param.Name()) - } - - return newArgs, nil -} - -func (a *Data) Args() map[string][]*FieldArgument { - ret := map[string][]*FieldArgument{} - for _, o := range a.Objects { - for _, f := range o.Fields { - if len(f.Args) > 0 { - ret[f.ArgsFunc()] = f.Args - } - } - } - - for _, d := range a.Directives() { - if len(d.Args) > 0 { - ret[d.ArgsFunc()] = d.Args - } - } - return ret -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/args.gotpl b/vendor/github.com/99designs/gqlgen/codegen/args.gotpl deleted file mode 100644 index 7b541ae1f2e..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/args.gotpl +++ /dev/null @@ -1,36 +0,0 @@ -{{ range $name, $args := .Args }} -func (ec *executionContext) {{ $name }}(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - {{- range $i, $arg := . }} - var arg{{$i}} {{ $arg.TypeReference.GO | ref}} - if tmp, ok := rawArgs[{{$arg.Name|quote}}]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField({{$arg.Name|quote}})) - {{- if $arg.ImplDirectives }} - directive0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp) } - {{ template "implDirectives" $arg }} - tmp, err = directive{{$arg.ImplDirectives|len}}(ctx) - if err != nil { - return nil, graphql.ErrorOnPath(ctx, err) - } - if data, ok := tmp.({{ $arg.TypeReference.GO | ref }}) ; ok { - arg{{$i}} = data - {{- if $arg.TypeReference.IsNilable }} - } else if tmp == nil { - arg{{$i}} = nil - {{- end }} - } else { - return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be {{ $arg.TypeReference.GO }}`, tmp)) - } - {{- else }} - arg{{$i}}, err = ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp) - if err != nil { - return nil, err - } - {{- end }} - } - args[{{$arg.Name|quote}}] = arg{{$i}} - {{- end }} - return args, nil -} -{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/complexity.go b/vendor/github.com/99designs/gqlgen/codegen/complexity.go deleted file mode 100644 index e9c6a20ee83..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/complexity.go +++ /dev/null @@ -1,11 +0,0 @@ -package codegen - -func (o *Object) UniqueFields() map[string][]*Field { - m := map[string][]*Field{} - - for _, f := range o.Fields { - m[f.GoFieldName] = append(m[f.GoFieldName], f) - } - - return m -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/binder.go b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go deleted file mode 100644 index 90820de6d36..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/config/binder.go +++ /dev/null @@ -1,494 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "go/token" - "go/types" - - "golang.org/x/tools/go/packages" - - "github.com/99designs/gqlgen/codegen/templates" - "github.com/99designs/gqlgen/internal/code" - "github.com/vektah/gqlparser/v2/ast" -) - -var ErrTypeNotFound = errors.New("unable to find type") - -// Binder connects graphql types to golang types using static analysis -type Binder struct { - pkgs *code.Packages - schema *ast.Schema - cfg *Config - References []*TypeReference - SawInvalid bool - objectCache map[string]map[string]types.Object -} - -func (c *Config) NewBinder() *Binder { - return &Binder{ - pkgs: c.Packages, - schema: c.Schema, - cfg: c, - } -} - -func (b *Binder) TypePosition(typ types.Type) token.Position { - named, isNamed := typ.(*types.Named) - if !isNamed { - return token.Position{ - Filename: "unknown", - } - } - - return b.ObjectPosition(named.Obj()) -} - -func (b *Binder) ObjectPosition(typ types.Object) token.Position { - if typ == nil { - return token.Position{ - Filename: "unknown", - } - } - pkg := b.pkgs.Load(typ.Pkg().Path()) - return pkg.Fset.Position(typ.Pos()) -} - -func (b *Binder) FindTypeFromName(name string) (types.Type, error) { - pkgName, typeName := code.PkgAndType(name) - return b.FindType(pkgName, typeName) -} - -func (b *Binder) FindType(pkgName string, typeName string) (types.Type, error) { - if pkgName == "" { - if typeName == "map[string]interface{}" { - return MapType, nil - } - - if typeName == "interface{}" { - return InterfaceType, nil - } - } - - obj, err := b.FindObject(pkgName, typeName) - if err != nil { - return nil, err - } - - if fun, isFunc := obj.(*types.Func); isFunc { - return fun.Type().(*types.Signature).Params().At(0).Type(), nil - } - return obj.Type(), nil -} - -var ( - MapType = types.NewMap(types.Typ[types.String], types.NewInterfaceType(nil, nil).Complete()) - InterfaceType = types.NewInterfaceType(nil, nil) -) - -func (b *Binder) DefaultUserObject(name string) (types.Type, error) { - models := b.cfg.Models[name].Model - if len(models) == 0 { - return nil, fmt.Errorf(name + " not found in typemap") - } - - if models[0] == "map[string]interface{}" { - return MapType, nil - } - - if models[0] == "interface{}" { - return InterfaceType, nil - } - - pkgName, typeName := code.PkgAndType(models[0]) - if pkgName == "" { - return nil, fmt.Errorf("missing package name for %s", name) - } - - obj, err := b.FindObject(pkgName, typeName) - if err != nil { - return nil, err - } - - return obj.Type(), nil -} - -func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, error) { - if pkgName == "" { - return nil, fmt.Errorf("package cannot be nil") - } - - pkg := b.pkgs.LoadWithTypes(pkgName) - if pkg == nil { - err := b.pkgs.Errors() - if err != nil { - return nil, fmt.Errorf("package could not be loaded: %s.%s: %w", pkgName, typeName, err) - } - return nil, fmt.Errorf("required package was not loaded: %s.%s", pkgName, typeName) - } - - if b.objectCache == nil { - b.objectCache = make(map[string]map[string]types.Object, b.pkgs.Count()) - } - - defsIndex, ok := b.objectCache[pkgName] - if !ok { - defsIndex = indexDefs(pkg) - b.objectCache[pkgName] = defsIndex - } - - // function based marshalers take precedence - if val, ok := defsIndex["Marshal"+typeName]; ok { - return val, nil - } - - if val, ok := defsIndex[typeName]; ok { - return val, nil - } - - return nil, fmt.Errorf("%w: %s.%s", ErrTypeNotFound, pkgName, typeName) -} - -func indexDefs(pkg *packages.Package) map[string]types.Object { - res := make(map[string]types.Object) - - scope := pkg.Types.Scope() - for astNode, def := range pkg.TypesInfo.Defs { - // only look at defs in the top scope - if def == nil { - continue - } - parent := def.Parent() - if parent == nil || parent != scope { - continue - } - - if _, ok := res[astNode.Name]; !ok { - // The above check may not be really needed, it is only here to have a consistent behavior with - // previous implementation of FindObject() function which only honored the first inclusion of a def. - // If this is still needed, we can consider something like sync.Map.LoadOrStore() to avoid two lookups. - res[astNode.Name] = def - } - } - - return res -} - -func (b *Binder) PointerTo(ref *TypeReference) *TypeReference { - newRef := *ref - newRef.GO = types.NewPointer(ref.GO) - b.References = append(b.References, &newRef) - return &newRef -} - -// TypeReference is used by args and field types. The Definition can refer to both input and output types. -type TypeReference struct { - Definition *ast.Definition - GQL *ast.Type - GO types.Type // Type of the field being bound. Could be a pointer or a value type of Target. - Target types.Type // The actual type that we know how to bind to. May require pointer juggling when traversing to fields. - CastType types.Type // Before calling marshalling functions cast from/to this base type - Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function - Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function - IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler - IsContext bool // Is the Marshaler/Unmarshaller the context version; applies to either the method or interface variety. -} - -func (ref *TypeReference) Elem() *TypeReference { - if p, isPtr := ref.GO.(*types.Pointer); isPtr { - newRef := *ref - newRef.GO = p.Elem() - return &newRef - } - - if ref.IsSlice() { - newRef := *ref - newRef.GO = ref.GO.(*types.Slice).Elem() - newRef.GQL = ref.GQL.Elem - return &newRef - } - return nil -} - -func (t *TypeReference) IsPtr() bool { - _, isPtr := t.GO.(*types.Pointer) - return isPtr -} - -// fix for https://github.com/golang/go/issues/31103 may make it possible to remove this (may still be useful) -// -func (t *TypeReference) IsPtrToPtr() bool { - if p, isPtr := t.GO.(*types.Pointer); isPtr { - _, isPtr := p.Elem().(*types.Pointer) - return isPtr - } - return false -} - -func (t *TypeReference) IsNilable() bool { - return IsNilable(t.GO) -} - -func (t *TypeReference) IsSlice() bool { - _, isSlice := t.GO.(*types.Slice) - return t.GQL.Elem != nil && isSlice -} - -func (t *TypeReference) IsPtrToSlice() bool { - if t.IsPtr() { - _, isPointerToSlice := t.GO.(*types.Pointer).Elem().(*types.Slice) - return isPointerToSlice - } - return false -} - -func (t *TypeReference) IsNamed() bool { - _, isSlice := t.GO.(*types.Named) - return isSlice -} - -func (t *TypeReference) IsStruct() bool { - _, isStruct := t.GO.Underlying().(*types.Struct) - return isStruct -} - -func (t *TypeReference) IsScalar() bool { - return t.Definition.Kind == ast.Scalar -} - -func (t *TypeReference) UniquenessKey() string { - nullability := "O" - if t.GQL.NonNull { - nullability = "N" - } - - elemNullability := "" - if t.GQL.Elem != nil && t.GQL.Elem.NonNull { - // Fix for #896 - elemNullability = "ᚄ" - } - return nullability + t.Definition.Name + "2" + templates.TypeIdentifier(t.GO) + elemNullability -} - -func (t *TypeReference) MarshalFunc() string { - if t.Definition == nil { - panic(errors.New("Definition missing for " + t.GQL.Name())) - } - - if t.Definition.Kind == ast.InputObject { - return "" - } - - return "marshal" + t.UniquenessKey() -} - -func (t *TypeReference) UnmarshalFunc() string { - if t.Definition == nil { - panic(errors.New("Definition missing for " + t.GQL.Name())) - } - - if !t.Definition.IsInputType() { - return "" - } - - return "unmarshal" + t.UniquenessKey() -} - -func (t *TypeReference) IsTargetNilable() bool { - return IsNilable(t.Target) -} - -func (b *Binder) PushRef(ret *TypeReference) { - b.References = append(b.References, ret) -} - -func isMap(t types.Type) bool { - if t == nil { - return true - } - _, ok := t.(*types.Map) - return ok -} - -func isIntf(t types.Type) bool { - if t == nil { - return true - } - _, ok := t.(*types.Interface) - return ok -} - -func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret *TypeReference, err error) { - if !isValid(bindTarget) { - b.SawInvalid = true - return nil, fmt.Errorf("%s has an invalid type", schemaType.Name()) - } - - var pkgName, typeName string - def := b.schema.Types[schemaType.Name()] - defer func() { - if err == nil && ret != nil { - b.PushRef(ret) - } - }() - - if len(b.cfg.Models[schemaType.Name()].Model) == 0 { - return nil, fmt.Errorf("%s was not found", schemaType.Name()) - } - - for _, model := range b.cfg.Models[schemaType.Name()].Model { - if model == "map[string]interface{}" { - if !isMap(bindTarget) { - continue - } - return &TypeReference{ - Definition: def, - GQL: schemaType, - GO: MapType, - }, nil - } - - if model == "interface{}" { - if !isIntf(bindTarget) { - continue - } - return &TypeReference{ - Definition: def, - GQL: schemaType, - GO: InterfaceType, - }, nil - } - - pkgName, typeName = code.PkgAndType(model) - if pkgName == "" { - return nil, fmt.Errorf("missing package name for %s", schemaType.Name()) - } - - ref := &TypeReference{ - Definition: def, - GQL: schemaType, - } - - obj, err := b.FindObject(pkgName, typeName) - if err != nil { - return nil, err - } - - if fun, isFunc := obj.(*types.Func); isFunc { - ref.GO = fun.Type().(*types.Signature).Params().At(0).Type() - ref.IsContext = fun.Type().(*types.Signature).Results().At(0).Type().String() == "github.com/99designs/gqlgen/graphql.ContextMarshaler" - ref.Marshaler = fun - ref.Unmarshaler = types.NewFunc(0, fun.Pkg(), "Unmarshal"+typeName, nil) - } else if hasMethod(obj.Type(), "MarshalGQLContext") && hasMethod(obj.Type(), "UnmarshalGQLContext") { - ref.GO = obj.Type() - ref.IsContext = true - ref.IsMarshaler = true - } else if hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL") { - ref.GO = obj.Type() - ref.IsMarshaler = true - } else if underlying := basicUnderlying(obj.Type()); def.IsLeafType() && underlying != nil && underlying.Kind() == types.String { - // TODO delete before v1. Backwards compatibility case for named types wrapping strings (see #595) - - ref.GO = obj.Type() - ref.CastType = underlying - - underlyingRef, err := b.TypeReference(&ast.Type{NamedType: "String"}, nil) - if err != nil { - return nil, err - } - - ref.Marshaler = underlyingRef.Marshaler - ref.Unmarshaler = underlyingRef.Unmarshaler - } else { - ref.GO = obj.Type() - } - - ref.Target = ref.GO - ref.GO = b.CopyModifiersFromAst(schemaType, ref.GO) - - if bindTarget != nil { - if err = code.CompatibleTypes(ref.GO, bindTarget); err != nil { - continue - } - ref.GO = bindTarget - } - - return ref, nil - } - - return nil, fmt.Errorf("%s is incompatible with %s", schemaType.Name(), bindTarget.String()) -} - -func isValid(t types.Type) bool { - basic, isBasic := t.(*types.Basic) - if !isBasic { - return true - } - return basic.Kind() != types.Invalid -} - -func (b *Binder) CopyModifiersFromAst(t *ast.Type, base types.Type) types.Type { - if t.Elem != nil { - child := b.CopyModifiersFromAst(t.Elem, base) - if _, isStruct := child.Underlying().(*types.Struct); isStruct && !b.cfg.OmitSliceElementPointers { - child = types.NewPointer(child) - } - return types.NewSlice(child) - } - - var isInterface bool - if named, ok := base.(*types.Named); ok { - _, isInterface = named.Underlying().(*types.Interface) - } - - if !isInterface && !IsNilable(base) && !t.NonNull { - return types.NewPointer(base) - } - - return base -} - -func IsNilable(t types.Type) bool { - if namedType, isNamed := t.(*types.Named); isNamed { - return IsNilable(namedType.Underlying()) - } - _, isPtr := t.(*types.Pointer) - _, isMap := t.(*types.Map) - _, isInterface := t.(*types.Interface) - _, isSlice := t.(*types.Slice) - _, isChan := t.(*types.Chan) - return isPtr || isMap || isInterface || isSlice || isChan -} - -func hasMethod(it types.Type, name string) bool { - if ptr, isPtr := it.(*types.Pointer); isPtr { - it = ptr.Elem() - } - namedType, ok := it.(*types.Named) - if !ok { - return false - } - - for i := 0; i < namedType.NumMethods(); i++ { - if namedType.Method(i).Name() == name { - return true - } - } - return false -} - -func basicUnderlying(it types.Type) *types.Basic { - if ptr, isPtr := it.(*types.Pointer); isPtr { - it = ptr.Elem() - } - namedType, ok := it.(*types.Named) - if !ok { - return nil - } - - if basic, ok := namedType.Underlying().(*types.Basic); ok { - return basic - } - - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/config.go b/vendor/github.com/99designs/gqlgen/codegen/config/config.go deleted file mode 100644 index 9affe6a6916..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/config/config.go +++ /dev/null @@ -1,648 +0,0 @@ -package config - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "sort" - "strings" - - "github.com/99designs/gqlgen/internal/code" - "github.com/vektah/gqlparser/v2" - "github.com/vektah/gqlparser/v2/ast" - "gopkg.in/yaml.v2" -) - -type Config struct { - SchemaFilename StringList `yaml:"schema,omitempty"` - Exec ExecConfig `yaml:"exec"` - Model PackageConfig `yaml:"model,omitempty"` - Federation PackageConfig `yaml:"federation,omitempty"` - Resolver ResolverConfig `yaml:"resolver,omitempty"` - AutoBind []string `yaml:"autobind"` - Models TypeMap `yaml:"models,omitempty"` - StructTag string `yaml:"struct_tag,omitempty"` - Directives map[string]DirectiveConfig `yaml:"directives,omitempty"` - OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"` - SkipValidation bool `yaml:"skip_validation,omitempty"` - SkipModTidy bool `yaml:"skip_mod_tidy,omitempty"` - Sources []*ast.Source `yaml:"-"` - Packages *code.Packages `yaml:"-"` - Schema *ast.Schema `yaml:"-"` - - // Deprecated: use Federation instead. Will be removed next release - Federated bool `yaml:"federated,omitempty"` -} - -var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"} - -// DefaultConfig creates a copy of the default config -func DefaultConfig() *Config { - return &Config{ - SchemaFilename: StringList{"schema.graphql"}, - Model: PackageConfig{Filename: "models_gen.go"}, - Exec: ExecConfig{Filename: "generated.go"}, - Directives: map[string]DirectiveConfig{}, - Models: TypeMap{}, - } -} - -// LoadDefaultConfig loads the default config so that it is ready to be used -func LoadDefaultConfig() (*Config, error) { - config := DefaultConfig() - - for _, filename := range config.SchemaFilename { - filename = filepath.ToSlash(filename) - var err error - var schemaRaw []byte - schemaRaw, err = ioutil.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to open schema: %w", err) - } - - config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) - } - - return config, nil -} - -// LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories -// walking up the tree. The closest config file will be returned. -func LoadConfigFromDefaultLocations() (*Config, error) { - cfgFile, err := findCfg() - if err != nil { - return nil, err - } - - err = os.Chdir(filepath.Dir(cfgFile)) - if err != nil { - return nil, fmt.Errorf("unable to enter config dir: %w", err) - } - return LoadConfig(cfgFile) -} - -var path2regex = strings.NewReplacer( - `.`, `\.`, - `*`, `.+`, - `\`, `[\\/]`, - `/`, `[\\/]`, -) - -// LoadConfig reads the gqlgen.yml config file -func LoadConfig(filename string) (*Config, error) { - config := DefaultConfig() - - b, err := ioutil.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to read config: %w", err) - } - - if err := yaml.UnmarshalStrict(b, config); err != nil { - return nil, fmt.Errorf("unable to parse config: %w", err) - } - - if err := CompleteConfig(config); err != nil { - return nil, err - } - - return config, nil -} - -// CompleteConfig fills in the schema and other values to a config loaded from -// YAML. -func CompleteConfig(config *Config) error { - defaultDirectives := map[string]DirectiveConfig{ - "skip": {SkipRuntime: true}, - "include": {SkipRuntime: true}, - "deprecated": {SkipRuntime: true}, - "specifiedBy": {SkipRuntime: true}, - } - - for key, value := range defaultDirectives { - if _, defined := config.Directives[key]; !defined { - config.Directives[key] = value - } - } - - preGlobbing := config.SchemaFilename - config.SchemaFilename = StringList{} - for _, f := range preGlobbing { - var matches []string - - // for ** we want to override default globbing patterns and walk all - // subdirectories to match schema files. - if strings.Contains(f, "**") { - pathParts := strings.SplitN(f, "**", 2) - rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`) - // turn the rest of the glob into a regex, anchored only at the end because ** allows - // for any number of dirs in between and walk will let us match against the full path name - globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`) - - if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) { - matches = append(matches, path) - } - - return nil - }); err != nil { - return fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) - } - } else { - var err error - matches, err = filepath.Glob(f) - if err != nil { - return fmt.Errorf("failed to glob schema filename %s: %w", f, err) - } - } - - for _, m := range matches { - if config.SchemaFilename.Has(m) { - continue - } - config.SchemaFilename = append(config.SchemaFilename, m) - } - } - - for _, filename := range config.SchemaFilename { - filename = filepath.ToSlash(filename) - var err error - var schemaRaw []byte - schemaRaw, err = ioutil.ReadFile(filename) - if err != nil { - return fmt.Errorf("unable to open schema: %w", err) - } - - config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) - } - return nil -} - -func (c *Config) Init() error { - if c.Packages == nil { - c.Packages = &code.Packages{} - } - - if c.Schema == nil { - if err := c.LoadSchema(); err != nil { - return err - } - } - - err := c.injectTypesFromSchema() - if err != nil { - return err - } - - err = c.autobind() - if err != nil { - return err - } - - c.injectBuiltins() - // prefetch all packages in one big packages.Load call - c.Packages.LoadAll(c.packageList()...) - - // check everything is valid on the way out - err = c.check() - if err != nil { - return err - } - - return nil -} - -func (c *Config) packageList() []string { - pkgs := []string{ - "github.com/99designs/gqlgen/graphql", - "github.com/99designs/gqlgen/graphql/introspection", - } - pkgs = append(pkgs, c.Models.ReferencedPackages()...) - pkgs = append(pkgs, c.AutoBind...) - return pkgs -} - -func (c *Config) ReloadAllPackages() { - c.Packages.ReloadAll(c.packageList()...) -} - -func (c *Config) injectTypesFromSchema() error { - c.Directives["goModel"] = DirectiveConfig{ - SkipRuntime: true, - } - - c.Directives["goField"] = DirectiveConfig{ - SkipRuntime: true, - } - - c.Directives["goTag"] = DirectiveConfig{ - SkipRuntime: true, - } - - for _, schemaType := range c.Schema.Types { - if schemaType == c.Schema.Query || schemaType == c.Schema.Mutation || schemaType == c.Schema.Subscription { - continue - } - - if bd := schemaType.Directives.ForName("goModel"); bd != nil { - if ma := bd.Arguments.ForName("model"); ma != nil { - if mv, err := ma.Value.Value(nil); err == nil { - c.Models.Add(schemaType.Name, mv.(string)) - } - } - if ma := bd.Arguments.ForName("models"); ma != nil { - if mvs, err := ma.Value.Value(nil); err == nil { - for _, mv := range mvs.([]interface{}) { - c.Models.Add(schemaType.Name, mv.(string)) - } - } - } - } - - if schemaType.Kind == ast.Object || schemaType.Kind == ast.InputObject { - for _, field := range schemaType.Fields { - if fd := field.Directives.ForName("goField"); fd != nil { - forceResolver := c.Models[schemaType.Name].Fields[field.Name].Resolver - fieldName := c.Models[schemaType.Name].Fields[field.Name].FieldName - - if ra := fd.Arguments.ForName("forceResolver"); ra != nil { - if fr, err := ra.Value.Value(nil); err == nil { - forceResolver = fr.(bool) - } - } - - if na := fd.Arguments.ForName("name"); na != nil { - if fr, err := na.Value.Value(nil); err == nil { - fieldName = fr.(string) - } - } - - if c.Models[schemaType.Name].Fields == nil { - c.Models[schemaType.Name] = TypeMapEntry{ - Model: c.Models[schemaType.Name].Model, - Fields: map[string]TypeMapField{}, - } - } - - c.Models[schemaType.Name].Fields[field.Name] = TypeMapField{ - FieldName: fieldName, - Resolver: forceResolver, - } - } - } - } - } - - return nil -} - -type TypeMapEntry struct { - Model StringList `yaml:"model"` - Fields map[string]TypeMapField `yaml:"fields,omitempty"` -} - -type TypeMapField struct { - Resolver bool `yaml:"resolver"` - FieldName string `yaml:"fieldName"` - GeneratedMethod string `yaml:"-"` -} - -type StringList []string - -func (a *StringList) UnmarshalYAML(unmarshal func(interface{}) error) error { - var single string - err := unmarshal(&single) - if err == nil { - *a = []string{single} - return nil - } - - var multi []string - err = unmarshal(&multi) - if err != nil { - return err - } - - *a = multi - return nil -} - -func (a StringList) Has(file string) bool { - for _, existing := range a { - if existing == file { - return true - } - } - return false -} - -func (c *Config) check() error { - if c.Models == nil { - c.Models = TypeMap{} - } - - type FilenamePackage struct { - Filename string - Package string - Declaree string - } - - fileList := map[string][]FilenamePackage{} - - if err := c.Models.Check(); err != nil { - return fmt.Errorf("config.models: %w", err) - } - if err := c.Exec.Check(); err != nil { - return fmt.Errorf("config.exec: %w", err) - } - fileList[c.Exec.ImportPath()] = append(fileList[c.Exec.ImportPath()], FilenamePackage{ - Filename: c.Exec.Filename, - Package: c.Exec.Package, - Declaree: "exec", - }) - - if c.Model.IsDefined() { - if err := c.Model.Check(); err != nil { - return fmt.Errorf("config.model: %w", err) - } - fileList[c.Model.ImportPath()] = append(fileList[c.Model.ImportPath()], FilenamePackage{ - Filename: c.Model.Filename, - Package: c.Model.Package, - Declaree: "model", - }) - } - if c.Resolver.IsDefined() { - if err := c.Resolver.Check(); err != nil { - return fmt.Errorf("config.resolver: %w", err) - } - fileList[c.Resolver.ImportPath()] = append(fileList[c.Resolver.ImportPath()], FilenamePackage{ - Filename: c.Resolver.Filename, - Package: c.Resolver.Package, - Declaree: "resolver", - }) - } - if c.Federation.IsDefined() { - if err := c.Federation.Check(); err != nil { - return fmt.Errorf("config.federation: %w", err) - } - fileList[c.Federation.ImportPath()] = append(fileList[c.Federation.ImportPath()], FilenamePackage{ - Filename: c.Federation.Filename, - Package: c.Federation.Package, - Declaree: "federation", - }) - if c.Federation.ImportPath() != c.Exec.ImportPath() { - return fmt.Errorf("federation and exec must be in the same package") - } - } - if c.Federated { - return fmt.Errorf("federated has been removed, instead use\nfederation:\n filename: path/to/federated.go") - } - - for importPath, pkg := range fileList { - for _, file1 := range pkg { - for _, file2 := range pkg { - if file1.Package != file2.Package { - return fmt.Errorf("%s and %s define the same import path (%s) with different package names (%s vs %s)", - file1.Declaree, - file2.Declaree, - importPath, - file1.Package, - file2.Package, - ) - } - } - } - } - - return nil -} - -type TypeMap map[string]TypeMapEntry - -func (tm TypeMap) Exists(typeName string) bool { - _, ok := tm[typeName] - return ok -} - -func (tm TypeMap) UserDefined(typeName string) bool { - m, ok := tm[typeName] - return ok && len(m.Model) > 0 -} - -func (tm TypeMap) Check() error { - for typeName, entry := range tm { - for _, model := range entry.Model { - if strings.LastIndex(model, ".") < strings.LastIndex(model, "/") { - return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model) - } - } - } - return nil -} - -func (tm TypeMap) ReferencedPackages() []string { - var pkgs []string - - for _, typ := range tm { - for _, model := range typ.Model { - if model == "map[string]interface{}" || model == "interface{}" { - continue - } - pkg, _ := code.PkgAndType(model) - if pkg == "" || inStrSlice(pkgs, pkg) { - continue - } - pkgs = append(pkgs, code.QualifyPackagePath(pkg)) - } - } - - sort.Slice(pkgs, func(i, j int) bool { - return pkgs[i] > pkgs[j] - }) - return pkgs -} - -func (tm TypeMap) Add(name string, goType string) { - modelCfg := tm[name] - modelCfg.Model = append(modelCfg.Model, goType) - tm[name] = modelCfg -} - -type DirectiveConfig struct { - SkipRuntime bool `yaml:"skip_runtime"` -} - -func inStrSlice(haystack []string, needle string) bool { - for _, v := range haystack { - if needle == v { - return true - } - } - - return false -} - -// findCfg searches for the config file in this directory and all parents up the tree -// looking for the closest match -func findCfg() (string, error) { - dir, err := os.Getwd() - if err != nil { - return "", fmt.Errorf("unable to get working dir to findCfg: %w", err) - } - - cfg := findCfgInDir(dir) - - for cfg == "" && dir != filepath.Dir(dir) { - dir = filepath.Dir(dir) - cfg = findCfgInDir(dir) - } - - if cfg == "" { - return "", os.ErrNotExist - } - - return cfg, nil -} - -func findCfgInDir(dir string) string { - for _, cfgName := range cfgFilenames { - path := filepath.Join(dir, cfgName) - if _, err := os.Stat(path); err == nil { - return path - } - } - return "" -} - -func (c *Config) autobind() error { - if len(c.AutoBind) == 0 { - return nil - } - - ps := c.Packages.LoadAll(c.AutoBind...) - - for _, t := range c.Schema.Types { - if c.Models.UserDefined(t.Name) { - continue - } - - for i, p := range ps { - if p == nil || p.Module == nil { - return fmt.Errorf("unable to load %s - make sure you're using an import path to a package that exists", c.AutoBind[i]) - } - if t := p.Types.Scope().Lookup(t.Name); t != nil { - c.Models.Add(t.Name(), t.Pkg().Path()+"."+t.Name()) - break - } - } - } - - for i, t := range c.Models { - for j, m := range t.Model { - pkg, typename := code.PkgAndType(m) - - // skip anything that looks like an import path - if strings.Contains(pkg, "/") { - continue - } - - for _, p := range ps { - if p.Name != pkg { - continue - } - if t := p.Types.Scope().Lookup(typename); t != nil { - c.Models[i].Model[j] = t.Pkg().Path() + "." + t.Name() - break - } - } - } - } - - return nil -} - -func (c *Config) injectBuiltins() { - builtins := TypeMap{ - "__Directive": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Directive"}}, - "__DirectiveLocation": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, - "__Type": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Type"}}, - "__TypeKind": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, - "__Field": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Field"}}, - "__EnumValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.EnumValue"}}, - "__InputValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.InputValue"}}, - "__Schema": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Schema"}}, - "Float": {Model: StringList{"github.com/99designs/gqlgen/graphql.FloatContext"}}, - "String": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, - "Boolean": {Model: StringList{"github.com/99designs/gqlgen/graphql.Boolean"}}, - "Int": {Model: StringList{ - "github.com/99designs/gqlgen/graphql.Int", - "github.com/99designs/gqlgen/graphql.Int32", - "github.com/99designs/gqlgen/graphql.Int64", - }}, - "ID": { - Model: StringList{ - "github.com/99designs/gqlgen/graphql.ID", - "github.com/99designs/gqlgen/graphql.IntID", - }, - }, - } - - for typeName, entry := range builtins { - if !c.Models.Exists(typeName) { - c.Models[typeName] = entry - } - } - - // These are additional types that are injected if defined in the schema as scalars. - extraBuiltins := TypeMap{ - "Time": {Model: StringList{"github.com/99designs/gqlgen/graphql.Time"}}, - "Map": {Model: StringList{"github.com/99designs/gqlgen/graphql.Map"}}, - "Upload": {Model: StringList{"github.com/99designs/gqlgen/graphql.Upload"}}, - "Any": {Model: StringList{"github.com/99designs/gqlgen/graphql.Any"}}, - } - - for typeName, entry := range extraBuiltins { - if t, ok := c.Schema.Types[typeName]; !c.Models.Exists(typeName) && ok && t.Kind == ast.Scalar { - c.Models[typeName] = entry - } - } -} - -func (c *Config) LoadSchema() error { - if c.Packages != nil { - c.Packages = &code.Packages{} - } - - if err := c.check(); err != nil { - return err - } - - schema, err := gqlparser.LoadSchema(c.Sources...) - if err != nil { - return err - } - - if schema.Query == nil { - schema.Query = &ast.Definition{ - Kind: ast.Object, - Name: "Query", - } - schema.Types["Query"] = schema.Query - } - - c.Schema = schema - return nil -} - -func abs(path string) string { - absPath, err := filepath.Abs(path) - if err != nil { - panic(err) - } - return filepath.ToSlash(absPath) -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/exec.go b/vendor/github.com/99designs/gqlgen/codegen/config/exec.go deleted file mode 100644 index fe1dccd21da..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/config/exec.go +++ /dev/null @@ -1,97 +0,0 @@ -package config - -import ( - "fmt" - "go/types" - "path/filepath" - "strings" - - "github.com/99designs/gqlgen/internal/code" -) - -type ExecConfig struct { - Package string `yaml:"package,omitempty"` - Layout ExecLayout `yaml:"layout,omitempty"` // Default: single-file - - // Only for single-file layout: - Filename string `yaml:"filename,omitempty"` - - // Only for follow-schema layout: - FilenameTemplate string `yaml:"filename_template,omitempty"` // String template with {name} as placeholder for base name. - DirName string `yaml:"dir"` -} - -type ExecLayout string - -var ( - // Write all generated code to a single file. - ExecLayoutSingleFile ExecLayout = "single-file" - // Write generated code to a directory, generating one Go source file for each GraphQL schema file. - ExecLayoutFollowSchema ExecLayout = "follow-schema" -) - -func (r *ExecConfig) Check() error { - if r.Layout == "" { - r.Layout = ExecLayoutSingleFile - } - - switch r.Layout { - case ExecLayoutSingleFile: - if r.Filename == "" { - return fmt.Errorf("filename must be specified when using single-file layout") - } - if !strings.HasSuffix(r.Filename, ".go") { - return fmt.Errorf("filename should be path to a go source file when using single-file layout") - } - r.Filename = abs(r.Filename) - case ExecLayoutFollowSchema: - if r.DirName == "" { - return fmt.Errorf("dir must be specified when using follow-schema layout") - } - r.DirName = abs(r.DirName) - default: - return fmt.Errorf("invalid layout %s", r.Layout) - } - - if strings.ContainsAny(r.Package, "./\\") { - return fmt.Errorf("package should be the output package name only, do not include the output filename") - } - - if r.Package == "" && r.Dir() != "" { - r.Package = code.NameForDir(r.Dir()) - } - - return nil -} - -func (r *ExecConfig) ImportPath() string { - if r.Dir() == "" { - return "" - } - return code.ImportPathForDir(r.Dir()) -} - -func (r *ExecConfig) Dir() string { - switch r.Layout { - case ExecLayoutSingleFile: - if r.Filename == "" { - return "" - } - return filepath.Dir(r.Filename) - case ExecLayoutFollowSchema: - return abs(r.DirName) - default: - panic("invalid layout " + r.Layout) - } -} - -func (r *ExecConfig) Pkg() *types.Package { - if r.Dir() == "" { - return nil - } - return types.NewPackage(r.ImportPath(), r.Package) -} - -func (r *ExecConfig) IsDefined() bool { - return r.Filename != "" || r.DirName != "" -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/package.go b/vendor/github.com/99designs/gqlgen/codegen/config/package.go deleted file mode 100644 index a9645938190..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/config/package.go +++ /dev/null @@ -1,62 +0,0 @@ -package config - -import ( - "fmt" - "go/types" - "path/filepath" - "strings" - - "github.com/99designs/gqlgen/internal/code" -) - -type PackageConfig struct { - Filename string `yaml:"filename,omitempty"` - Package string `yaml:"package,omitempty"` -} - -func (c *PackageConfig) ImportPath() string { - if !c.IsDefined() { - return "" - } - return code.ImportPathForDir(c.Dir()) -} - -func (c *PackageConfig) Dir() string { - if !c.IsDefined() { - return "" - } - return filepath.Dir(c.Filename) -} - -func (c *PackageConfig) Pkg() *types.Package { - if !c.IsDefined() { - return nil - } - return types.NewPackage(c.ImportPath(), c.Package) -} - -func (c *PackageConfig) IsDefined() bool { - return c.Filename != "" -} - -func (c *PackageConfig) Check() error { - if strings.ContainsAny(c.Package, "./\\") { - return fmt.Errorf("package should be the output package name only, do not include the output filename") - } - if c.Filename == "" { - return fmt.Errorf("filename must be specified") - } - if !strings.HasSuffix(c.Filename, ".go") { - return fmt.Errorf("filename should be path to a go source file") - } - - c.Filename = abs(c.Filename) - - // If Package is not set, first attempt to load the package at the output dir. If that fails - // fallback to just the base dir name of the output filename. - if c.Package == "" { - c.Package = code.NameForDir(c.Dir()) - } - - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/resolver.go b/vendor/github.com/99designs/gqlgen/codegen/config/resolver.go deleted file mode 100644 index cd03f188729..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/config/resolver.go +++ /dev/null @@ -1,100 +0,0 @@ -package config - -import ( - "fmt" - "go/types" - "path/filepath" - "strings" - - "github.com/99designs/gqlgen/internal/code" -) - -type ResolverConfig struct { - Filename string `yaml:"filename,omitempty"` - FilenameTemplate string `yaml:"filename_template,omitempty"` - Package string `yaml:"package,omitempty"` - Type string `yaml:"type,omitempty"` - Layout ResolverLayout `yaml:"layout,omitempty"` - DirName string `yaml:"dir"` -} - -type ResolverLayout string - -var ( - LayoutSingleFile ResolverLayout = "single-file" - LayoutFollowSchema ResolverLayout = "follow-schema" -) - -func (r *ResolverConfig) Check() error { - if r.Layout == "" { - r.Layout = LayoutSingleFile - } - if r.Type == "" { - r.Type = "Resolver" - } - - switch r.Layout { - case LayoutSingleFile: - if r.Filename == "" { - return fmt.Errorf("filename must be specified with layout=%s", r.Layout) - } - if !strings.HasSuffix(r.Filename, ".go") { - return fmt.Errorf("filename should be path to a go source file with layout=%s", r.Layout) - } - r.Filename = abs(r.Filename) - case LayoutFollowSchema: - if r.DirName == "" { - return fmt.Errorf("dirname must be specified with layout=%s", r.Layout) - } - r.DirName = abs(r.DirName) - if r.Filename == "" { - r.Filename = filepath.Join(r.DirName, "resolver.go") - } else { - r.Filename = abs(r.Filename) - } - default: - return fmt.Errorf("invalid layout %s. must be %s or %s", r.Layout, LayoutSingleFile, LayoutFollowSchema) - } - - if strings.ContainsAny(r.Package, "./\\") { - return fmt.Errorf("package should be the output package name only, do not include the output filename") - } - - if r.Package == "" && r.Dir() != "" { - r.Package = code.NameForDir(r.Dir()) - } - - return nil -} - -func (r *ResolverConfig) ImportPath() string { - if r.Dir() == "" { - return "" - } - return code.ImportPathForDir(r.Dir()) -} - -func (r *ResolverConfig) Dir() string { - switch r.Layout { - case LayoutSingleFile: - if r.Filename == "" { - return "" - } - return filepath.Dir(r.Filename) - case LayoutFollowSchema: - return r.DirName - default: - panic("invalid layout " + r.Layout) - } -} - -func (r *ResolverConfig) Pkg() *types.Package { - if r.Dir() == "" { - return nil - } - return types.NewPackage(r.ImportPath(), r.Package) -} - -func (r *ResolverConfig) IsDefined() bool { - return r.Filename != "" || r.DirName != "" -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/data.go b/vendor/github.com/99designs/gqlgen/codegen/data.go deleted file mode 100644 index e12fb104730..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/data.go +++ /dev/null @@ -1,185 +0,0 @@ -package codegen - -import ( - "fmt" - "sort" - - "github.com/vektah/gqlparser/v2/ast" - - "github.com/99designs/gqlgen/codegen/config" -) - -// Data is a unified model of the code to be generated. Plugins may modify this structure to do things like implement -// resolvers or directives automatically (eg grpc, validation) -type Data struct { - Config *config.Config - Schema *ast.Schema - // If a schema is broken up into multiple Data instance, each representing part of the schema, - // AllDirectives should contain the directives for the entire schema. Directives() can - // then be used to get the directives that were defined in this Data instance's sources. - // If a single Data instance is used for the entire schema, AllDirectives and Directives() - // will be identical. - // AllDirectives should rarely be used directly. - AllDirectives DirectiveList - Objects Objects - Inputs Objects - Interfaces map[string]*Interface - ReferencedTypes map[string]*config.TypeReference - ComplexityRoots map[string]*Object - - QueryRoot *Object - MutationRoot *Object - SubscriptionRoot *Object -} - -type builder struct { - Config *config.Config - Schema *ast.Schema - Binder *config.Binder - Directives map[string]*Directive -} - -// Get only the directives which are defined in the config's sources. -func (d *Data) Directives() DirectiveList { - res := DirectiveList{} - for k, directive := range d.AllDirectives { - for _, s := range d.Config.Sources { - if directive.Position.Src.Name == s.Name { - res[k] = directive - break - } - } - } - return res -} - -func BuildData(cfg *config.Config) (*Data, error) { - // We reload all packages to allow packages to be compared correctly. - cfg.ReloadAllPackages() - - b := builder{ - Config: cfg, - Schema: cfg.Schema, - } - - b.Binder = b.Config.NewBinder() - - var err error - b.Directives, err = b.buildDirectives() - if err != nil { - return nil, err - } - - dataDirectives := make(map[string]*Directive) - for name, d := range b.Directives { - if !d.Builtin { - dataDirectives[name] = d - } - } - - s := Data{ - Config: cfg, - AllDirectives: dataDirectives, - Schema: b.Schema, - Interfaces: map[string]*Interface{}, - } - - for _, schemaType := range b.Schema.Types { - switch schemaType.Kind { - case ast.Object: - obj, err := b.buildObject(schemaType) - if err != nil { - return nil, fmt.Errorf("unable to build object definition: %w", err) - } - - s.Objects = append(s.Objects, obj) - case ast.InputObject: - input, err := b.buildObject(schemaType) - if err != nil { - return nil, fmt.Errorf("unable to build input definition: %w", err) - } - - s.Inputs = append(s.Inputs, input) - - case ast.Union, ast.Interface: - s.Interfaces[schemaType.Name], err = b.buildInterface(schemaType) - if err != nil { - return nil, fmt.Errorf("unable to bind to interface: %w", err) - } - } - } - - if s.Schema.Query != nil { - s.QueryRoot = s.Objects.ByName(s.Schema.Query.Name) - } else { - return nil, fmt.Errorf("query entry point missing") - } - - if s.Schema.Mutation != nil { - s.MutationRoot = s.Objects.ByName(s.Schema.Mutation.Name) - } - - if s.Schema.Subscription != nil { - s.SubscriptionRoot = s.Objects.ByName(s.Schema.Subscription.Name) - } - - if err := b.injectIntrospectionRoots(&s); err != nil { - return nil, err - } - - s.ReferencedTypes = b.buildTypes() - - sort.Slice(s.Objects, func(i, j int) bool { - return s.Objects[i].Definition.Name < s.Objects[j].Definition.Name - }) - - sort.Slice(s.Inputs, func(i, j int) bool { - return s.Inputs[i].Definition.Name < s.Inputs[j].Definition.Name - }) - - if b.Binder.SawInvalid { - // if we have a syntax error, show it - err := cfg.Packages.Errors() - if len(err) > 0 { - return nil, err - } - - // 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") - } - - return &s, nil -} - -func (b *builder) injectIntrospectionRoots(s *Data) error { - obj := s.Objects.ByName(b.Schema.Query.Name) - if obj == nil { - return fmt.Errorf("root query type must be defined") - } - - __type, err := b.buildField(obj, &ast.FieldDefinition{ - Name: "__type", - Type: ast.NamedType("__Type", nil), - Arguments: []*ast.ArgumentDefinition{ - { - Name: "name", - Type: ast.NonNullNamedType("String", nil), - }, - }, - }) - if err != nil { - return err - } - - __schema, err := b.buildField(obj, &ast.FieldDefinition{ - Name: "__schema", - Type: ast.NamedType("__Schema", nil), - }) - if err != nil { - return err - } - - obj.Fields = append(obj.Fields, __type, __schema) - - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive.go b/vendor/github.com/99designs/gqlgen/codegen/directive.go deleted file mode 100644 index 973061129a2..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/directive.go +++ /dev/null @@ -1,174 +0,0 @@ -package codegen - -import ( - "fmt" - "strconv" - "strings" - - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -type DirectiveList map[string]*Directive - -// LocationDirectives filter directives by location -func (dl DirectiveList) LocationDirectives(location string) DirectiveList { - return locationDirectives(dl, ast.DirectiveLocation(location)) -} - -type Directive struct { - *ast.DirectiveDefinition - Name string - Args []*FieldArgument - Builtin bool -} - -// IsLocation check location directive -func (d *Directive) IsLocation(location ...ast.DirectiveLocation) bool { - for _, l := range d.Locations { - for _, a := range location { - if l == a { - return true - } - } - } - - return false -} - -func locationDirectives(directives DirectiveList, location ...ast.DirectiveLocation) map[string]*Directive { - mDirectives := make(map[string]*Directive) - for name, d := range directives { - if d.IsLocation(location...) { - mDirectives[name] = d - } - } - return mDirectives -} - -func (b *builder) buildDirectives() (map[string]*Directive, error) { - directives := make(map[string]*Directive, len(b.Schema.Directives)) - - for name, dir := range b.Schema.Directives { - if _, ok := directives[name]; ok { - return nil, fmt.Errorf("directive with name %s already exists", name) - } - - var args []*FieldArgument - for _, arg := range dir.Arguments { - tr, err := b.Binder.TypeReference(arg.Type, nil) - if err != nil { - return nil, err - } - - newArg := &FieldArgument{ - ArgumentDefinition: arg, - TypeReference: tr, - VarName: templates.ToGoPrivate(arg.Name), - } - - if arg.DefaultValue != nil { - var err error - newArg.Default, err = arg.DefaultValue.Value(nil) - if err != nil { - return nil, fmt.Errorf("default value for directive argument %s(%s) is not valid: %w", dir.Name, arg.Name, err) - } - } - args = append(args, newArg) - } - - directives[name] = &Directive{ - DirectiveDefinition: dir, - Name: name, - Args: args, - Builtin: b.Config.Directives[name].SkipRuntime, - } - } - - return directives, nil -} - -func (b *builder) getDirectives(list ast.DirectiveList) ([]*Directive, error) { - dirs := make([]*Directive, len(list)) - for i, d := range list { - argValues := make(map[string]interface{}, len(d.Arguments)) - for _, da := range d.Arguments { - val, err := da.Value.Value(nil) - if err != nil { - return nil, err - } - argValues[da.Name] = val - } - def, ok := b.Directives[d.Name] - if !ok { - return nil, fmt.Errorf("directive %s not found", d.Name) - } - - var args []*FieldArgument - for _, a := range def.Args { - value := a.Default - if argValue, ok := argValues[a.Name]; ok { - value = argValue - } - args = append(args, &FieldArgument{ - ArgumentDefinition: a.ArgumentDefinition, - Value: value, - VarName: a.VarName, - TypeReference: a.TypeReference, - }) - } - dirs[i] = &Directive{ - Name: d.Name, - Args: args, - DirectiveDefinition: list[i].Definition, - Builtin: b.Config.Directives[d.Name].SkipRuntime, - } - - } - - return dirs, nil -} - -func (d *Directive) ArgsFunc() string { - if len(d.Args) == 0 { - return "" - } - - return "dir_" + d.Name + "_args" -} - -func (d *Directive) CallArgs() string { - args := []string{"ctx", "obj", "n"} - - for _, arg := range d.Args { - args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")") - } - - return strings.Join(args, ", ") -} - -func (d *Directive) ResolveArgs(obj string, next int) string { - args := []string{"ctx", obj, fmt.Sprintf("directive%d", next)} - - for _, arg := range d.Args { - dArg := arg.VarName - if arg.Value == nil && arg.Default == nil { - dArg = "nil" - } - - args = append(args, dArg) - } - - return strings.Join(args, ", ") -} - -func (d *Directive) Declaration() string { - res := ucFirst(d.Name) + " func(ctx context.Context, obj interface{}, next graphql.Resolver" - - for _, arg := range d.Args { - res += fmt.Sprintf(", %s %s", templates.ToGoPrivate(arg.Name), templates.CurrentImports.LookupType(arg.TypeReference.GO)) - } - - res += ") (res interface{}, err error)" - return res -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/directives.gotpl b/vendor/github.com/99designs/gqlgen/codegen/directives.gotpl deleted file mode 100644 index e6d2455f6c8..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/directives.gotpl +++ /dev/null @@ -1,149 +0,0 @@ -{{ define "implDirectives" }}{{ $in := .DirectiveObjName }} - {{- range $i, $directive := .ImplDirectives -}} - directive{{add $i 1}} := func(ctx context.Context) (interface{}, error) { - {{- range $arg := $directive.Args }} - {{- if notNil "Value" $arg }} - {{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Value | dump }}) - if err != nil{ - return nil, err - } - {{- else if notNil "Default" $arg }} - {{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Default | dump }}) - if err != nil{ - return nil, err - } - {{- end }} - {{- end }} - if ec.directives.{{$directive.Name|ucFirst}} == nil { - return nil, errors.New("directive {{$directive.Name}} is not implemented") - } - return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs $in $i }}) - } - {{ end -}} -{{ end }} - -{{define "queryDirectives"}} - for _, d := range obj.Directives { - switch d.Name { - {{- range $directive := . }} - case "{{$directive.Name}}": - {{- if $directive.Args }} - rawArgs := d.ArgumentMap(ec.Variables) - args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - {{- end }} - n := next - next = func(ctx context.Context) (interface{}, error) { - if ec.directives.{{$directive.Name|ucFirst}} == nil { - return nil, errors.New("directive {{$directive.Name}} is not implemented") - } - return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}}) - } - {{- end }} - } - } - tmp, err := next(ctx) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if data, ok := tmp.(graphql.Marshaler); ok { - return data - } - ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp) - return graphql.Null -{{end}} - -{{ if .Directives.LocationDirectives "QUERY" }} -func (ec *executionContext) _queryMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) graphql.Marshaler { - {{ template "queryDirectives" .Directives.LocationDirectives "QUERY" }} -} -{{ end }} - -{{ if .Directives.LocationDirectives "MUTATION" }} -func (ec *executionContext) _mutationMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) graphql.Marshaler { - {{ template "queryDirectives" .Directives.LocationDirectives "MUTATION" }} -} -{{ 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 { - for _, d := range obj.Directives { - switch d.Name { - {{- range $directive := .Directives.LocationDirectives "SUBSCRIPTION" }} - case "{{$directive.Name}}": - {{- if $directive.Args }} - rawArgs := d.ArgumentMap(ec.Variables) - args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs) - if err != nil { - ec.Error(ctx, err) - return func() graphql.Marshaler { - return graphql.Null - } - } - {{- end }} - n := next - next = func(ctx context.Context) (interface{}, error) { - if ec.directives.{{$directive.Name|ucFirst}} == nil { - return nil, errors.New("directive {{$directive.Name}} is not implemented") - } - return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}}) - } - {{- end }} - } - } - tmp, err := next(ctx) - if err != nil { - ec.Error(ctx, err) - return func() graphql.Marshaler { - return graphql.Null - } - } - if data, ok := tmp.(func() graphql.Marshaler); ok { - return data - } - ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp) - return func() graphql.Marshaler { - return graphql.Null - } -} -{{ end }} - -{{ if .Directives.LocationDirectives "FIELD" }} - func (ec *executionContext) _fieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) interface{} { - {{- if .Directives.LocationDirectives "FIELD" }} - fc := graphql.GetFieldContext(ctx) - for _, d := range fc.Field.Directives { - switch d.Name { - {{- range $directive := .Directives.LocationDirectives "FIELD" }} - case "{{$directive.Name}}": - {{- if $directive.Args }} - rawArgs := d.ArgumentMap(ec.Variables) - args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs) - if err != nil { - ec.Error(ctx, err) - return nil - } - {{- end }} - n := next - next = func(ctx context.Context) (interface{}, error) { - if ec.directives.{{$directive.Name|ucFirst}} == nil { - return nil, errors.New("directive {{$directive.Name}} is not implemented") - } - return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}}) - } - {{- end }} - } - } - {{- end }} - res, err := ec.ResolverMiddleware(ctx, next) - if err != nil { - ec.Error(ctx, err) - return nil - } - return res - } -{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.go b/vendor/github.com/99designs/gqlgen/codegen/field.go deleted file mode 100644 index 867215e5b20..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/field.go +++ /dev/null @@ -1,556 +0,0 @@ -package codegen - -import ( - "errors" - "fmt" - "go/types" - "log" - "reflect" - "strconv" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -type Field struct { - *ast.FieldDefinition - - TypeReference *config.TypeReference - GoFieldType GoFieldType // The field type in go, if any - GoReceiverName string // The name of method & var receiver in go, if any - GoFieldName string // The name of the method or var in go, if any - IsResolver bool // Does this field need a resolver - Args []*FieldArgument // A list of arguments to be passed to this field - MethodHasContext bool // If this is bound to a go method, does the method also take a context - NoErr bool // If this is bound to a go method, does that method have an error as the second argument - VOkFunc bool // If this is bound to a go method, is it of shape (interface{}, bool) - Object *Object // A link back to the parent object - Default interface{} // The default value - Stream bool // does this field return a channel? - Directives []*Directive -} - -func (b *builder) buildField(obj *Object, field *ast.FieldDefinition) (*Field, error) { - dirs, err := b.getDirectives(field.Directives) - if err != nil { - return nil, err - } - - f := Field{ - FieldDefinition: field, - Object: obj, - Directives: dirs, - GoFieldName: templates.ToGo(field.Name), - GoFieldType: GoFieldVariable, - GoReceiverName: "obj", - } - - if field.DefaultValue != nil { - var err error - f.Default, err = field.DefaultValue.Value(nil) - if err != nil { - return nil, fmt.Errorf("default value %s is not valid: %w", field.Name, err) - } - } - - for _, arg := range field.Arguments { - newArg, err := b.buildArg(obj, arg) - if err != nil { - return nil, err - } - f.Args = append(f.Args, newArg) - } - - if err = b.bindField(obj, &f); err != nil { - f.IsResolver = true - if errors.Is(err, config.ErrTypeNotFound) { - return nil, err - } - log.Println(err.Error()) - } - - if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() { - f.TypeReference = b.Binder.PointerTo(f.TypeReference) - } - - return &f, nil -} - -func (b *builder) bindField(obj *Object, f *Field) (errret error) { - defer func() { - if f.TypeReference == nil { - tr, err := b.Binder.TypeReference(f.Type, nil) - if err != nil { - errret = err - } - f.TypeReference = tr - } - if f.TypeReference != nil { - dirs, err := b.getDirectives(f.TypeReference.Definition.Directives) - if err != nil { - errret = err - } - for _, dir := range obj.Directives { - if dir.IsLocation(ast.LocationInputObject) { - dirs = append(dirs, dir) - } - } - f.Directives = append(dirs, f.Directives...) - } - }() - - f.Stream = obj.Stream - - switch { - case f.Name == "__schema": - f.GoFieldType = GoFieldMethod - f.GoReceiverName = "ec" - f.GoFieldName = "introspectSchema" - return nil - case f.Name == "__type": - f.GoFieldType = GoFieldMethod - f.GoReceiverName = "ec" - f.GoFieldName = "introspectType" - return nil - case f.Name == "_entities": - f.GoFieldType = GoFieldMethod - f.GoReceiverName = "ec" - f.GoFieldName = "__resolve_entities" - f.MethodHasContext = true - f.NoErr = true - return nil - case f.Name == "_service": - f.GoFieldType = GoFieldMethod - f.GoReceiverName = "ec" - f.GoFieldName = "__resolve__service" - f.MethodHasContext = true - return nil - case obj.Root: - f.IsResolver = true - return nil - case b.Config.Models[obj.Name].Fields[f.Name].Resolver: - f.IsResolver = true - return nil - case obj.Type == config.MapType: - f.GoFieldType = GoFieldMap - return nil - case b.Config.Models[obj.Name].Fields[f.Name].FieldName != "": - f.GoFieldName = b.Config.Models[obj.Name].Fields[f.Name].FieldName - } - - target, err := b.findBindTarget(obj.Type.(*types.Named), f.GoFieldName) - if err != nil { - return err - } - - pos := b.Binder.ObjectPosition(target) - - switch target := target.(type) { - case nil: - objPos := b.Binder.TypePosition(obj.Type) - return fmt.Errorf( - "%s:%d adding resolver method for %s.%s, nothing matched", - objPos.Filename, - objPos.Line, - obj.Name, - f.Name, - ) - - case *types.Func: - sig := target.Type().(*types.Signature) - if sig.Results().Len() == 1 { - f.NoErr = true - } else if s := sig.Results(); s.Len() == 2 && s.At(1).Type().String() == "bool" { - f.VOkFunc = true - } else if sig.Results().Len() != 2 { - return fmt.Errorf("method has wrong number of args") - } - params := sig.Params() - // If the first argument is the context, remove it from the comparison and set - // the MethodHasContext flag so that the context will be passed to this model's method - if params.Len() > 0 && params.At(0).Type().String() == "context.Context" { - f.MethodHasContext = true - vars := make([]*types.Var, params.Len()-1) - for i := 1; i < params.Len(); i++ { - vars[i-1] = params.At(i) - } - params = types.NewTuple(vars...) - } - - // Try to match target function's arguments with GraphQL field arguments - newArgs, err := b.bindArgs(f, params) - if err != nil { - return fmt.Errorf("%s:%d: %w", pos.Filename, pos.Line, err) - } - - // Try to match target function's return types with GraphQL field return type - result := sig.Results().At(0) - tr, err := b.Binder.TypeReference(f.Type, result.Type()) - if err != nil { - return err - } - - // success, args and return type match. Bind to method - f.GoFieldType = GoFieldMethod - f.GoReceiverName = "obj" - f.GoFieldName = target.Name() - f.Args = newArgs - f.TypeReference = tr - - return nil - - case *types.Var: - tr, err := b.Binder.TypeReference(f.Type, target.Type()) - if err != nil { - return err - } - - // success, bind to var - f.GoFieldType = GoFieldVariable - f.GoReceiverName = "obj" - f.GoFieldName = target.Name() - f.TypeReference = tr - - return nil - default: - panic(fmt.Errorf("unknown bind target %T for %s", target, f.Name)) - } -} - -// findBindTarget attempts to match the name to a field or method on a Type -// with the following priorites: -// 1. Any Fields with a struct tag (see config.StructTag). Errors if more than one match is found -// 2. Any method or field with a matching name. Errors if more than one match is found -// 3. Same logic again for embedded fields -func (b *builder) findBindTarget(t types.Type, name string) (types.Object, error) { - // NOTE: a struct tag will override both methods and fields - // Bind to struct tag - found, err := b.findBindStructTagTarget(t, name) - if found != nil || err != nil { - return found, err - } - - // Search for a method to bind to - foundMethod, err := b.findBindMethodTarget(t, name) - if err != nil { - return nil, err - } - - // Search for a field to bind to - foundField, err := b.findBindFieldTarget(t, name) - if err != nil { - return nil, err - } - - switch { - case foundField == nil && foundMethod != nil: - // Bind to method - return foundMethod, nil - case foundField != nil && foundMethod == nil: - // Bind to field - return foundField, nil - case foundField != nil && foundMethod != nil: - // Error - return nil, fmt.Errorf("found more than one way to bind for %s", name) - } - - // Search embeds - return b.findBindEmbedsTarget(t, name) -} - -func (b *builder) findBindStructTagTarget(in types.Type, name string) (types.Object, error) { - if b.Config.StructTag == "" { - return nil, nil - } - - switch t := in.(type) { - case *types.Named: - return b.findBindStructTagTarget(t.Underlying(), name) - case *types.Struct: - var found types.Object - for i := 0; i < t.NumFields(); i++ { - field := t.Field(i) - if !field.Exported() || field.Embedded() { - continue - } - tags := reflect.StructTag(t.Tag(i)) - if val, ok := tags.Lookup(b.Config.StructTag); ok && equalFieldName(val, name) { - if found != nil { - return nil, fmt.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val) - } - - found = field - } - } - - return found, nil - } - - return nil, nil -} - -func (b *builder) findBindMethodTarget(in types.Type, name string) (types.Object, error) { - switch t := in.(type) { - case *types.Named: - if _, ok := t.Underlying().(*types.Interface); ok { - return b.findBindMethodTarget(t.Underlying(), name) - } - - return b.findBindMethoderTarget(t.Method, t.NumMethods(), name) - case *types.Interface: - // FIX-ME: Should use ExplicitMethod here? What's the difference? - return b.findBindMethoderTarget(t.Method, t.NumMethods(), name) - } - - return nil, nil -} - -func (b *builder) findBindMethoderTarget(methodFunc func(i int) *types.Func, methodCount int, name string) (types.Object, error) { - var found types.Object - for i := 0; i < methodCount; i++ { - method := methodFunc(i) - if !method.Exported() || !strings.EqualFold(method.Name(), name) { - continue - } - - if found != nil { - return nil, fmt.Errorf("found more than one matching method to bind for %s", name) - } - - found = method - } - - return found, nil -} - -func (b *builder) findBindFieldTarget(in types.Type, name string) (types.Object, error) { - switch t := in.(type) { - case *types.Named: - return b.findBindFieldTarget(t.Underlying(), name) - case *types.Struct: - var found types.Object - for i := 0; i < t.NumFields(); i++ { - field := t.Field(i) - if !field.Exported() || !equalFieldName(field.Name(), name) { - continue - } - - if found != nil { - return nil, fmt.Errorf("found more than one matching field to bind for %s", name) - } - - found = field - } - - return found, nil - } - - return nil, nil -} - -func (b *builder) findBindEmbedsTarget(in types.Type, name string) (types.Object, error) { - switch t := in.(type) { - case *types.Named: - return b.findBindEmbedsTarget(t.Underlying(), name) - case *types.Struct: - return b.findBindStructEmbedsTarget(t, name) - case *types.Interface: - return b.findBindInterfaceEmbedsTarget(t, name) - } - - return nil, nil -} - -func (b *builder) findBindStructEmbedsTarget(strukt *types.Struct, name string) (types.Object, error) { - var found types.Object - for i := 0; i < strukt.NumFields(); i++ { - field := strukt.Field(i) - if !field.Embedded() { - continue - } - - fieldType := field.Type() - if ptr, ok := fieldType.(*types.Pointer); ok { - fieldType = ptr.Elem() - } - - f, err := b.findBindTarget(fieldType, name) - if err != nil { - return nil, err - } - - if f != nil && found != nil { - return nil, fmt.Errorf("found more than one way to bind for %s", name) - } - - if f != nil { - found = f - } - } - - return found, nil -} - -func (b *builder) findBindInterfaceEmbedsTarget(iface *types.Interface, name string) (types.Object, error) { - var found types.Object - for i := 0; i < iface.NumEmbeddeds(); i++ { - embeddedType := iface.EmbeddedType(i) - - f, err := b.findBindTarget(embeddedType, name) - if err != nil { - return nil, err - } - - if f != nil && found != nil { - return nil, fmt.Errorf("found more than one way to bind for %s", name) - } - - if f != nil { - found = f - } - } - - return found, nil -} - -func (f *Field) HasDirectives() bool { - return len(f.ImplDirectives()) > 0 -} - -func (f *Field) DirectiveObjName() string { - if f.Object.Root { - return "nil" - } - return f.GoReceiverName -} - -func (f *Field) ImplDirectives() []*Directive { - var d []*Directive - loc := ast.LocationFieldDefinition - if f.Object.IsInputType() { - loc = ast.LocationInputFieldDefinition - } - for i := range f.Directives { - if !f.Directives[i].Builtin && - (f.Directives[i].IsLocation(loc, ast.LocationObject) || f.Directives[i].IsLocation(loc, ast.LocationInputObject)) { - d = append(d, f.Directives[i]) - } - } - return d -} - -func (f *Field) IsReserved() bool { - return strings.HasPrefix(f.Name, "__") -} - -func (f *Field) IsMethod() bool { - return f.GoFieldType == GoFieldMethod -} - -func (f *Field) IsVariable() bool { - return f.GoFieldType == GoFieldVariable -} - -func (f *Field) IsMap() bool { - return f.GoFieldType == GoFieldMap -} - -func (f *Field) IsConcurrent() bool { - if f.Object.DisableConcurrency { - return false - } - return f.MethodHasContext || f.IsResolver -} - -func (f *Field) GoNameUnexported() string { - return templates.ToGoPrivate(f.Name) -} - -func (f *Field) ShortInvocation() string { - if f.Object.Kind == ast.InputObject { - return fmt.Sprintf("%s().%s(ctx, &it, data)", strings.Title(f.Object.Definition.Name), f.GoFieldName) - } - return fmt.Sprintf("%s().%s(%s)", strings.Title(f.Object.Definition.Name), f.GoFieldName, f.CallArgs()) -} - -func (f *Field) ArgsFunc() string { - if len(f.Args) == 0 { - return "" - } - - return "field_" + f.Object.Definition.Name + "_" + f.Name + "_args" -} - -func (f *Field) ResolverType() string { - if !f.IsResolver { - return "" - } - - return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs()) -} - -func (f *Field) ShortResolverDeclaration() string { - if f.Object.Kind == ast.InputObject { - return fmt.Sprintf("(ctx context.Context, obj %s, data %s) error", - templates.CurrentImports.LookupType(f.Object.Reference()), - templates.CurrentImports.LookupType(f.TypeReference.GO), - ) - } - - res := "(ctx context.Context" - - if !f.Object.Root { - res += fmt.Sprintf(", obj %s", templates.CurrentImports.LookupType(f.Object.Reference())) - } - for _, arg := range f.Args { - res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO)) - } - - result := templates.CurrentImports.LookupType(f.TypeReference.GO) - if f.Object.Stream { - result = "<-chan " + result - } - - res += fmt.Sprintf(") (%s, error)", result) - return res -} - -func (f *Field) ComplexitySignature() string { - res := "func(childComplexity int" - for _, arg := range f.Args { - res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO)) - } - res += ") int" - return res -} - -func (f *Field) ComplexityArgs() string { - args := make([]string, len(f.Args)) - for i, arg := range f.Args { - args[i] = "args[" + strconv.Quote(arg.Name) + "].(" + templates.CurrentImports.LookupType(arg.TypeReference.GO) + ")" - } - - return strings.Join(args, ", ") -} - -func (f *Field) CallArgs() string { - args := make([]string, 0, len(f.Args)+2) - - if f.IsResolver { - args = append(args, "rctx") - - if !f.Object.Root { - args = append(args, "obj") - } - } else if f.MethodHasContext { - args = append(args, "ctx") - } - - for _, arg := range f.Args { - args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")") - } - - return strings.Join(args, ", ") -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.gotpl b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl deleted file mode 100644 index 0c6becaea6a..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/field.gotpl +++ /dev/null @@ -1,129 +0,0 @@ -{{- 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) { - {{- $null := "graphql.Null" }} - {{- if $object.Stream }} - {{- $null = "nil" }} - {{- end }} - 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 }} - }) - {{ else }} - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - {{ template "field" $field }} - }) - if err != nil { - ec.Error(ctx, err) - return {{ $null }} - } - {{- end }} - if resTmp == nil { - {{- if $field.TypeReference.GQL.NonNull }} - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - {{- end }} - return {{ $null }} - } - {{- if $object.Stream }} - return func() graphql.Marshaler { - 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{'}'}) - }) - } - {{- else }} - res := resTmp.({{$field.TypeReference.GO | ref}}) - fc.Result = res - return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res) - {{- end }} -} - -{{- end }}{{- end}} - -{{ define "field" }} - {{- if .HasDirectives -}} - directive0 := func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - {{ template "fieldDefinition" . }} - } - {{ template "implDirectives" . }} - tmp, err := directive{{.ImplDirectives|len}}(rctx) - if err != nil { - return nil, graphql.ErrorOnPath(ctx, err) - } - if tmp == nil { - return nil, nil - } - if data, ok := tmp.({{if .Stream}}<-chan {{end}}{{ .TypeReference.GO | ref }}) ; ok { - return data, nil - } - return nil, fmt.Errorf(`unexpected type %T from directive, should be {{if .Stream}}<-chan {{end}}{{ .TypeReference.GO }}`, tmp) - {{- else -}} - ctx = rctx // use context from middleware stack in children - {{ template "fieldDefinition" . }} - {{- end -}} -{{ end }} - -{{ define "fieldDefinition" }} - {{- if .IsResolver -}} - return ec.resolvers.{{ .ShortInvocation }} - {{- else if .IsMap -}} - switch v := {{.GoReceiverName}}[{{.Name|quote}}].(type) { - case {{if .Stream}}<-chan {{end}}{{.TypeReference.GO | ref}}: - return v, nil - case {{if .Stream}}<-chan {{end}}{{.TypeReference.Elem.GO | ref}}: - return &v, nil - case nil: - return ({{.TypeReference.GO | ref}})(nil), nil - default: - return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ .Name | quote}}) - } - {{- else if .IsMethod -}} - {{- if .VOkFunc -}} - v, ok := {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}) - if !ok { - return nil, nil - } - return v, nil - {{- else if .NoErr -}} - return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}), nil - {{- else -}} - return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}) - {{- end -}} - {{- else if .IsVariable -}} - return {{.GoReceiverName}}.{{.GoFieldName}}, nil - {{- end }} -{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/generate.go b/vendor/github.com/99designs/gqlgen/codegen/generate.go deleted file mode 100644 index 77bbf575111..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/generate.go +++ /dev/null @@ -1,213 +0,0 @@ -package codegen - -import ( - "errors" - "fmt" - "io/ioutil" - "path/filepath" - "runtime" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -func GenerateCode(data *Data) error { - if !data.Config.Exec.IsDefined() { - return fmt.Errorf("missing exec config") - } - - switch data.Config.Exec.Layout { - case config.ExecLayoutSingleFile: - return generateSingleFile(data) - case config.ExecLayoutFollowSchema: - return generatePerSchema(data) - } - - return fmt.Errorf("unrecognized exec layout %s", data.Config.Exec.Layout) -} - -func generateSingleFile(data *Data) error { - return templates.Render(templates.Options{ - PackageName: data.Config.Exec.Package, - Filename: data.Config.Exec.Filename, - Data: data, - RegionTags: true, - GeneratedHeader: true, - Packages: data.Config.Packages, - }) -} - -func generatePerSchema(data *Data) error { - err := generateRootFile(data) - if err != nil { - return err - } - - builds := map[string]*Data{} - - err = addObjects(data, &builds) - if err != nil { - return err - } - - err = addInputs(data, &builds) - if err != nil { - return err - } - - err = addInterfaces(data, &builds) - if err != nil { - return err - } - - err = addReferencedTypes(data, &builds) - if err != nil { - return err - } - - for filename, build := range builds { - if filename == "" { - continue - } - - dir := data.Config.Exec.DirName - path := filepath.Join(dir, filename) - - err = templates.Render(templates.Options{ - PackageName: data.Config.Exec.Package, - Filename: path, - Data: build, - RegionTags: true, - GeneratedHeader: true, - Packages: data.Config.Packages, - }) - if err != nil { - return err - } - } - - return nil -} - -func filename(p *ast.Position, config *config.Config) string { - name := "common!" - if p != nil && p.Src != nil { - gqlname := filepath.Base(p.Src.Name) - ext := filepath.Ext(p.Src.Name) - name = strings.TrimSuffix(gqlname, ext) - } - - filenameTempl := config.Exec.FilenameTemplate - if filenameTempl == "" { - filenameTempl = "{name}.generated.go" - } - - return strings.ReplaceAll(filenameTempl, "{name}", name) -} - -func addBuild(filename string, p *ast.Position, data *Data, builds *map[string]*Data) { - buildConfig := *data.Config - if p != nil { - buildConfig.Sources = []*ast.Source{p.Src} - } - - (*builds)[filename] = &Data{ - Config: &buildConfig, - QueryRoot: data.QueryRoot, - MutationRoot: data.MutationRoot, - SubscriptionRoot: data.SubscriptionRoot, - AllDirectives: data.AllDirectives, - } -} - -// Root file contains top-level definitions that should not be duplicated across the generated -// files for each schema file. -func generateRootFile(data *Data) error { - dir := data.Config.Exec.DirName - path := filepath.Join(dir, "root_.generated.go") - - _, thisFile, _, _ := runtime.Caller(0) - rootDir := filepath.Dir(thisFile) - templatePath := filepath.Join(rootDir, "root_.gotpl") - templateBytes, err := ioutil.ReadFile(templatePath) - if err != nil { - return err - } - template := string(templateBytes) - - return templates.Render(templates.Options{ - PackageName: data.Config.Exec.Package, - Template: template, - Filename: path, - Data: data, - RegionTags: false, - GeneratedHeader: true, - Packages: data.Config.Packages, - }) -} - -func addObjects(data *Data, builds *map[string]*Data) error { - for _, o := range data.Objects { - filename := filename(o.Position, data.Config) - if (*builds)[filename] == nil { - addBuild(filename, o.Position, data, builds) - } - - (*builds)[filename].Objects = append((*builds)[filename].Objects, o) - } - return nil -} - -func addInputs(data *Data, builds *map[string]*Data) error { - for _, in := range data.Inputs { - filename := filename(in.Position, data.Config) - if (*builds)[filename] == nil { - addBuild(filename, in.Position, data, builds) - } - - (*builds)[filename].Inputs = append((*builds)[filename].Inputs, in) - } - return nil -} - -func addInterfaces(data *Data, builds *map[string]*Data) error { - for k, inf := range data.Interfaces { - filename := filename(inf.Position, data.Config) - if (*builds)[filename] == nil { - addBuild(filename, inf.Position, data, builds) - } - build := (*builds)[filename] - - if build.Interfaces == nil { - build.Interfaces = map[string]*Interface{} - } - if build.Interfaces[k] != nil { - return errors.New("conflicting interface keys") - } - - build.Interfaces[k] = inf - } - return nil -} - -func addReferencedTypes(data *Data, builds *map[string]*Data) error { - for k, rt := range data.ReferencedTypes { - filename := filename(rt.Definition.Position, data.Config) - if (*builds)[filename] == nil { - addBuild(filename, rt.Definition.Position, data, builds) - } - build := (*builds)[filename] - - if build.ReferencedTypes == nil { - build.ReferencedTypes = map[string]*config.TypeReference{} - } - if build.ReferencedTypes[k] != nil { - return errors.New("conflicting referenced type keys") - } - - build.ReferencedTypes[k] = rt - } - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl b/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl deleted file mode 100644 index bf59daccef9..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl +++ /dev/null @@ -1,235 +0,0 @@ -{{ reserveImport "context" }} -{{ reserveImport "fmt" }} -{{ reserveImport "io" }} -{{ reserveImport "strconv" }} -{{ reserveImport "time" }} -{{ reserveImport "sync" }} -{{ reserveImport "sync/atomic" }} -{{ reserveImport "errors" }} -{{ reserveImport "bytes" }} - -{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }} -{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} - - -{{ if eq .Config.Exec.Layout "single-file" }} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. - func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { - return &executableSchema{ - resolvers: cfg.Resolvers, - directives: cfg.Directives, - complexity: cfg.Complexity, - } - } - - type Config struct { - Resolvers ResolverRoot - Directives DirectiveRoot - Complexity ComplexityRoot - } - - type ResolverRoot interface { - {{- range $object := .Objects -}} - {{ if $object.HasResolvers -}} - {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver - {{ end }} - {{- end }} - {{- range $object := .Inputs -}} - {{ if $object.HasResolvers -}} - {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver - {{ end }} -{{- end }} -} - - type DirectiveRoot struct { - {{ range $directive := .Directives }} - {{- $directive.Declaration }} - {{ end }} - } - - type ComplexityRoot struct { - {{ range $object := .Objects }} - {{ if not $object.IsReserved -}} - {{ ucFirst $object.Name }} struct { - {{ range $_, $fields := $object.UniqueFields }} - {{- $field := index $fields 0 -}} - {{ if not $field.IsReserved -}} - {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} - {{ end }} - {{- end }} - } - {{- end }} - {{ end }} - } -{{ end }} - -{{ range $object := .Objects -}} - {{ if $object.HasResolvers }} - type {{ucFirst $object.Name}}Resolver interface { - {{ range $field := $object.Fields -}} - {{- if $field.IsResolver }} - {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }} - {{- end }} - {{ end }} - } - {{- end }} -{{- end }} - -{{ range $object := .Inputs -}} - {{ if $object.HasResolvers }} - type {{$object.Name}}Resolver interface { - {{ range $field := $object.Fields -}} - {{- if $field.IsResolver }} - {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }} - {{- end }} - {{ end }} - } - {{- end }} -{{- end }} - -{{ if eq .Config.Exec.Layout "single-file" }} - type executableSchema struct { - resolvers ResolverRoot - directives DirectiveRoot - complexity ComplexityRoot - } - - func (e *executableSchema) Schema() *ast.Schema { - return parsedSchema - } - - func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { - ec := executionContext{nil, e} - _ = ec - switch typeName + "." + field { - {{ range $object := .Objects }} - {{ if not $object.IsReserved }} - {{ range $_, $fields := $object.UniqueFields }} - {{- $len := len $fields }} - {{- range $i, $field := $fields }} - {{- $last := eq (add $i 1) $len }} - {{- if not $field.IsReserved }} - {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: - if e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}} == nil { - break - } - {{ if $field.Args }} - args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) - if err != nil { - return 0, false - } - {{ end }} - return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true - {{ end }} - {{- end }} - {{- end }} - {{ end }} - {{ end }} - {{ end }} - } - return 0, false - } - - func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { - rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e} - first := true - - switch rc.Operation.Operation { - {{- if .QueryRoot }} case ast.Query: - return func(ctx context.Context) *graphql.Response { - if !first { return nil } - first = false - {{ 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 - }) - {{- else -}} - data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - var buf bytes.Buffer - data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), - } - } - {{ end }} - - {{- if .MutationRoot }} case ast.Mutation: - return func(ctx context.Context) *graphql.Response { - if !first { return nil } - first = false - {{ 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 - }) - {{- else -}} - data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - var buf bytes.Buffer - data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), - } - } - {{ end }} - - {{- if .SubscriptionRoot }} case ast.Subscription: - {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} - next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ - return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil - }) - {{- else -}} - next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - - var buf bytes.Buffer - return func(ctx context.Context) *graphql.Response { - buf.Reset() - data := next() - - if data == nil { - return nil - } - data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), - } - } - {{ end }} - default: - return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) - } - } - - type executionContext struct { - *graphql.OperationContext - *executableSchema - } - - func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapSchema(parsedSchema), nil - } - - func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil - } - - var sources = []*ast.Source{ - {{- range $source := .Config.Sources }} - {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, - {{- end }} - } - var parsedSchema = gqlparser.MustLoadSchema(sources...) -{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/input.gotpl b/vendor/github.com/99designs/gqlgen/codegen/input.gotpl deleted file mode 100644 index 5694bcd613c..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/input.gotpl +++ /dev/null @@ -1,72 +0,0 @@ -{{- range $input := .Inputs }} - {{- if not .HasUnmarshal }} - func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, obj interface{}) ({{.Type | ref}}, error) { - var it {{.Type | ref}} - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v - } - {{ range $field := .Fields}} - {{- if notNil "Default" $field }} - if _, present := asMap[{{$field.Name|quote}}] ; !present { - asMap[{{$field.Name|quote}}] = {{ $field.Default | dump }} - } - {{- end}} - {{- end }} - - for k, v := range asMap { - switch k { - {{- range $field := .Fields }} - case {{$field.Name|quote}}: - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField({{$field.Name|quote}})) - {{- if $field.ImplDirectives }} - directive0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) } - {{ template "implDirectives" $field }} - tmp, err := directive{{$field.ImplDirectives|len}}(ctx) - if err != nil { - return it, graphql.ErrorOnPath(ctx, err) - } - if data, ok := tmp.({{ $field.TypeReference.GO | ref }}) ; ok { - {{- if $field.IsResolver }} - if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil { - return it, err - } - {{- else }} - it.{{$field.GoFieldName}} = data - {{- end }} - {{- if $field.TypeReference.IsNilable }} - {{- if not $field.IsResolver }} - } else if tmp == nil { - it.{{$field.GoFieldName}} = nil - {{- end }} - {{- end }} - } else { - err := fmt.Errorf(`unexpected type %T from directive, should be {{ $field.TypeReference.GO }}`, tmp) - return it, graphql.ErrorOnPath(ctx, err) - } - {{- else }} - {{- if $field.IsResolver }} - data, err := ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) - if err != nil { - return it, err - } - if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil { - return it, err - } - {{- else }} - it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) - if err != nil { - return it, err - } - {{- end }} - {{- end }} - {{- end }} - } - } - - return it, nil - } - {{- end }} -{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface.go b/vendor/github.com/99designs/gqlgen/codegen/interface.go deleted file mode 100644 index cdc4d4d32ed..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/interface.go +++ /dev/null @@ -1,87 +0,0 @@ -package codegen - -import ( - "fmt" - "go/types" - - "github.com/vektah/gqlparser/v2/ast" - - "github.com/99designs/gqlgen/codegen/config" -) - -type Interface struct { - *ast.Definition - Type types.Type - Implementors []InterfaceImplementor - InTypemap bool -} - -type InterfaceImplementor struct { - *ast.Definition - - Type types.Type - TakeRef bool -} - -func (b *builder) buildInterface(typ *ast.Definition) (*Interface, error) { - obj, err := b.Binder.DefaultUserObject(typ.Name) - if err != nil { - panic(err) - } - - i := &Interface{ - Definition: typ, - Type: obj, - InTypemap: b.Config.Models.UserDefined(typ.Name), - } - - interfaceType, err := findGoInterface(i.Type) - if interfaceType == nil || err != nil { - return nil, fmt.Errorf("%s is not an interface", i.Type) - } - - for _, implementor := range b.Schema.GetPossibleTypes(typ) { - obj, err := b.Binder.DefaultUserObject(implementor.Name) - if err != nil { - return nil, fmt.Errorf("%s has no backing go type", implementor.Name) - } - - implementorType, err := findGoNamedType(obj) - if err != nil { - return nil, fmt.Errorf("can not find backing go type %s: %w", obj.String(), err) - } else if implementorType == nil { - return nil, fmt.Errorf("can not find backing go type %s", obj.String()) - } - - anyValid := false - - // first check if the value receiver can be nil, eg can we type switch on case Thing: - if types.Implements(implementorType, interfaceType) { - i.Implementors = append(i.Implementors, InterfaceImplementor{ - Definition: implementor, - Type: obj, - TakeRef: !types.IsInterface(obj), - }) - anyValid = true - } - - // then check if the pointer receiver can be nil, eg can we type switch on case *Thing: - if types.Implements(types.NewPointer(implementorType), interfaceType) { - i.Implementors = append(i.Implementors, InterfaceImplementor{ - Definition: implementor, - Type: types.NewPointer(obj), - }) - anyValid = true - } - - if !anyValid { - return nil, fmt.Errorf("%s does not satisfy the interface %s", implementorType.String(), i.Type.String()) - } - } - - return i, nil -} - -func (i *InterfaceImplementor) CanBeNil() bool { - return config.IsNilable(i.Type) -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl b/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl deleted file mode 100644 index e9d560c8f64..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl +++ /dev/null @@ -1,21 +0,0 @@ -{{- range $interface := .Interfaces }} - -func (ec *executionContext) _{{$interface.Name}}(ctx context.Context, sel ast.SelectionSet, obj {{$interface.Type | ref}}) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - {{- range $implementor := $interface.Implementors }} - case {{$implementor.Type | ref}}: - {{- if $implementor.CanBeNil }} - if obj == nil { - return graphql.Null - } - {{- end }} - return ec._{{$implementor.Name}}(ctx, sel, {{ if $implementor.TakeRef }}&{{ end }}obj) - {{- end }} - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - -{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.go b/vendor/github.com/99designs/gqlgen/codegen/object.go deleted file mode 100644 index 6cf922d47c4..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/object.go +++ /dev/null @@ -1,169 +0,0 @@ -package codegen - -import ( - "fmt" - "go/types" - "strconv" - "strings" - "unicode" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/vektah/gqlparser/v2/ast" -) - -type GoFieldType int - -const ( - GoFieldUndefined GoFieldType = iota - GoFieldMethod - GoFieldVariable - GoFieldMap -) - -type Object struct { - *ast.Definition - - Type types.Type - ResolverInterface types.Type - Root bool - Fields []*Field - Implements []*ast.Definition - DisableConcurrency bool - Stream bool - Directives []*Directive -} - -func (b *builder) buildObject(typ *ast.Definition) (*Object, error) { - dirs, err := b.getDirectives(typ.Directives) - if err != nil { - return nil, fmt.Errorf("%s: %w", typ.Name, err) - } - - obj := &Object{ - Definition: typ, - Root: b.Schema.Query == typ || b.Schema.Mutation == typ || b.Schema.Subscription == typ, - DisableConcurrency: typ == b.Schema.Mutation, - Stream: typ == b.Schema.Subscription, - Directives: dirs, - ResolverInterface: types.NewNamed( - types.NewTypeName(0, b.Config.Exec.Pkg(), strings.Title(typ.Name)+"Resolver", nil), - nil, - nil, - ), - } - - if !obj.Root { - goObject, err := b.Binder.DefaultUserObject(typ.Name) - if err != nil { - return nil, err - } - obj.Type = goObject - } - - for _, intf := range b.Schema.GetImplements(typ) { - obj.Implements = append(obj.Implements, b.Schema.Types[intf.Name]) - } - - for _, field := range typ.Fields { - if strings.HasPrefix(field.Name, "__") { - continue - } - - var f *Field - f, err = b.buildField(obj, field) - if err != nil { - return nil, err - } - - obj.Fields = append(obj.Fields, f) - } - - return obj, nil -} - -func (o *Object) Reference() types.Type { - if config.IsNilable(o.Type) { - return o.Type - } - return types.NewPointer(o.Type) -} - -type Objects []*Object - -func (o *Object) Implementors() string { - satisfiedBy := strconv.Quote(o.Name) - for _, s := range o.Implements { - satisfiedBy += ", " + strconv.Quote(s.Name) - } - return "[]string{" + satisfiedBy + "}" -} - -func (o *Object) HasResolvers() bool { - for _, f := range o.Fields { - if f.IsResolver { - return true - } - } - return false -} - -func (o *Object) HasUnmarshal() bool { - if o.Type == config.MapType { - return true - } - for i := 0; i < o.Type.(*types.Named).NumMethods(); i++ { - if o.Type.(*types.Named).Method(i).Name() == "UnmarshalGQL" { - return true - } - } - return false -} - -func (o *Object) HasDirectives() bool { - if len(o.Directives) > 0 { - return true - } - for _, f := range o.Fields { - if f.HasDirectives() { - return true - } - } - - return false -} - -func (o *Object) IsConcurrent() bool { - for _, f := range o.Fields { - if f.IsConcurrent() { - return true - } - } - return false -} - -func (o *Object) IsReserved() bool { - return strings.HasPrefix(o.Definition.Name, "__") -} - -func (o *Object) Description() string { - return o.Definition.Description -} - -func (os Objects) ByName(name string) *Object { - for i, o := range os { - if strings.EqualFold(o.Definition.Name, name) { - return os[i] - } - } - return nil -} - -func ucFirst(s string) string { - if s == "" { - return "" - } - - r := []rune(s) - r[0] = unicode.ToUpper(r[0]) - return string(r) -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.gotpl b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl deleted file mode 100644 index 8cb9d28ced7..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/object.gotpl +++ /dev/null @@ -1,113 +0,0 @@ -{{- range $object := .Objects }} - -var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}} - -{{- if .Stream }} -func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ - Object: {{$object.Name|quote}}, - }) - if len(fields) != 1 { - ec.Errorf(ctx, "must subscribe to exactly one stream") - return nil - } - - switch fields[0].Name { - {{- range $field := $object.Fields }} - case "{{$field.Name}}": - return ec._{{$object.Name}}_{{$field.Name}}(ctx, fields[0]) - {{- end }} - default: - panic("unknown field " + strconv.Quote(fields[0].Name)) - } -} -{{- else }} -func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors) - {{- if $object.Root }} - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ - Object: {{$object.Name|quote}}, - }) - {{end}} - out := graphql.NewFieldSet(fields) - var invalids uint32 - for i, field := range fields { - {{- if $object.Root }} - innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ - Object: field.Name, - Field: field, - }) - {{end}} - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString({{$object.Name|quote}}) - {{- range $field := $object.Fields }} - case "{{$field.Name}}": - {{- if $field.IsConcurrent }} - field := field - - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) - {{- if $field.TypeReference.GQL.NonNull }} - if res == graphql.Null { - {{- if $object.IsConcurrent }} - atomic.AddUint32(&invalids, 1) - {{- else }} - invalids++ - {{- end }} - } - {{- end }} - return res - } - - {{if $object.Root}} - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) - } - {{end}} - - out.Concurrently(i, func() graphql.Marshaler { - {{- if $object.Root -}} - return rrm(innerCtx) - {{- else -}} - return innerFunc(ctx) - {{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) - {{else}} - out.Values[i] = innerFunc(ctx) - {{end}} - - {{- if $field.TypeReference.GQL.NonNull }} - if out.Values[i] == graphql.Null { - {{- if $object.IsConcurrent }} - atomic.AddUint32(&invalids, 1) - {{- else }} - invalids++ - {{- end }} - } - {{- end }} - {{- end }} - {{- end }} - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch() - if invalids > 0 { return graphql.Null } - return out -} -{{- end }} - -{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/root_.gotpl b/vendor/github.com/99designs/gqlgen/codegen/root_.gotpl deleted file mode 100644 index 13d77961837..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/root_.gotpl +++ /dev/null @@ -1,201 +0,0 @@ -{{ reserveImport "context" }} -{{ reserveImport "fmt" }} -{{ reserveImport "io" }} -{{ reserveImport "strconv" }} -{{ reserveImport "time" }} -{{ reserveImport "sync" }} -{{ reserveImport "sync/atomic" }} -{{ reserveImport "errors" }} -{{ reserveImport "bytes" }} - -{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }} -{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} - -// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. -func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { - return &executableSchema{ - resolvers: cfg.Resolvers, - directives: cfg.Directives, - complexity: cfg.Complexity, - } -} - -type Config struct { - Resolvers ResolverRoot - Directives DirectiveRoot - Complexity ComplexityRoot -} - -type ResolverRoot interface { -{{- range $object := .Objects -}} - {{ if $object.HasResolvers -}} - {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver - {{ end }} -{{- end }} -} - -type DirectiveRoot struct { -{{ range $directive := .Directives }} - {{- $directive.Declaration }} -{{ end }} -} - -type ComplexityRoot struct { -{{ range $object := .Objects }} - {{ if not $object.IsReserved -}} - {{ ucFirst $object.Name }} struct { - {{ range $_, $fields := $object.UniqueFields }} - {{- $field := index $fields 0 -}} - {{ if not $field.IsReserved -}} - {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} - {{ end }} - {{- end }} - } - {{- end }} -{{ end }} -} - -type executableSchema struct { - resolvers ResolverRoot - directives DirectiveRoot - complexity ComplexityRoot -} - -func (e *executableSchema) Schema() *ast.Schema { - return parsedSchema -} - -func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { - ec := executionContext{nil, e} - _ = ec - switch typeName + "." + field { - {{ range $object := .Objects }} - {{ if not $object.IsReserved }} - {{ range $_, $fields := $object.UniqueFields }} - {{- $len := len $fields }} - {{- range $i, $field := $fields }} - {{- $last := eq (add $i 1) $len }} - {{- if not $field.IsReserved }} - {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: - if e.complexity.{{ucFirst $object.Name }}.{{$field.GoFieldName}} == nil { - break - } - {{ if $field.Args }} - args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) - if err != nil { - return 0, false - } - {{ end }} - return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true - {{ end }} - {{- end }} - {{- end }} - {{ end }} - {{ end }} - {{ end }} - } - return 0, false -} - -func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { - rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e} - first := true - - switch rc.Operation.Operation { - {{- if .QueryRoot }} case ast.Query: - return func(ctx context.Context) *graphql.Response { - if !first { return nil } - first = false - {{ 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 - }) - {{- else -}} - data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - var buf bytes.Buffer - data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), - } - } - {{ end }} - - {{- if .MutationRoot }} case ast.Mutation: - return func(ctx context.Context) *graphql.Response { - if !first { return nil } - first = false - {{ 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 - }) - {{- else -}} - data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - var buf bytes.Buffer - data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), - } - } - {{ end }} - - {{- if .SubscriptionRoot }} case ast.Subscription: - {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} - next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ - return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil - }) - {{- else -}} - next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - - var buf bytes.Buffer - return func(ctx context.Context) *graphql.Response { - buf.Reset() - data := next() - - if data == nil { - return nil - } - data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), - } - } - {{ end }} - default: - return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) - } -} - -type executionContext struct { - *graphql.OperationContext - *executableSchema -} - -func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapSchema(parsedSchema), nil -} - -func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil -} - -var sources = []*ast.Source{ -{{- range $source := .Config.Sources }} - {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, -{{- end }} -} -var parsedSchema = gqlparser.MustLoadSchema(sources...) diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/import.go b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go deleted file mode 100644 index 00a82ea5ef1..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/import.go +++ /dev/null @@ -1,139 +0,0 @@ -package templates - -import ( - "fmt" - "go/types" - "strconv" - "strings" - - "github.com/99designs/gqlgen/internal/code" -) - -type Import struct { - Name string - Path string - Alias string -} - -type Imports struct { - imports []*Import - destDir string - packages *code.Packages -} - -func (i *Import) String() string { - if strings.HasSuffix(i.Path, i.Alias) { - return strconv.Quote(i.Path) - } - - return i.Alias + " " + strconv.Quote(i.Path) -} - -func (s *Imports) String() string { - res := "" - for i, imp := range s.imports { - if i != 0 { - res += "\n" - } - res += imp.String() - } - return res -} - -func (s *Imports) Reserve(path string, aliases ...string) (string, error) { - if path == "" { - panic("empty ambient import") - } - - // if we are referencing our own package we dont need an import - if code.ImportPathForDir(s.destDir) == path { - return "", nil - } - - name := s.packages.NameForPackage(path) - var alias string - if len(aliases) != 1 { - alias = name - } else { - alias = aliases[0] - } - - if existing := s.findByPath(path); existing != nil { - if existing.Alias == alias { - return "", nil - } - return "", fmt.Errorf("ambient import already exists") - } - - if alias := s.findByAlias(alias); alias != nil { - return "", fmt.Errorf("ambient import collides on an alias") - } - - s.imports = append(s.imports, &Import{ - Name: name, - Path: path, - Alias: alias, - }) - - return "", nil -} - -func (s *Imports) Lookup(path string) string { - if path == "" { - return "" - } - - path = code.NormalizeVendor(path) - - // if we are referencing our own package we dont need an import - if code.ImportPathForDir(s.destDir) == path { - return "" - } - - if existing := s.findByPath(path); existing != nil { - return existing.Alias - } - - imp := &Import{ - Name: s.packages.NameForPackage(path), - Path: path, - } - s.imports = append(s.imports, imp) - - alias := imp.Name - i := 1 - for s.findByAlias(alias) != nil { - alias = imp.Name + strconv.Itoa(i) - i++ - if i > 1000 { - panic(fmt.Errorf("too many collisions, last attempt was %s", alias)) - } - } - imp.Alias = alias - - return imp.Alias -} - -func (s *Imports) LookupType(t types.Type) string { - return types.TypeString(t, func(i *types.Package) string { - return s.Lookup(i.Path()) - }) -} - -func (s Imports) findByPath(importPath string) *Import { - for _, imp := range s.imports { - if imp.Path == importPath { - return imp - } - } - return nil -} - -func (s Imports) findByAlias(alias string) *Import { - for _, imp := range s.imports { - if imp.Alias == alias { - return imp - } - } - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go deleted file mode 100644 index 0ea3c8725e6..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go +++ /dev/null @@ -1,611 +0,0 @@ -package templates - -import ( - "bytes" - "fmt" - "go/types" - "io/ioutil" - "os" - "path/filepath" - "reflect" - "runtime" - "sort" - "strconv" - "strings" - "text/template" - "unicode" - - "github.com/99designs/gqlgen/internal/code" - - "github.com/99designs/gqlgen/internal/imports" -) - -// CurrentImports keeps track of all the import declarations that are needed during the execution of a plugin. -// this is done with a global because subtemplates currently get called in functions. Lets aim to remove this eventually. -var CurrentImports *Imports - -// Options specify various parameters to rendering a template. -type Options struct { - // PackageName is a helper that specifies the package header declaration. - // In other words, when you write the template you don't need to specify `package X` - // at the top of the file. By providing PackageName in the Options, the Render - // function will do that for you. - PackageName string - // Template is a string of the entire template that - // will be parsed and rendered. If it's empty, - // the plugin processor will look for .gotpl files - // in the same directory of where you wrote the plugin. - Template string - // Filename is the name of the file that will be - // written to the system disk once the template is rendered. - Filename string - RegionTags bool - GeneratedHeader bool - // PackageDoc is documentation written above the package line - PackageDoc string - // FileNotice is notice written below the package line - FileNotice string - // Data will be passed to the template execution. - Data interface{} - Funcs template.FuncMap - - // Packages cache, you can find me on config.Config - Packages *code.Packages -} - -// Render renders a gql plugin template from the given Options. Render is an -// abstraction of the text/template package that makes it easier to write gqlgen -// plugins. If Options.Template is empty, the Render function will look for `.gotpl` -// files inside the directory where you wrote the plugin. -func Render(cfg Options) error { - if CurrentImports != nil { - panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected")) - } - CurrentImports = &Imports{packages: cfg.Packages, destDir: filepath.Dir(cfg.Filename)} - - // load path relative to calling source file - _, callerFile, _, _ := runtime.Caller(1) - rootDir := filepath.Dir(callerFile) - - funcs := Funcs() - for n, f := range cfg.Funcs { - funcs[n] = f - } - t := template.New("").Funcs(funcs) - - var roots []string - if cfg.Template != "" { - var err error - t, err = t.New("template.gotpl").Parse(cfg.Template) - if err != nil { - return fmt.Errorf("error with provided template: %w", err) - } - roots = append(roots, "template.gotpl") - } else { - // load all the templates in the directory - err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - name := filepath.ToSlash(strings.TrimPrefix(path, rootDir+string(os.PathSeparator))) - if !strings.HasSuffix(info.Name(), ".gotpl") { - return nil - } - // omit any templates with "_" at the end of their name, which are meant for specific contexts only - if strings.HasSuffix(info.Name(), "_.gotpl") { - return nil - } - b, err := ioutil.ReadFile(path) - if err != nil { - return err - } - - t, err = t.New(name).Parse(string(b)) - if err != nil { - return fmt.Errorf("%s: %w", cfg.Filename, err) - } - - roots = append(roots, name) - - return nil - }) - if err != nil { - return fmt.Errorf("locating templates: %w", err) - } - } - - // then execute all the important looking ones in order, adding them to the same file - sort.Slice(roots, func(i, j int) bool { - // important files go first - if strings.HasSuffix(roots[i], "!.gotpl") { - return true - } - if strings.HasSuffix(roots[j], "!.gotpl") { - return false - } - return roots[i] < roots[j] - }) - var buf bytes.Buffer - for _, root := range roots { - if cfg.RegionTags { - buf.WriteString("\n// region " + center(70, "*", " "+root+" ") + "\n") - } - err := t.Lookup(root).Execute(&buf, cfg.Data) - if err != nil { - return fmt.Errorf("%s: %w", root, err) - } - if cfg.RegionTags { - buf.WriteString("\n// endregion " + center(70, "*", " "+root+" ") + "\n") - } - } - - var result bytes.Buffer - if cfg.GeneratedHeader { - result.WriteString("// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\n") - } - if cfg.PackageDoc != "" { - result.WriteString(cfg.PackageDoc + "\n") - } - result.WriteString("package ") - result.WriteString(cfg.PackageName) - result.WriteString("\n\n") - if cfg.FileNotice != "" { - result.WriteString(cfg.FileNotice) - result.WriteString("\n\n") - } - result.WriteString("import (\n") - result.WriteString(CurrentImports.String()) - result.WriteString(")\n") - _, err := buf.WriteTo(&result) - if err != nil { - return err - } - CurrentImports = nil - - err = write(cfg.Filename, result.Bytes(), cfg.Packages) - if err != nil { - return err - } - - cfg.Packages.Evict(code.ImportPathForDir(filepath.Dir(cfg.Filename))) - return nil -} - -func center(width int, pad string, s string) string { - if len(s)+2 > width { - return s - } - lpad := (width - len(s)) / 2 - rpad := width - (lpad + len(s)) - return strings.Repeat(pad, lpad) + s + strings.Repeat(pad, rpad) -} - -func Funcs() template.FuncMap { - return template.FuncMap{ - "ucFirst": UcFirst, - "lcFirst": LcFirst, - "quote": strconv.Quote, - "rawQuote": rawQuote, - "dump": Dump, - "ref": ref, - "ts": TypeIdentifier, - "call": Call, - "prefixLines": prefixLines, - "notNil": notNil, - "reserveImport": CurrentImports.Reserve, - "lookupImport": CurrentImports.Lookup, - "go": ToGo, - "goPrivate": ToGoPrivate, - "add": func(a, b int) int { - return a + b - }, - "render": func(filename string, tpldata interface{}) (*bytes.Buffer, error) { - return render(resolveName(filename, 0), tpldata) - }, - } -} - -func UcFirst(s string) string { - if s == "" { - return "" - } - r := []rune(s) - r[0] = unicode.ToUpper(r[0]) - return string(r) -} - -func LcFirst(s string) string { - if s == "" { - return "" - } - - r := []rune(s) - r[0] = unicode.ToLower(r[0]) - return string(r) -} - -func isDelimiter(c rune) bool { - return c == '-' || c == '_' || unicode.IsSpace(c) -} - -func ref(p types.Type) string { - return CurrentImports.LookupType(p) -} - -var pkgReplacer = strings.NewReplacer( - "/", "ᚋ", - ".", "ᚗ", - "-", "ᚑ", - "~", "א", -) - -func TypeIdentifier(t types.Type) string { - res := "" - for { - switch it := t.(type) { - case *types.Pointer: - t.Underlying() - res += "ᚖ" - t = it.Elem() - case *types.Slice: - res += "ᚕ" - t = it.Elem() - case *types.Named: - res += pkgReplacer.Replace(it.Obj().Pkg().Path()) - res += "ᚐ" - res += it.Obj().Name() - return res - case *types.Basic: - res += it.Name() - return res - case *types.Map: - res += "map" - return res - case *types.Interface: - res += "interface" - return res - default: - panic(fmt.Errorf("unexpected type %T", it)) - } - } -} - -func Call(p *types.Func) string { - pkg := CurrentImports.Lookup(p.Pkg().Path()) - - if pkg != "" { - pkg += "." - } - - if p.Type() != nil { - // make sure the returned type is listed in our imports. - ref(p.Type().(*types.Signature).Results().At(0).Type()) - } - - return pkg + p.Name() -} - -func ToGo(name string) string { - if name == "_" { - return "_" - } - runes := make([]rune, 0, len(name)) - - wordWalker(name, func(info *wordInfo) { - word := info.Word - if info.MatchCommonInitial { - word = strings.ToUpper(word) - } else if !info.HasCommonInitial { - if strings.ToUpper(word) == word || strings.ToLower(word) == word { - // FOO or foo → Foo - // FOo → FOo - word = UcFirst(strings.ToLower(word)) - } - } - runes = append(runes, []rune(word)...) - }) - - return string(runes) -} - -func ToGoPrivate(name string) string { - if name == "_" { - return "_" - } - runes := make([]rune, 0, len(name)) - - first := true - wordWalker(name, func(info *wordInfo) { - word := info.Word - switch { - case first: - if strings.ToUpper(word) == word || strings.ToLower(word) == word { - // ID → id, CAMEL → camel - word = strings.ToLower(info.Word) - } else { - // ITicket → iTicket - word = LcFirst(info.Word) - } - first = false - case info.MatchCommonInitial: - word = strings.ToUpper(word) - case !info.HasCommonInitial: - word = UcFirst(strings.ToLower(word)) - } - runes = append(runes, []rune(word)...) - }) - - return sanitizeKeywords(string(runes)) -} - -type wordInfo struct { - Word string - MatchCommonInitial bool - HasCommonInitial bool -} - -// This function is based on the following code. -// https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679 -func wordWalker(str string, f func(*wordInfo)) { - runes := []rune(strings.TrimFunc(str, isDelimiter)) - w, i := 0, 0 // index of start of word, scan - hasCommonInitial := false - for i+1 <= len(runes) { - eow := false // whether we hit the end of a word - switch { - case i+1 == len(runes): - eow = true - case isDelimiter(runes[i+1]): - // underscore; shift the remainder forward over any run of underscores - eow = true - n := 1 - for i+n+1 < len(runes) && isDelimiter(runes[i+n+1]) { - n++ - } - - // Leave at most one underscore if the underscore is between two digits - if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) { - n-- - } - - copy(runes[i+1:], runes[i+n+1:]) - runes = runes[:len(runes)-n] - case unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]): - // lower->non-lower - eow = true - } - i++ - - // [w,i) is a word. - word := string(runes[w:i]) - if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) { - // through - // split IDFoo → ID, Foo - // but URLs → URLs - } else if !eow { - if commonInitialisms[word] { - hasCommonInitial = true - } - continue - } - - matchCommonInitial := false - if commonInitialisms[strings.ToUpper(word)] { - hasCommonInitial = true - matchCommonInitial = true - } - - f(&wordInfo{ - Word: word, - MatchCommonInitial: matchCommonInitial, - HasCommonInitial: hasCommonInitial, - }) - hasCommonInitial = false - w = i - } -} - -var keywords = []string{ - "break", - "default", - "func", - "interface", - "select", - "case", - "defer", - "go", - "map", - "struct", - "chan", - "else", - "goto", - "package", - "switch", - "const", - "fallthrough", - "if", - "range", - "type", - "continue", - "for", - "import", - "return", - "var", - "_", -} - -// sanitizeKeywords prevents collisions with go keywords for arguments to resolver functions -func sanitizeKeywords(name string) string { - for _, k := range keywords { - if name == k { - return name + "Arg" - } - } - return name -} - -// commonInitialisms is a set of common initialisms. -// Only add entries that are highly unlikely to be non-initialisms. -// For instance, "ID" is fine (Freudian code is rare), but "AND" is not. -var commonInitialisms = map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "CSV": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTP": true, - "HTTPS": true, - "ICMP": true, - "ID": true, - "IP": true, - "JSON": true, - "KVK": true, - "LHS": true, - "PDF": true, - "PGP": true, - "QPS": true, - "QR": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "SVG": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "URI": true, - "URL": true, - "UTF8": true, - "UUID": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, -} - -func rawQuote(s string) string { - return "`" + strings.ReplaceAll(s, "`", "`+\"`\"+`") + "`" -} - -func notNil(field string, data interface{}) bool { - v := reflect.ValueOf(data) - - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if v.Kind() != reflect.Struct { - return false - } - val := v.FieldByName(field) - - return val.IsValid() && !val.IsNil() -} - -func Dump(val interface{}) string { - switch val := val.(type) { - case int: - return strconv.Itoa(val) - case int64: - return fmt.Sprintf("%d", val) - case float64: - return fmt.Sprintf("%f", val) - case string: - return strconv.Quote(val) - case bool: - return strconv.FormatBool(val) - case nil: - return "nil" - case []interface{}: - var parts []string - for _, part := range val { - parts = append(parts, Dump(part)) - } - return "[]interface{}{" + strings.Join(parts, ",") + "}" - case map[string]interface{}: - buf := bytes.Buffer{} - buf.WriteString("map[string]interface{}{") - var keys []string - for key := range val { - keys = append(keys, key) - } - sort.Strings(keys) - - for _, key := range keys { - data := val[key] - - buf.WriteString(strconv.Quote(key)) - buf.WriteString(":") - buf.WriteString(Dump(data)) - buf.WriteString(",") - } - buf.WriteString("}") - return buf.String() - default: - panic(fmt.Errorf("unsupported type %T", val)) - } -} - -func prefixLines(prefix, s string) string { - return prefix + strings.ReplaceAll(s, "\n", "\n"+prefix) -} - -func resolveName(name string, skip int) string { - if name[0] == '.' { - // load path relative to calling source file - _, callerFile, _, _ := runtime.Caller(skip + 1) - return filepath.Join(filepath.Dir(callerFile), name[1:]) - } - - // load path relative to this directory - _, callerFile, _, _ := runtime.Caller(0) - return filepath.Join(filepath.Dir(callerFile), name) -} - -func render(filename string, tpldata interface{}) (*bytes.Buffer, error) { - t := template.New("").Funcs(Funcs()) - - b, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - - t, err = t.New(filepath.Base(filename)).Parse(string(b)) - if err != nil { - panic(err) - } - - buf := &bytes.Buffer{} - return buf, t.Execute(buf, tpldata) -} - -func write(filename string, b []byte, packages *code.Packages) error { - err := os.MkdirAll(filepath.Dir(filename), 0o755) - if err != nil { - return fmt.Errorf("failed to create directory: %w", err) - } - - formatted, err := imports.Prune(filename, b, packages) - if err != nil { - fmt.Fprintf(os.Stderr, "gofmt failed on %s: %s\n", filepath.Base(filename), err.Error()) - formatted = b - } - - err = ioutil.WriteFile(filename, formatted, 0o644) - if err != nil { - return fmt.Errorf("failed to write %s: %w", filename, err) - } - - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.go b/vendor/github.com/99designs/gqlgen/codegen/type.go deleted file mode 100644 index 20b09dc9755..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/type.go +++ /dev/null @@ -1,32 +0,0 @@ -package codegen - -import ( - "fmt" - - "github.com/99designs/gqlgen/codegen/config" -) - -func (b *builder) buildTypes() map[string]*config.TypeReference { - ret := map[string]*config.TypeReference{} - for _, ref := range b.Binder.References { - processType(ret, ref) - } - return ret -} - -func processType(ret map[string]*config.TypeReference, ref *config.TypeReference) { - key := ref.UniquenessKey() - if existing, found := ret[key]; found { - // Simplistic check of content which is obviously different. - existingGQL := fmt.Sprintf("%v", existing.GQL) - newGQL := fmt.Sprintf("%v", ref.GQL) - if existingGQL != newGQL { - panic(fmt.Sprintf("non-unique key \"%s\", trying to replace %s with %s", key, existingGQL, newGQL)) - } - } - ret[key] = ref - - if ref.IsSlice() || ref.IsPtrToSlice() || ref.IsPtrToPtr() { - processType(ret, ref.Elem()) - } -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.gotpl b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl deleted file mode 100644 index 1fc6319c555..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/type.gotpl +++ /dev/null @@ -1,192 +0,0 @@ -{{- range $type := .ReferencedTypes }} - {{ with $type.UnmarshalFunc }} - func (ec *executionContext) {{ . }}(ctx context.Context, v interface{}) ({{ $type.GO | ref }}, error) { - {{- if and $type.IsNilable (not $type.GQL.NonNull) (not $type.IsPtrToPtr) }} - if v == nil { return nil, nil } - {{- end }} - {{- if $type.IsPtrToSlice }} - res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) - {{- else if $type.IsSlice }} - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]{{$type.GO.Elem | ref}}, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.{{ $type.Elem.UnmarshalFunc }}(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil - {{- else if and $type.IsPtrToPtr (not $type.Unmarshaler) (not $type.IsMarshaler) }} - var pres {{ $type.Elem.GO | ref }} - if v != nil { - res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v) - if err != nil { - return nil, graphql.ErrorOnPath(ctx, err) - } - pres = res - } - return &pres, nil - {{- else }} - {{- if $type.Unmarshaler }} - {{- if $type.CastType }} - {{- if $type.IsContext }} - tmp, err := {{ $type.Unmarshaler | call }}(ctx, v) - {{- else }} - tmp, err := {{ $type.Unmarshaler | call }}(v) - {{- end }} - {{- if and $type.IsNilable $type.Elem }} - res := {{ $type.Elem.GO | ref }}(tmp) - {{- else}} - res := {{ $type.GO | ref }}(tmp) - {{- end }} - {{- else}} - {{- if $type.IsContext }} - res, err := {{ $type.Unmarshaler | call }}(ctx, v) - {{- else }} - res, err := {{ $type.Unmarshaler | call }}(v) - {{- end }} - {{- end }} - {{- if and $type.IsTargetNilable (not $type.IsNilable) }} - return *res, graphql.ErrorOnPath(ctx, err) - {{- else if and (not $type.IsTargetNilable) $type.IsNilable }} - return &res, graphql.ErrorOnPath(ctx, err) - {{- else}} - return res, graphql.ErrorOnPath(ctx, err) - {{- end }} - {{- else if eq ($type.GO | ref) "map[string]interface{}" }} - return v.(map[string]interface{}), nil - {{- else if $type.IsMarshaler }} - {{- if and $type.IsNilable $type.Elem }} - var res = new({{ $type.Elem.GO | ref }}) - {{- else}} - var res {{ $type.GO | ref }} - {{- end }} - {{- if $type.IsContext }} - err := res.UnmarshalGQLContext(ctx, v) - {{- else }} - err := res.UnmarshalGQL(v) - {{- end }} - return res, graphql.ErrorOnPath(ctx, err) - {{- else }} - res, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v) - {{- if $type.IsNilable }} - return &res, graphql.ErrorOnPath(ctx, err) - {{- else}} - return res, graphql.ErrorOnPath(ctx, err) - {{- end }} - {{- end }} - {{- end }} - } - {{- end }} - - {{ with $type.MarshalFunc }} - func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler { - {{- if $type.IsPtrToSlice }} - return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v) - {{- else if $type.IsSlice }} - {{- if not $type.GQL.NonNull }} - if v == nil { - return graphql.Null - } - {{- end }} - ret := make(graphql.Array, len(v)) - {{- if not $type.IsScalar }} - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - {{- end }} - for i := range v { - {{- if not $type.IsScalar }} - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - {{ else }} - ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i]) - {{- end }} - } - {{ if not $type.IsScalar }} wg.Wait() {{ end }} - {{ if $type.Elem.GQL.NonNull }} - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - {{ end }} - return ret - {{- else if and $type.IsPtrToPtr (not $type.Unmarshaler) (not $type.IsMarshaler) }} - if v == nil { - return graphql.Null - } - return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v) - {{- else }} - {{- if $type.IsNilable }} - if v == nil { - {{- if $type.GQL.NonNull }} - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "must not be null") - } - {{- end }} - return graphql.Null - } - {{- end }} - {{- if $type.IsMarshaler }} - {{- if $type.IsContext }} - return graphql.WrapContextMarshaler(ctx, v) - {{- else }} - return v - {{- end }} - {{- else if $type.Marshaler }} - {{- $v := "v" }} - {{- if and $type.IsTargetNilable (not $type.IsNilable) }} - {{- $v = "&v" }} - {{- else if and (not $type.IsTargetNilable) $type.IsNilable }} - {{- $v = "*v" }} - {{- end }} - res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}({{ $v }}){{else}}{{ $v }}{{- end }}) - {{- if $type.GQL.NonNull }} - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "must not be null") - } - } - {{- end }} - {{- if $type.IsContext }} - return graphql.WrapContextMarshaler(ctx, res) - {{- else }} - return res - {{- end }} - {{- else }} - return ec._{{$type.Definition.Name}}(ctx, sel, {{ if not $type.IsNilable}}&{{end}} v) - {{- end }} - {{- end }} - } - {{- end }} -{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/util.go b/vendor/github.com/99designs/gqlgen/codegen/util.go deleted file mode 100644 index fa2ceed3dfe..00000000000 --- a/vendor/github.com/99designs/gqlgen/codegen/util.go +++ /dev/null @@ -1,46 +0,0 @@ -package codegen - -import ( - "fmt" - "go/types" - "strings" -) - -func findGoNamedType(def types.Type) (*types.Named, error) { - if def == nil { - return nil, nil - } - - namedType, ok := def.(*types.Named) - if !ok { - return nil, fmt.Errorf("expected %s to be a named type, instead found %T\n", def.String(), def) - } - - return namedType, nil -} - -func findGoInterface(def types.Type) (*types.Interface, error) { - if def == nil { - return nil, nil - } - namedType, err := findGoNamedType(def) - if err != nil { - return nil, err - } - if namedType == nil { - return nil, nil - } - - underlying, ok := namedType.Underlying().(*types.Interface) - if !ok { - return nil, fmt.Errorf("expected %s to be a named interface, instead found %s", def.String(), namedType.String()) - } - - return underlying, nil -} - -func equalFieldName(source, target string) bool { - source = strings.ReplaceAll(source, "_", "") - target = strings.ReplaceAll(target, "_", "") - return strings.EqualFold(source, target) -} diff --git a/vendor/github.com/99designs/gqlgen/complexity/complexity.go b/vendor/github.com/99designs/gqlgen/complexity/complexity.go deleted file mode 100644 index e3ecf7612d5..00000000000 --- a/vendor/github.com/99designs/gqlgen/complexity/complexity.go +++ /dev/null @@ -1,109 +0,0 @@ -package complexity - -import ( - "github.com/99designs/gqlgen/graphql" - "github.com/vektah/gqlparser/v2/ast" -) - -func Calculate(es graphql.ExecutableSchema, op *ast.OperationDefinition, vars map[string]interface{}) int { - walker := complexityWalker{ - es: es, - schema: es.Schema(), - vars: vars, - } - return walker.selectionSetComplexity(op.SelectionSet) -} - -type complexityWalker struct { - es graphql.ExecutableSchema - schema *ast.Schema - vars map[string]interface{} -} - -func (cw complexityWalker) selectionSetComplexity(selectionSet ast.SelectionSet) int { - var complexity int - for _, selection := range selectionSet { - switch s := selection.(type) { - case *ast.Field: - fieldDefinition := cw.schema.Types[s.Definition.Type.Name()] - - if fieldDefinition.Name == "__Schema" { - continue - } - - var childComplexity int - switch fieldDefinition.Kind { - case ast.Object, ast.Interface, ast.Union: - childComplexity = cw.selectionSetComplexity(s.SelectionSet) - } - - args := s.ArgumentMap(cw.vars) - var fieldComplexity int - if s.ObjectDefinition.Kind == ast.Interface { - fieldComplexity = cw.interfaceFieldComplexity(s.ObjectDefinition, s.Name, childComplexity, args) - } else { - fieldComplexity = cw.fieldComplexity(s.ObjectDefinition.Name, s.Name, childComplexity, args) - } - complexity = safeAdd(complexity, fieldComplexity) - - case *ast.FragmentSpread: - complexity = safeAdd(complexity, cw.selectionSetComplexity(s.Definition.SelectionSet)) - - case *ast.InlineFragment: - complexity = safeAdd(complexity, cw.selectionSetComplexity(s.SelectionSet)) - } - } - return complexity -} - -func (cw complexityWalker) interfaceFieldComplexity(def *ast.Definition, field string, childComplexity int, args map[string]interface{}) int { - // Interfaces don't have their own separate field costs, so they have to assume the worst case. - // We iterate over all implementors and choose the most expensive one. - maxComplexity := 0 - implementors := cw.schema.GetPossibleTypes(def) - for _, t := range implementors { - fieldComplexity := cw.fieldComplexity(t.Name, field, childComplexity, args) - if fieldComplexity > maxComplexity { - maxComplexity = fieldComplexity - } - } - return maxComplexity -} - -func (cw complexityWalker) fieldComplexity(object, field string, childComplexity int, args map[string]interface{}) int { - if customComplexity, ok := cw.es.Complexity(object, field, childComplexity, args); ok && customComplexity >= childComplexity { - return customComplexity - } - // default complexity calculation - return safeAdd(1, childComplexity) -} - -const maxInt = int(^uint(0) >> 1) - -// safeAdd is a saturating add of a and b that ignores negative operands. -// If a + b would overflow through normal Go addition, -// it returns the maximum integer value instead. -// -// Adding complexities with this function prevents attackers from intentionally -// overflowing the complexity calculation to allow overly-complex queries. -// -// It also helps mitigate the impact of custom complexities that accidentally -// return negative values. -func safeAdd(a, b int) int { - // Ignore negative operands. - if a < 0 { - if b < 0 { - return 1 - } - return b - } else if b < 0 { - return a - } - - c := a + b - if c < a { - // Set c to maximum integer instead of overflowing. - c = maxInt - } - return c -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/any.go b/vendor/github.com/99designs/gqlgen/graphql/any.go deleted file mode 100644 index 6ea8bf2eaeb..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/any.go +++ /dev/null @@ -1,19 +0,0 @@ -package graphql - -import ( - "encoding/json" - "io" -) - -func MarshalAny(v interface{}) Marshaler { - return WriterFunc(func(w io.Writer) { - err := json.NewEncoder(w).Encode(v) - if err != nil { - panic(err) - } - }) -} - -func UnmarshalAny(v interface{}) (interface{}, error) { - return v, nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/bool.go b/vendor/github.com/99designs/gqlgen/graphql/bool.go deleted file mode 100644 index f435e0c0988..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/bool.go +++ /dev/null @@ -1,27 +0,0 @@ -package graphql - -import ( - "fmt" - "io" - "strings" -) - -func MarshalBoolean(b bool) Marshaler { - if b { - return WriterFunc(func(w io.Writer) { w.Write(trueLit) }) - } - return WriterFunc(func(w io.Writer) { w.Write(falseLit) }) -} - -func UnmarshalBoolean(v interface{}) (bool, error) { - switch v := v.(type) { - case string: - return strings.ToLower(v) == "true", nil - case int: - return v != 0, nil - case bool: - return v, nil - default: - return false, fmt.Errorf("%T is not a bool", v) - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/cache.go b/vendor/github.com/99designs/gqlgen/graphql/cache.go deleted file mode 100644 index fe86ca35028..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/cache.go +++ /dev/null @@ -1,29 +0,0 @@ -package graphql - -import "context" - -// Cache is a shared store for APQ and query AST caching -type Cache interface { - // Get looks up a key's value from the cache. - Get(ctx context.Context, key string) (value interface{}, ok bool) - - // Add adds a value to the cache. - Add(ctx context.Context, key string, value interface{}) -} - -// MapCache is the simplest implementation of a cache, because it can not evict it should only be used in tests -type MapCache map[string]interface{} - -// Get looks up a key's value from the cache. -func (m MapCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { - v, ok := m[key] - return v, ok -} - -// Add adds a value to the cache. -func (m MapCache) Add(ctx context.Context, key string, value interface{}) { m[key] = value } - -type NoCache struct{} - -func (n NoCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { return nil, false } -func (n NoCache) Add(ctx context.Context, key string, value interface{}) {} diff --git a/vendor/github.com/99designs/gqlgen/graphql/coercion.go b/vendor/github.com/99designs/gqlgen/graphql/coercion.go deleted file mode 100644 index d3d3c18b2b1..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/coercion.go +++ /dev/null @@ -1,56 +0,0 @@ -package graphql - -import ( - "encoding/json" -) - -// CoerceList applies coercion from a single value to a list. -func CoerceList(v interface{}) []interface{} { - var vSlice []interface{} - if v != nil { - switch v := v.(type) { - case []interface{}: - // already a slice no coercion required - vSlice = v - case []string: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []json.Number: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []bool: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []map[string]interface{}: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []float64: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []float32: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []int: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []int32: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - case []int64: - if len(v) > 0 { - vSlice = []interface{}{v[0]} - } - default: - vSlice = []interface{}{v} - } - } - return vSlice -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_field.go b/vendor/github.com/99designs/gqlgen/graphql/context_field.go deleted file mode 100644 index c06118b2c5e..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/context_field.go +++ /dev/null @@ -1,94 +0,0 @@ -package graphql - -import ( - "context" - "time" - - "github.com/vektah/gqlparser/v2/ast" -) - -type key string - -const resolverCtx key = "resolver_context" - -// Deprecated: Use FieldContext instead -type ResolverContext = FieldContext - -type FieldContext struct { - Parent *FieldContext - // The name of the type this field belongs to - Object string - // These are the args after processing, they can be mutated in middleware to change what the resolver will get. - Args map[string]interface{} - // The raw field - Field CollectedField - // The index of array in path. - Index *int - // The result object of resolver - Result interface{} - // IsMethod indicates if the resolver is a method - IsMethod bool - // IsResolver indicates if the field has a user-specified resolver - IsResolver bool -} - -type FieldStats struct { - // When field execution started - Started time.Time - - // When argument marshaling finished - ArgumentsCompleted time.Time - - // When the field completed running all middleware. Not available inside field middleware! - Completed time.Time -} - -func (r *FieldContext) Path() ast.Path { - var path ast.Path - for it := r; it != nil; it = it.Parent { - if it.Index != nil { - path = append(path, ast.PathIndex(*it.Index)) - } else if it.Field.Field != nil { - path = append(path, ast.PathName(it.Field.Alias)) - } - } - - // because we are walking up the chain, all the elements are backwards, do an inplace flip. - for i := len(path)/2 - 1; i >= 0; i-- { - opp := len(path) - 1 - i - path[i], path[opp] = path[opp], path[i] - } - - return path -} - -// Deprecated: Use GetFieldContext instead -func GetResolverContext(ctx context.Context) *ResolverContext { - return GetFieldContext(ctx) -} - -func GetFieldContext(ctx context.Context) *FieldContext { - if val, ok := ctx.Value(resolverCtx).(*FieldContext); ok { - return val - } - return nil -} - -func WithFieldContext(ctx context.Context, rc *FieldContext) context.Context { - rc.Parent = GetFieldContext(ctx) - return context.WithValue(ctx, resolverCtx, rc) -} - -func equalPath(a ast.Path, b ast.Path) bool { - if len(a) != len(b) { - return false - } - - for i := 0; i < len(a); i++ { - if a[i] != b[i] { - return false - } - } - - return true -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_operation.go b/vendor/github.com/99designs/gqlgen/graphql/context_operation.go deleted file mode 100644 index bfbbc5c002f..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/context_operation.go +++ /dev/null @@ -1,115 +0,0 @@ -package graphql - -import ( - "context" - "errors" - - "github.com/vektah/gqlparser/v2/ast" -) - -// Deprecated: Please update all references to OperationContext instead -type RequestContext = OperationContext - -type OperationContext struct { - RawQuery string - Variables map[string]interface{} - OperationName string - Doc *ast.QueryDocument - - Operation *ast.OperationDefinition - DisableIntrospection bool - RecoverFunc RecoverFunc - ResolverMiddleware FieldMiddleware - RootResolverMiddleware RootFieldMiddleware - - Stats Stats -} - -func (c *OperationContext) Validate(ctx context.Context) error { - if c.Doc == nil { - return errors.New("field 'Doc'is required") - } - if c.RawQuery == "" { - return errors.New("field 'RawQuery' is required") - } - if c.Variables == nil { - c.Variables = make(map[string]interface{}) - } - if c.ResolverMiddleware == nil { - return errors.New("field 'ResolverMiddleware' is required") - } - if c.RootResolverMiddleware == nil { - return errors.New("field 'RootResolverMiddleware' is required") - } - if c.RecoverFunc == nil { - c.RecoverFunc = DefaultRecover - } - - return nil -} - -const operationCtx key = "operation_context" - -// Deprecated: Please update all references to GetOperationContext instead -func GetRequestContext(ctx context.Context) *RequestContext { - return GetOperationContext(ctx) -} - -func GetOperationContext(ctx context.Context) *OperationContext { - if val, ok := ctx.Value(operationCtx).(*OperationContext); ok && val != nil { - return val - } - panic("missing operation context") -} - -func WithOperationContext(ctx context.Context, rc *OperationContext) context.Context { - return context.WithValue(ctx, operationCtx, rc) -} - -// HasOperationContext checks if the given context is part of an ongoing operation -// -// Some errors can happen outside of an operation, eg json unmarshal errors. -func HasOperationContext(ctx context.Context) bool { - _, ok := ctx.Value(operationCtx).(*OperationContext) - return ok -} - -// This is just a convenient wrapper method for CollectFields -func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField { - resctx := GetFieldContext(ctx) - return CollectFields(GetOperationContext(ctx), resctx.Field.Selections, satisfies) -} - -// CollectAllFields returns a slice of all GraphQL field names that were selected for the current resolver context. -// The slice will contain the unique set of all field names requested regardless of fragment type conditions. -func CollectAllFields(ctx context.Context) []string { - resctx := GetFieldContext(ctx) - collected := CollectFields(GetOperationContext(ctx), resctx.Field.Selections, nil) - uniq := make([]string, 0, len(collected)) -Next: - for _, f := range collected { - for _, name := range uniq { - if name == f.Name { - continue Next - } - } - uniq = append(uniq, f.Name) - } - return uniq -} - -// Errorf sends an error string to the client, passing it through the formatter. -// Deprecated: use graphql.AddErrorf(ctx, err) instead -func (c *OperationContext) Errorf(ctx context.Context, format string, args ...interface{}) { - AddErrorf(ctx, format, args...) -} - -// Error sends an error to the client, passing it through the formatter. -// Deprecated: use graphql.AddError(ctx, err) instead -func (c *OperationContext) Error(ctx context.Context, err error) { - AddError(ctx, err) -} - -func (c *OperationContext) Recover(ctx context.Context, err interface{}) error { - return ErrorOnPath(ctx, c.RecoverFunc(ctx, err)) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_path.go b/vendor/github.com/99designs/gqlgen/graphql/context_path.go deleted file mode 100644 index a46ed83ddc4..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/context_path.go +++ /dev/null @@ -1,77 +0,0 @@ -package graphql - -import ( - "context" - - "github.com/vektah/gqlparser/v2/ast" -) - -const fieldInputCtx key = "path_context" - -type PathContext struct { - ParentField *FieldContext - Parent *PathContext - Field *string - Index *int -} - -func (fic *PathContext) Path() ast.Path { - var path ast.Path - for it := fic; it != nil; it = it.Parent { - if it.Index != nil { - path = append(path, ast.PathIndex(*it.Index)) - } else if it.Field != nil { - path = append(path, ast.PathName(*it.Field)) - } - } - - // because we are walking up the chain, all the elements are backwards, do an inplace flip. - for i := len(path)/2 - 1; i >= 0; i-- { - opp := len(path) - 1 - i - path[i], path[opp] = path[opp], path[i] - } - - if fic.ParentField != nil { - fieldPath := fic.ParentField.Path() - return append(fieldPath, path...) - - } - - return path -} - -func NewPathWithField(field string) *PathContext { - return &PathContext{Field: &field} -} - -func NewPathWithIndex(index int) *PathContext { - return &PathContext{Index: &index} -} - -func WithPathContext(ctx context.Context, fic *PathContext) context.Context { - if fieldContext := GetFieldContext(ctx); fieldContext != nil { - fic.ParentField = fieldContext - } - if fieldInputContext := GetPathContext(ctx); fieldInputContext != nil { - fic.Parent = fieldInputContext - } - - return context.WithValue(ctx, fieldInputCtx, fic) -} - -func GetPathContext(ctx context.Context) *PathContext { - if val, ok := ctx.Value(fieldInputCtx).(*PathContext); ok { - return val - } - return nil -} - -func GetPath(ctx context.Context) ast.Path { - if pc := GetPathContext(ctx); pc != nil { - return pc.Path() - } - if fc := GetFieldContext(ctx); fc != nil { - return fc.Path() - } - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_response.go b/vendor/github.com/99designs/gqlgen/graphql/context_response.go deleted file mode 100644 index c128fdb49ce..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/context_response.go +++ /dev/null @@ -1,153 +0,0 @@ -package graphql - -import ( - "context" - "fmt" - "sync" - - "github.com/vektah/gqlparser/v2/gqlerror" -) - -type responseContext struct { - errorPresenter ErrorPresenterFunc - recover RecoverFunc - - errors gqlerror.List - errorsMu sync.Mutex - - extensions map[string]interface{} - extensionsMu sync.Mutex -} - -const resultCtx key = "result_context" - -func getResponseContext(ctx context.Context) *responseContext { - val, ok := ctx.Value(resultCtx).(*responseContext) - if !ok { - panic("missing response context") - } - return val -} - -func WithResponseContext(ctx context.Context, presenterFunc ErrorPresenterFunc, recoverFunc RecoverFunc) context.Context { - return context.WithValue(ctx, resultCtx, &responseContext{ - errorPresenter: presenterFunc, - recover: recoverFunc, - }) -} - -// AddErrorf writes a formatted error to the client, first passing it through the error presenter. -func AddErrorf(ctx context.Context, format string, args ...interface{}) { - AddError(ctx, fmt.Errorf(format, args...)) -} - -// AddError sends an error to the client, first passing it through the error presenter. -func AddError(ctx context.Context, err error) { - c := getResponseContext(ctx) - - presentedError := c.errorPresenter(ctx, ErrorOnPath(ctx, err)) - - c.errorsMu.Lock() - defer c.errorsMu.Unlock() - c.errors = append(c.errors, presentedError) -} - -func Recover(ctx context.Context, err interface{}) (userMessage error) { - c := getResponseContext(ctx) - return ErrorOnPath(ctx, c.recover(ctx, err)) -} - -// HasFieldError returns true if the given field has already errored -func HasFieldError(ctx context.Context, rctx *FieldContext) bool { - c := getResponseContext(ctx) - - c.errorsMu.Lock() - defer c.errorsMu.Unlock() - - if len(c.errors) == 0 { - return false - } - - path := rctx.Path() - for _, err := range c.errors { - if equalPath(err.Path, path) { - return true - } - } - return false -} - -// GetFieldErrors returns a list of errors that occurred in the given field -func GetFieldErrors(ctx context.Context, rctx *FieldContext) gqlerror.List { - c := getResponseContext(ctx) - - c.errorsMu.Lock() - defer c.errorsMu.Unlock() - - if len(c.errors) == 0 { - return nil - } - - path := rctx.Path() - var errs gqlerror.List - for _, err := range c.errors { - if equalPath(err.Path, path) { - errs = append(errs, err) - } - } - return errs -} - -func GetErrors(ctx context.Context) gqlerror.List { - resCtx := getResponseContext(ctx) - resCtx.errorsMu.Lock() - defer resCtx.errorsMu.Unlock() - - if len(resCtx.errors) == 0 { - return nil - } - - errs := resCtx.errors - cpy := make(gqlerror.List, len(errs)) - for i := range errs { - errCpy := *errs[i] - cpy[i] = &errCpy - } - return cpy -} - -// RegisterExtension allows you to add a new extension into the graphql response -func RegisterExtension(ctx context.Context, key string, value interface{}) { - c := getResponseContext(ctx) - c.extensionsMu.Lock() - defer c.extensionsMu.Unlock() - - if c.extensions == nil { - c.extensions = make(map[string]interface{}) - } - - if _, ok := c.extensions[key]; ok { - panic(fmt.Errorf("extension already registered for key %s", key)) - } - - c.extensions[key] = value -} - -// GetExtensions returns any extensions registered in the current result context -func GetExtensions(ctx context.Context) map[string]interface{} { - ext := getResponseContext(ctx).extensions - if ext == nil { - return map[string]interface{}{} - } - - return ext -} - -func GetExtension(ctx context.Context, name string) interface{} { - ext := getResponseContext(ctx).extensions - if ext == nil { - return nil - } - - return ext[name] -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_root_field.go b/vendor/github.com/99designs/gqlgen/graphql/context_root_field.go deleted file mode 100644 index 1bf4d13b84d..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/context_root_field.go +++ /dev/null @@ -1,25 +0,0 @@ -package graphql - -import ( - "context" -) - -const rootResolverCtx key = "root_resolver_context" - -type RootFieldContext struct { - // The name of the type this field belongs to - Object string - // The raw field - Field CollectedField -} - -func GetRootFieldContext(ctx context.Context) *RootFieldContext { - if val, ok := ctx.Value(rootResolverCtx).(*RootFieldContext); ok { - return val - } - return nil -} - -func WithRootFieldContext(ctx context.Context, rc *RootFieldContext) context.Context { - return context.WithValue(ctx, rootResolverCtx, rc) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go b/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go deleted file mode 100644 index 98b95d0050c..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go +++ /dev/null @@ -1,51 +0,0 @@ -package errcode - -import ( - "github.com/vektah/gqlparser/v2/gqlerror" -) - -const ( - ValidationFailed = "GRAPHQL_VALIDATION_FAILED" - ParseFailed = "GRAPHQL_PARSE_FAILED" -) - -type ErrorKind int - -const ( - // issues with graphql (validation, parsing). 422s in http, GQL_ERROR in websocket - KindProtocol ErrorKind = iota - // user errors, 200s in http, GQL_DATA in websocket - KindUser -) - -var codeType = map[string]ErrorKind{ - ValidationFailed: KindProtocol, - ParseFailed: KindProtocol, -} - -// RegisterErrorType should be called by extensions that want to customize the http status codes for errors they return -func RegisterErrorType(code string, kind ErrorKind) { - codeType[code] = kind -} - -// Set the error code on a given graphql error extension -func Set(err *gqlerror.Error, value string) { - if err.Extensions == nil { - err.Extensions = map[string]interface{}{} - } - - err.Extensions["code"] = value -} - -// get the kind of the first non User error, defaults to User if no errors have a custom extension -func GetErrorKind(errs gqlerror.List) ErrorKind { - for _, err := range errs { - if code, ok := err.Extensions["code"].(string); ok { - if kind, ok := codeType[code]; ok && kind != KindUser { - return kind - } - } - } - - return KindUser -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/error.go b/vendor/github.com/99designs/gqlgen/graphql/error.go deleted file mode 100644 index 4fe520b2852..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/error.go +++ /dev/null @@ -1,32 +0,0 @@ -package graphql - -import ( - "context" - "errors" - - "github.com/vektah/gqlparser/v2/gqlerror" -) - -type ErrorPresenterFunc func(ctx context.Context, err error) *gqlerror.Error - -func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error { - var gqlErr *gqlerror.Error - if errors.As(err, &gqlErr) { - return gqlErr - } - return gqlerror.WrapPath(GetPath(ctx), err) -} - -func ErrorOnPath(ctx context.Context, err error) error { - if err == nil { - return nil - } - var gqlErr *gqlerror.Error - if errors.As(err, &gqlErr) { - if gqlErr.Path == nil { - gqlErr.Path = GetPath(ctx) - } - return gqlErr - } - return gqlerror.WrapPath(GetPath(ctx), err) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go b/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go deleted file mode 100644 index 541b65fbeea..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go +++ /dev/null @@ -1,162 +0,0 @@ -//go:generate go run github.com/matryer/moq -out executable_schema_mock.go . ExecutableSchema - -package graphql - -import ( - "context" - "fmt" - - "github.com/vektah/gqlparser/v2/ast" -) - -type ExecutableSchema interface { - Schema() *ast.Schema - - Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) - Exec(ctx context.Context) ResponseHandler -} - -// CollectFields returns the set of fields from an ast.SelectionSet where all collected fields satisfy at least one of the GraphQL types -// passed through satisfies. Providing an empty or nil slice for satisfies will return collect all fields regardless of fragment -// type conditions. -func CollectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies []string) []CollectedField { - return collectFields(reqCtx, selSet, satisfies, map[string]bool{}) -} - -func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies []string, visited map[string]bool) []CollectedField { - groupedFields := make([]CollectedField, 0, len(selSet)) - - for _, sel := range selSet { - switch sel := sel.(type) { - case *ast.Field: - if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { - continue - } - f := getOrCreateAndAppendField(&groupedFields, sel.Name, sel.Alias, sel.ObjectDefinition, func() CollectedField { - return CollectedField{Field: sel} - }) - - f.Selections = append(f.Selections, sel.SelectionSet...) - - case *ast.InlineFragment: - if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { - continue - } - if len(satisfies) > 0 && !instanceOf(sel.TypeCondition, satisfies) { - continue - } - for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) { - f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) - f.Selections = append(f.Selections, childField.Selections...) - } - - case *ast.FragmentSpread: - if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { - continue - } - fragmentName := sel.Name - if _, seen := visited[fragmentName]; seen { - continue - } - visited[fragmentName] = true - - fragment := reqCtx.Doc.Fragments.ForName(fragmentName) - if fragment == nil { - // should never happen, validator has already run - panic(fmt.Errorf("missing fragment %s", fragmentName)) - } - - if len(satisfies) > 0 && !instanceOf(fragment.TypeCondition, satisfies) { - continue - } - - for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) { - f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) - f.Selections = append(f.Selections, childField.Selections...) - } - - default: - panic(fmt.Errorf("unsupported %T", sel)) - } - } - - return groupedFields -} - -type CollectedField struct { - *ast.Field - - Selections ast.SelectionSet -} - -func instanceOf(val string, satisfies []string) bool { - for _, s := range satisfies { - if val == s { - return true - } - } - return false -} - -func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { - for i, cf := range *c { - if cf.Name == name && cf.Alias == alias { - if cf.ObjectDefinition == objectDefinition { - return &(*c)[i] - } - - if cf.ObjectDefinition == nil || objectDefinition == nil { - continue - } - - if cf.ObjectDefinition.Name == objectDefinition.Name { - return &(*c)[i] - } - - for _, ifc := range objectDefinition.Interfaces { - if ifc == cf.ObjectDefinition.Name { - return &(*c)[i] - } - } - } - } - - f := creator() - - *c = append(*c, f) - return &(*c)[len(*c)-1] -} - -func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interface{}) bool { - if len(directives) == 0 { - return true - } - - skip, include := false, true - - if d := directives.ForName("skip"); d != nil { - skip = resolveIfArgument(d, variables) - } - - if d := directives.ForName("include"); d != nil { - include = resolveIfArgument(d, variables) - } - - return !skip && include -} - -func resolveIfArgument(d *ast.Directive, variables map[string]interface{}) bool { - arg := d.Arguments.ForName("if") - if arg == nil { - panic(fmt.Sprintf("%s: argument 'if' not defined", d.Name)) - } - value, err := arg.Value.Value(variables) - if err != nil { - panic(err) - } - ret, ok := value.(bool) - if !ok { - panic(fmt.Sprintf("%s: argument 'if' is not a boolean", d.Name)) - } - return ret -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go b/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go deleted file mode 100644 index 5d7433162fe..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go +++ /dev/null @@ -1,172 +0,0 @@ -// Code generated by moq; DO NOT EDIT. -// github.com/matryer/moq - -package graphql - -import ( - "context" - "github.com/vektah/gqlparser/v2/ast" - "sync" -) - -// Ensure, that ExecutableSchemaMock does implement ExecutableSchema. -// If this is not the case, regenerate this file with moq. -var _ ExecutableSchema = &ExecutableSchemaMock{} - -// ExecutableSchemaMock is a mock implementation of ExecutableSchema. -// -// func TestSomethingThatUsesExecutableSchema(t *testing.T) { -// -// // make and configure a mocked ExecutableSchema -// mockedExecutableSchema := &ExecutableSchemaMock{ -// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { -// panic("mock out the Complexity method") -// }, -// ExecFunc: func(ctx context.Context) ResponseHandler { -// panic("mock out the Exec method") -// }, -// SchemaFunc: func() *ast.Schema { -// panic("mock out the Schema method") -// }, -// } -// -// // use mockedExecutableSchema in code that requires ExecutableSchema -// // and then make assertions. -// -// } -type ExecutableSchemaMock struct { - // ComplexityFunc mocks the Complexity method. - ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) - - // ExecFunc mocks the Exec method. - ExecFunc func(ctx context.Context) ResponseHandler - - // SchemaFunc mocks the Schema method. - SchemaFunc func() *ast.Schema - - // calls tracks calls to the methods. - calls struct { - // Complexity holds details about calls to the Complexity method. - Complexity []struct { - // TypeName is the typeName argument value. - TypeName string - // FieldName is the fieldName argument value. - FieldName string - // ChildComplexity is the childComplexity argument value. - ChildComplexity int - // Args is the args argument value. - Args map[string]interface{} - } - // Exec holds details about calls to the Exec method. - Exec []struct { - // Ctx is the ctx argument value. - Ctx context.Context - } - // Schema holds details about calls to the Schema method. - Schema []struct { - } - } - lockComplexity sync.RWMutex - lockExec sync.RWMutex - lockSchema sync.RWMutex -} - -// Complexity calls ComplexityFunc. -func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { - if mock.ComplexityFunc == nil { - panic("ExecutableSchemaMock.ComplexityFunc: method is nil but ExecutableSchema.Complexity was just called") - } - callInfo := struct { - TypeName string - FieldName string - ChildComplexity int - Args map[string]interface{} - }{ - TypeName: typeName, - FieldName: fieldName, - ChildComplexity: childComplexity, - Args: args, - } - mock.lockComplexity.Lock() - mock.calls.Complexity = append(mock.calls.Complexity, callInfo) - mock.lockComplexity.Unlock() - return mock.ComplexityFunc(typeName, fieldName, childComplexity, args) -} - -// ComplexityCalls gets all the calls that were made to Complexity. -// Check the length with: -// len(mockedExecutableSchema.ComplexityCalls()) -func (mock *ExecutableSchemaMock) ComplexityCalls() []struct { - TypeName string - FieldName string - ChildComplexity int - Args map[string]interface{} -} { - var calls []struct { - TypeName string - FieldName string - ChildComplexity int - Args map[string]interface{} - } - mock.lockComplexity.RLock() - calls = mock.calls.Complexity - mock.lockComplexity.RUnlock() - return calls -} - -// Exec calls ExecFunc. -func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler { - if mock.ExecFunc == nil { - panic("ExecutableSchemaMock.ExecFunc: method is nil but ExecutableSchema.Exec was just called") - } - callInfo := struct { - Ctx context.Context - }{ - Ctx: ctx, - } - mock.lockExec.Lock() - mock.calls.Exec = append(mock.calls.Exec, callInfo) - mock.lockExec.Unlock() - return mock.ExecFunc(ctx) -} - -// ExecCalls gets all the calls that were made to Exec. -// Check the length with: -// len(mockedExecutableSchema.ExecCalls()) -func (mock *ExecutableSchemaMock) ExecCalls() []struct { - Ctx context.Context -} { - var calls []struct { - Ctx context.Context - } - mock.lockExec.RLock() - calls = mock.calls.Exec - mock.lockExec.RUnlock() - return calls -} - -// Schema calls SchemaFunc. -func (mock *ExecutableSchemaMock) Schema() *ast.Schema { - if mock.SchemaFunc == nil { - panic("ExecutableSchemaMock.SchemaFunc: method is nil but ExecutableSchema.Schema was just called") - } - callInfo := struct { - }{} - mock.lockSchema.Lock() - mock.calls.Schema = append(mock.calls.Schema, callInfo) - mock.lockSchema.Unlock() - return mock.SchemaFunc() -} - -// SchemaCalls gets all the calls that were made to Schema. -// Check the length with: -// len(mockedExecutableSchema.SchemaCalls()) -func (mock *ExecutableSchemaMock) SchemaCalls() []struct { -} { - var calls []struct { - } - mock.lockSchema.RLock() - calls = mock.calls.Schema - mock.lockSchema.RUnlock() - return calls -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go b/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go deleted file mode 100644 index 95a28031148..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go +++ /dev/null @@ -1,192 +0,0 @@ -package executor - -import ( - "context" - - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/gqlerror" - "github.com/vektah/gqlparser/v2/parser" - "github.com/vektah/gqlparser/v2/validator" -) - -// Executor executes graphql queries against a schema. -type Executor struct { - es graphql.ExecutableSchema - extensions []graphql.HandlerExtension - ext extensions - - errorPresenter graphql.ErrorPresenterFunc - recoverFunc graphql.RecoverFunc - queryCache graphql.Cache -} - -var _ graphql.GraphExecutor = &Executor{} - -// New creates a new Executor with the given schema, and a default error and -// recovery callbacks, and no query cache or extensions. -func New(es graphql.ExecutableSchema) *Executor { - e := &Executor{ - es: es, - errorPresenter: graphql.DefaultErrorPresenter, - recoverFunc: graphql.DefaultRecover, - queryCache: graphql.NoCache{}, - ext: processExtensions(nil), - } - return e -} - -func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.RawParams) (*graphql.OperationContext, gqlerror.List) { - rc := &graphql.OperationContext{ - DisableIntrospection: true, - RecoverFunc: e.recoverFunc, - ResolverMiddleware: e.ext.fieldMiddleware, - RootResolverMiddleware: e.ext.rootFieldMiddleware, - Stats: graphql.Stats{ - Read: params.ReadTime, - OperationStart: graphql.GetStartTime(ctx), - }, - } - ctx = graphql.WithOperationContext(ctx, rc) - - for _, p := range e.ext.operationParameterMutators { - if err := p.MutateOperationParameters(ctx, params); err != nil { - return rc, gqlerror.List{err} - } - } - - rc.RawQuery = params.Query - rc.OperationName = params.OperationName - - var listErr gqlerror.List - rc.Doc, listErr = e.parseQuery(ctx, &rc.Stats, params.Query) - if len(listErr) != 0 { - return rc, listErr - } - - rc.Operation = rc.Doc.Operations.ForName(params.OperationName) - if rc.Operation == nil { - return rc, gqlerror.List{gqlerror.Errorf("operation %s not found", params.OperationName)} - } - - var err *gqlerror.Error - rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables) - if err != nil { - errcode.Set(err, errcode.ValidationFailed) - return rc, gqlerror.List{err} - } - rc.Stats.Validation.End = graphql.Now() - - for _, p := range e.ext.operationContextMutators { - if err := p.MutateOperationContext(ctx, rc); err != nil { - return rc, gqlerror.List{err} - } - } - - return rc, nil -} - -func (e *Executor) DispatchOperation(ctx context.Context, rc *graphql.OperationContext) (graphql.ResponseHandler, context.Context) { - ctx = graphql.WithOperationContext(ctx, rc) - - var innerCtx context.Context - res := e.ext.operationMiddleware(ctx, func(ctx context.Context) graphql.ResponseHandler { - innerCtx = ctx - - tmpResponseContext := graphql.WithResponseContext(ctx, e.errorPresenter, e.recoverFunc) - responses := e.es.Exec(tmpResponseContext) - if errs := graphql.GetErrors(tmpResponseContext); errs != nil { - return graphql.OneShot(&graphql.Response{Errors: errs}) - } - - return func(ctx context.Context) *graphql.Response { - ctx = graphql.WithResponseContext(ctx, e.errorPresenter, e.recoverFunc) - resp := e.ext.responseMiddleware(ctx, func(ctx context.Context) *graphql.Response { - resp := responses(ctx) - if resp == nil { - return nil - } - resp.Errors = append(resp.Errors, graphql.GetErrors(ctx)...) - resp.Extensions = graphql.GetExtensions(ctx) - return resp - }) - if resp == nil { - return nil - } - - return resp - } - }) - - return res, innerCtx -} - -func (e *Executor) DispatchError(ctx context.Context, list gqlerror.List) *graphql.Response { - ctx = graphql.WithResponseContext(ctx, e.errorPresenter, e.recoverFunc) - for _, gErr := range list { - graphql.AddError(ctx, gErr) - } - - resp := e.ext.responseMiddleware(ctx, func(ctx context.Context) *graphql.Response { - resp := &graphql.Response{ - Errors: list, - } - resp.Extensions = graphql.GetExtensions(ctx) - return resp - }) - - return resp -} - -func (e *Executor) PresentRecoveredError(ctx context.Context, err interface{}) *gqlerror.Error { - return e.errorPresenter(ctx, e.recoverFunc(ctx, err)) -} - -func (e *Executor) SetQueryCache(cache graphql.Cache) { - e.queryCache = cache -} - -func (e *Executor) SetErrorPresenter(f graphql.ErrorPresenterFunc) { - e.errorPresenter = f -} - -func (e *Executor) SetRecoverFunc(f graphql.RecoverFunc) { - e.recoverFunc = f -} - -// parseQuery decodes the incoming query and validates it, pulling from cache if present. -// -// NOTE: This should NOT look at variables, they will change per request. It should only parse and validate -// the raw query string. -func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query string) (*ast.QueryDocument, gqlerror.List) { - stats.Parsing.Start = graphql.Now() - - if doc, ok := e.queryCache.Get(ctx, query); ok { - now := graphql.Now() - - stats.Parsing.End = now - stats.Validation.Start = now - return doc.(*ast.QueryDocument), nil - } - - doc, err := parser.ParseQuery(&ast.Source{Input: query}) - if err != nil { - errcode.Set(err, errcode.ParseFailed) - return nil, gqlerror.List{err} - } - stats.Parsing.End = graphql.Now() - - stats.Validation.Start = graphql.Now() - listErr := validator.Validate(e.es.Schema(), doc) - if len(listErr) != 0 { - for _, e := range listErr { - errcode.Set(e, errcode.ValidationFailed) - } - return nil, listErr - } - - e.queryCache.Add(ctx, query, doc) - - return doc, nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go b/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go deleted file mode 100644 index a8eebf110c4..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go +++ /dev/null @@ -1,195 +0,0 @@ -package executor - -import ( - "context" - "fmt" - - "github.com/99designs/gqlgen/graphql" -) - -// Use adds the given extension to this Executor. -func (e *Executor) Use(extension graphql.HandlerExtension) { - if err := extension.Validate(e.es); err != nil { - panic(err) - } - - switch extension.(type) { - case graphql.OperationParameterMutator, - graphql.OperationContextMutator, - graphql.OperationInterceptor, - graphql.RootFieldInterceptor, - graphql.FieldInterceptor, - graphql.ResponseInterceptor: - e.extensions = append(e.extensions, extension) - e.ext = processExtensions(e.extensions) - - default: - panic(fmt.Errorf("cannot Use %T as a gqlgen handler extension because it does not implement any extension hooks", extension)) - } -} - -// AroundFields is a convenience method for creating an extension that only implements field middleware -func (e *Executor) AroundFields(f graphql.FieldMiddleware) { - e.Use(aroundFieldFunc(f)) -} - -// AroundRootFields is a convenience method for creating an extension that only implements root field middleware -func (e *Executor) AroundRootFields(f graphql.RootFieldMiddleware) { - e.Use(aroundRootFieldFunc(f)) -} - -// AroundOperations is a convenience method for creating an extension that only implements operation middleware -func (e *Executor) AroundOperations(f graphql.OperationMiddleware) { - e.Use(aroundOpFunc(f)) -} - -// AroundResponses is a convenience method for creating an extension that only implements response middleware -func (e *Executor) AroundResponses(f graphql.ResponseMiddleware) { - e.Use(aroundRespFunc(f)) -} - -type extensions struct { - operationMiddleware graphql.OperationMiddleware - responseMiddleware graphql.ResponseMiddleware - rootFieldMiddleware graphql.RootFieldMiddleware - fieldMiddleware graphql.FieldMiddleware - operationParameterMutators []graphql.OperationParameterMutator - operationContextMutators []graphql.OperationContextMutator -} - -func processExtensions(exts []graphql.HandlerExtension) extensions { - e := extensions{ - operationMiddleware: func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { - return next(ctx) - }, - responseMiddleware: func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { - return next(ctx) - }, - rootFieldMiddleware: func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { - return next(ctx) - }, - fieldMiddleware: func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - return next(ctx) - }, - } - - // this loop goes backwards so the first extension is the outer most middleware and runs first. - for i := len(exts) - 1; i >= 0; i-- { - p := exts[i] - if p, ok := p.(graphql.OperationInterceptor); ok { - previous := e.operationMiddleware - e.operationMiddleware = func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { - return p.InterceptOperation(ctx, func(ctx context.Context) graphql.ResponseHandler { - return previous(ctx, next) - }) - } - } - - if p, ok := p.(graphql.ResponseInterceptor); ok { - previous := e.responseMiddleware - e.responseMiddleware = func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { - return p.InterceptResponse(ctx, func(ctx context.Context) *graphql.Response { - return previous(ctx, next) - }) - } - } - - if p, ok := p.(graphql.RootFieldInterceptor); ok { - previous := e.rootFieldMiddleware - e.rootFieldMiddleware = func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { - return p.InterceptRootField(ctx, func(ctx context.Context) graphql.Marshaler { - return previous(ctx, next) - }) - } - } - - if p, ok := p.(graphql.FieldInterceptor); ok { - previous := e.fieldMiddleware - e.fieldMiddleware = func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - return p.InterceptField(ctx, func(ctx context.Context) (res interface{}, err error) { - return previous(ctx, next) - }) - } - } - } - - for _, p := range exts { - if p, ok := p.(graphql.OperationParameterMutator); ok { - e.operationParameterMutators = append(e.operationParameterMutators, p) - } - - if p, ok := p.(graphql.OperationContextMutator); ok { - e.operationContextMutators = append(e.operationContextMutators, p) - } - } - - return e -} - -type aroundOpFunc func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler - -func (r aroundOpFunc) ExtensionName() string { - return "InlineOperationFunc" -} - -func (r aroundOpFunc) Validate(schema graphql.ExecutableSchema) error { - if r == nil { - return fmt.Errorf("OperationFunc can not be nil") - } - return nil -} - -func (r aroundOpFunc) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { - return r(ctx, next) -} - -type aroundRespFunc func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response - -func (r aroundRespFunc) ExtensionName() string { - return "InlineResponseFunc" -} - -func (r aroundRespFunc) Validate(schema graphql.ExecutableSchema) error { - if r == nil { - return fmt.Errorf("ResponseFunc can not be nil") - } - return nil -} - -func (r aroundRespFunc) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { - return r(ctx, next) -} - -type aroundFieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) - -func (f aroundFieldFunc) ExtensionName() string { - return "InlineFieldFunc" -} - -func (f aroundFieldFunc) Validate(schema graphql.ExecutableSchema) error { - if f == nil { - return fmt.Errorf("FieldFunc can not be nil") - } - return nil -} - -func (f aroundFieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - return f(ctx, next) -} - -type aroundRootFieldFunc func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler - -func (f aroundRootFieldFunc) ExtensionName() string { - return "InlineRootFieldFunc" -} - -func (f aroundRootFieldFunc) Validate(schema graphql.ExecutableSchema) error { - if f == nil { - return fmt.Errorf("RootFieldFunc can not be nil") - } - return nil -} - -func (f aroundRootFieldFunc) InterceptRootField(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { - return f(ctx, next) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/fieldset.go b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go deleted file mode 100644 index 351e266fdb3..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/fieldset.go +++ /dev/null @@ -1,63 +0,0 @@ -package graphql - -import ( - "io" - "sync" -) - -type FieldSet struct { - fields []CollectedField - Values []Marshaler - delayed []delayedResult -} - -type delayedResult struct { - i int - f func() Marshaler -} - -func NewFieldSet(fields []CollectedField) *FieldSet { - return &FieldSet{ - fields: fields, - Values: make([]Marshaler, len(fields)), - } -} - -func (m *FieldSet) Concurrently(i int, f func() Marshaler) { - m.delayed = append(m.delayed, delayedResult{i: i, f: f}) -} - -func (m *FieldSet) Dispatch() { - if len(m.delayed) == 1 { - // only one concurrent task, no need to spawn a goroutine or deal create waitgroups - d := m.delayed[0] - m.Values[d.i] = d.f() - } else if len(m.delayed) > 1 { - // more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others - - var wg sync.WaitGroup - for _, d := range m.delayed[1:] { - wg.Add(1) - go func(d delayedResult) { - m.Values[d.i] = d.f() - wg.Done() - }(d) - } - - m.Values[m.delayed[0].i] = m.delayed[0].f() - wg.Wait() - } -} - -func (m *FieldSet) MarshalGQL(writer io.Writer) { - writer.Write(openBrace) - for i, field := range m.fields { - if i != 0 { - writer.Write(comma) - } - writeQuotedString(writer, field.Alias) - writer.Write(colon) - m.Values[i].MarshalGQL(writer) - } - writer.Write(closeBrace) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/float.go b/vendor/github.com/99designs/gqlgen/graphql/float.go deleted file mode 100644 index ccb825ddb8b..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/float.go +++ /dev/null @@ -1,47 +0,0 @@ -package graphql - -import ( - "context" - "encoding/json" - "fmt" - "io" - "math" - "strconv" -) - -func MarshalFloat(f float64) Marshaler { - return WriterFunc(func(w io.Writer) { - io.WriteString(w, fmt.Sprintf("%g", f)) - }) -} - -func UnmarshalFloat(v interface{}) (float64, error) { - switch v := v.(type) { - case string: - return strconv.ParseFloat(v, 64) - case int: - return float64(v), nil - case int64: - return float64(v), nil - case float64: - return v, nil - case json.Number: - return strconv.ParseFloat(string(v), 64) - default: - return 0, fmt.Errorf("%T is not an float", v) - } -} - -func MarshalFloatContext(f float64) ContextMarshaler { - return ContextWriterFunc(func(ctx context.Context, w io.Writer) error { - if math.IsInf(f, 0) || math.IsNaN(f) { - return fmt.Errorf("cannot marshal infinite no NaN float values") - } - io.WriteString(w, fmt.Sprintf("%g", f)) - return nil - }) -} - -func UnmarshalFloatContext(ctx context.Context, v interface{}) (float64, error) { - return UnmarshalFloat(v) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler.go b/vendor/github.com/99designs/gqlgen/graphql/handler.go deleted file mode 100644 index 921165978c2..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler.go +++ /dev/null @@ -1,130 +0,0 @@ -package graphql - -import ( - "context" - "net/http" - "strconv" - "strings" - - "github.com/vektah/gqlparser/v2/gqlerror" -) - -type ( - OperationMiddleware func(ctx context.Context, next OperationHandler) ResponseHandler - OperationHandler func(ctx context.Context) ResponseHandler - - ResponseHandler func(ctx context.Context) *Response - ResponseMiddleware func(ctx context.Context, next ResponseHandler) *Response - - Resolver func(ctx context.Context) (res interface{}, err error) - FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error) - - RootResolver func(ctx context.Context) Marshaler - RootFieldMiddleware func(ctx context.Context, next RootResolver) Marshaler - - RawParams struct { - Query string `json:"query"` - OperationName string `json:"operationName"` - Variables map[string]interface{} `json:"variables"` - Extensions map[string]interface{} `json:"extensions"` - - ReadTime TraceTiming `json:"-"` - } - - GraphExecutor interface { - CreateOperationContext(ctx context.Context, params *RawParams) (*OperationContext, gqlerror.List) - DispatchOperation(ctx context.Context, rc *OperationContext) (ResponseHandler, context.Context) - DispatchError(ctx context.Context, list gqlerror.List) *Response - } - - // HandlerExtension adds functionality to the http handler. See the list of possible hook points below - // Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen - // before working with these - // - // +--- REQUEST POST /graphql --------------------------------------------+ - // | +- OPERATION query OpName { viewer { name } } -----------------------+ | - // | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | | - // | +- OPERATION subscription OpName2 { chat { message } } --------------+ | - // | | RESPONSE { "data": { "chat": { "message": "hello" } } } | | - // | | RESPONSE { "data": { "chat": { "message": "byee" } } } | | - // | +--------------------------------------------------------------------+ | - // +------------------------------------------------------------------------+ - HandlerExtension interface { - // ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging. - ExtensionName() string - // Validate is called when adding an extension to the server, it allows validation against the servers schema. - Validate(schema ExecutableSchema) error - } - - // OperationParameterMutator is called before creating a request context. allows manipulating the raw query - // on the way in. - OperationParameterMutator interface { - MutateOperationParameters(ctx context.Context, request *RawParams) *gqlerror.Error - } - - // OperationContextMutator is called after creating the request context, but before executing the root resolver. - OperationContextMutator interface { - MutateOperationContext(ctx context.Context, rc *OperationContext) *gqlerror.Error - } - - // OperationInterceptor is called for each incoming query, for basic requests the writer will be invoked once, - // for subscriptions it will be invoked multiple times. - OperationInterceptor interface { - InterceptOperation(ctx context.Context, next OperationHandler) ResponseHandler - } - - // ResponseInterceptor is called around each graphql operation response. This can be called many times for a single - // operation the case of subscriptions. - ResponseInterceptor interface { - InterceptResponse(ctx context.Context, next ResponseHandler) *Response - } - - RootFieldInterceptor interface { - InterceptRootField(ctx context.Context, next RootResolver) Marshaler - } - - // FieldInterceptor called around each field - FieldInterceptor interface { - InterceptField(ctx context.Context, next Resolver) (res interface{}, err error) - } - - // Transport provides support for different wire level encodings of graphql requests, eg Form, Get, Post, Websocket - Transport interface { - Supports(r *http.Request) bool - Do(w http.ResponseWriter, r *http.Request, exec GraphExecutor) - } -) - -type Status int - -func (p *RawParams) AddUpload(upload Upload, key, path string) *gqlerror.Error { - if !strings.HasPrefix(path, "variables.") { - return gqlerror.Errorf("invalid operations paths for key %s", key) - } - - var ptr interface{} = p.Variables - parts := strings.Split(path, ".") - - // skip the first part (variables) because we started there - for i, p := range parts[1:] { - last := i == len(parts)-2 - if ptr == nil { - return gqlerror.Errorf("path is missing \"variables.\" prefix, key: %s, path: %s", key, path) - } - if index, parseNbrErr := strconv.Atoi(p); parseNbrErr == nil { - if last { - ptr.([]interface{})[index] = upload - } else { - ptr = ptr.([]interface{})[index] - } - } else { - if last { - ptr.(map[string]interface{})[p] = upload - } else { - ptr = ptr.(map[string]interface{})[p] - } - } - } - - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go deleted file mode 100644 index 866276eed99..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go +++ /dev/null @@ -1,114 +0,0 @@ -package extension - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "fmt" - - "github.com/99designs/gqlgen/graphql/errcode" - - "github.com/vektah/gqlparser/v2/gqlerror" - - "github.com/99designs/gqlgen/graphql" - "github.com/mitchellh/mapstructure" -) - -const ( - errPersistedQueryNotFound = "PersistedQueryNotFound" - errPersistedQueryNotFoundCode = "PERSISTED_QUERY_NOT_FOUND" -) - -// AutomaticPersistedQuery saves client upload by optimistically sending only the hashes of queries, if the server -// does not yet know what the query is for the hash it will respond telling the client to send the query along with the -// hash in the next request. -// see https://github.com/apollographql/apollo-link-persisted-queries -type AutomaticPersistedQuery struct { - Cache graphql.Cache -} - -type ApqStats struct { - // The hash of the incoming query - Hash string - - // SentQuery is true if the incoming request sent the full query - SentQuery bool -} - -const apqExtension = "APQ" - -var _ interface { - graphql.OperationParameterMutator - graphql.HandlerExtension -} = AutomaticPersistedQuery{} - -func (a AutomaticPersistedQuery) ExtensionName() string { - return "AutomaticPersistedQuery" -} - -func (a AutomaticPersistedQuery) Validate(schema graphql.ExecutableSchema) error { - if a.Cache == nil { - return fmt.Errorf("AutomaticPersistedQuery.Cache can not be nil") - } - return nil -} - -func (a AutomaticPersistedQuery) MutateOperationParameters(ctx context.Context, rawParams *graphql.RawParams) *gqlerror.Error { - if rawParams.Extensions["persistedQuery"] == nil { - return nil - } - - var extension struct { - Sha256 string `mapstructure:"sha256Hash"` - Version int64 `mapstructure:"version"` - } - - if err := mapstructure.Decode(rawParams.Extensions["persistedQuery"], &extension); err != nil { - return gqlerror.Errorf("invalid APQ extension data") - } - - if extension.Version != 1 { - return gqlerror.Errorf("unsupported APQ version") - } - - fullQuery := false - if rawParams.Query == "" { - // client sent optimistic query hash without query string, get it from the cache - query, ok := a.Cache.Get(ctx, extension.Sha256) - if !ok { - err := gqlerror.Errorf(errPersistedQueryNotFound) - errcode.Set(err, errPersistedQueryNotFoundCode) - return err - } - rawParams.Query = query.(string) - } else { - // client sent optimistic query hash with query string, verify and store it - if computeQueryHash(rawParams.Query) != extension.Sha256 { - return gqlerror.Errorf("provided APQ hash does not match query") - } - a.Cache.Add(ctx, extension.Sha256, rawParams.Query) - fullQuery = true - } - - graphql.GetOperationContext(ctx).Stats.SetExtension(apqExtension, &ApqStats{ - Hash: extension.Sha256, - SentQuery: fullQuery, - }) - - return nil -} - -func GetApqStats(ctx context.Context) *ApqStats { - rc := graphql.GetOperationContext(ctx) - if rc == nil { - return nil - } - - s, _ := rc.Stats.GetExtension(apqExtension).(*ApqStats) - return s -} - -func computeQueryHash(query string) string { - b := sha256.Sum256([]byte(query)) - return hex.EncodeToString(b[:]) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go deleted file mode 100644 index 2d853802bf3..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go +++ /dev/null @@ -1,88 +0,0 @@ -package extension - -import ( - "context" - "fmt" - - "github.com/99designs/gqlgen/complexity" - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -const errComplexityLimit = "COMPLEXITY_LIMIT_EXCEEDED" - -// ComplexityLimit allows you to define a limit on query complexity -// -// If a query is submitted that exceeds the limit, a 422 status code will be returned. -type ComplexityLimit struct { - Func func(ctx context.Context, rc *graphql.OperationContext) int - - es graphql.ExecutableSchema -} - -var _ interface { - graphql.OperationContextMutator - graphql.HandlerExtension -} = &ComplexityLimit{} - -const complexityExtension = "ComplexityLimit" - -type ComplexityStats struct { - // The calculated complexity for this request - Complexity int - - // The complexity limit for this request returned by the extension func - ComplexityLimit int -} - -// FixedComplexityLimit sets a complexity limit that does not change -func FixedComplexityLimit(limit int) *ComplexityLimit { - return &ComplexityLimit{ - Func: func(ctx context.Context, rc *graphql.OperationContext) int { - return limit - }, - } -} - -func (c ComplexityLimit) ExtensionName() string { - return complexityExtension -} - -func (c *ComplexityLimit) Validate(schema graphql.ExecutableSchema) error { - if c.Func == nil { - return fmt.Errorf("ComplexityLimit func can not be nil") - } - c.es = schema - return nil -} - -func (c ComplexityLimit) MutateOperationContext(ctx context.Context, rc *graphql.OperationContext) *gqlerror.Error { - op := rc.Doc.Operations.ForName(rc.OperationName) - complexity := complexity.Calculate(c.es, op, rc.Variables) - - limit := c.Func(ctx, rc) - - rc.Stats.SetExtension(complexityExtension, &ComplexityStats{ - Complexity: complexity, - ComplexityLimit: limit, - }) - - if complexity > limit { - err := gqlerror.Errorf("operation has complexity %d, which exceeds the limit of %d", complexity, limit) - errcode.Set(err, errComplexityLimit) - return err - } - - return nil -} - -func GetComplexityStats(ctx context.Context) *ComplexityStats { - rc := graphql.GetOperationContext(ctx) - if rc == nil { - return nil - } - - s, _ := rc.Stats.GetExtension(complexityExtension).(*ComplexityStats) - return s -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go deleted file mode 100644 index acc5db2fbcc..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go +++ /dev/null @@ -1,29 +0,0 @@ -package extension - -import ( - "context" - - "github.com/99designs/gqlgen/graphql" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -// EnableIntrospection enables clients to reflect all of the types available on the graph. -type Introspection struct{} - -var _ interface { - graphql.OperationContextMutator - graphql.HandlerExtension -} = Introspection{} - -func (c Introspection) ExtensionName() string { - return "Introspection" -} - -func (c Introspection) Validate(schema graphql.ExecutableSchema) error { - return nil -} - -func (c Introspection) MutateOperationContext(ctx context.Context, rc *graphql.OperationContext) *gqlerror.Error { - rc.DisableIntrospection = false - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go b/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go deleted file mode 100644 index e2b1561acbb..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go +++ /dev/null @@ -1,32 +0,0 @@ -package lru - -import ( - "context" - - "github.com/99designs/gqlgen/graphql" - lru "github.com/hashicorp/golang-lru" -) - -type LRU struct { - lru *lru.Cache -} - -var _ graphql.Cache = &LRU{} - -func New(size int) *LRU { - cache, err := lru.New(size) - if err != nil { - // An error is only returned for non-positive cache size - // and we already checked for that. - panic("unexpected error creating cache: " + err.Error()) - } - return &LRU{cache} -} - -func (l LRU) Get(ctx context.Context, key string) (value interface{}, ok bool) { - return l.lru.Get(key) -} - -func (l LRU) Add(ctx context.Context, key string, value interface{}) { - l.lru.Add(key, value) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go deleted file mode 100644 index 69530bbc552..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go +++ /dev/null @@ -1,185 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "time" - - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/executor" - "github.com/99designs/gqlgen/graphql/handler/extension" - "github.com/99designs/gqlgen/graphql/handler/lru" - "github.com/99designs/gqlgen/graphql/handler/transport" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -type ( - Server struct { - transports []graphql.Transport - exec *executor.Executor - } -) - -func New(es graphql.ExecutableSchema) *Server { - return &Server{ - exec: executor.New(es), - } -} - -func NewDefaultServer(es graphql.ExecutableSchema) *Server { - srv := New(es) - - srv.AddTransport(transport.Websocket{ - KeepAlivePingInterval: 10 * time.Second, - }) - srv.AddTransport(transport.Options{}) - srv.AddTransport(transport.GET{}) - srv.AddTransport(transport.POST{}) - srv.AddTransport(transport.MultipartForm{}) - - srv.SetQueryCache(lru.New(1000)) - - srv.Use(extension.Introspection{}) - srv.Use(extension.AutomaticPersistedQuery{ - Cache: lru.New(100), - }) - - return srv -} - -func (s *Server) AddTransport(transport graphql.Transport) { - s.transports = append(s.transports, transport) -} - -func (s *Server) SetErrorPresenter(f graphql.ErrorPresenterFunc) { - s.exec.SetErrorPresenter(f) -} - -func (s *Server) SetRecoverFunc(f graphql.RecoverFunc) { - s.exec.SetRecoverFunc(f) -} - -func (s *Server) SetQueryCache(cache graphql.Cache) { - s.exec.SetQueryCache(cache) -} - -func (s *Server) Use(extension graphql.HandlerExtension) { - s.exec.Use(extension) -} - -// AroundFields is a convenience method for creating an extension that only implements field middleware -func (s *Server) AroundFields(f graphql.FieldMiddleware) { - s.exec.AroundFields(f) -} - -// AroundRootFields is a convenience method for creating an extension that only implements field middleware -func (s *Server) AroundRootFields(f graphql.RootFieldMiddleware) { - s.exec.AroundRootFields(f) -} - -// AroundOperations is a convenience method for creating an extension that only implements operation middleware -func (s *Server) AroundOperations(f graphql.OperationMiddleware) { - s.exec.AroundOperations(f) -} - -// AroundResponses is a convenience method for creating an extension that only implements response middleware -func (s *Server) AroundResponses(f graphql.ResponseMiddleware) { - s.exec.AroundResponses(f) -} - -func (s *Server) getTransport(r *http.Request) graphql.Transport { - for _, t := range s.transports { - if t.Supports(r) { - return t - } - } - return nil -} - -func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { - defer func() { - if err := recover(); err != nil { - err := s.exec.PresentRecoveredError(r.Context(), err) - resp := &graphql.Response{Errors: []*gqlerror.Error{err}} - b, _ := json.Marshal(resp) - w.WriteHeader(http.StatusUnprocessableEntity) - w.Write(b) - } - }() - - r = r.WithContext(graphql.StartOperationTrace(r.Context())) - - transport := s.getTransport(r) - if transport == nil { - sendErrorf(w, http.StatusBadRequest, "transport not supported") - return - } - - transport.Do(w, r, s.exec) -} - -func sendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) { - w.WriteHeader(code) - b, err := json.Marshal(&graphql.Response{Errors: errors}) - if err != nil { - panic(err) - } - w.Write(b) -} - -func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { - sendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)}) -} - -type OperationFunc func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler - -func (r OperationFunc) ExtensionName() string { - return "InlineOperationFunc" -} - -func (r OperationFunc) Validate(schema graphql.ExecutableSchema) error { - if r == nil { - return fmt.Errorf("OperationFunc can not be nil") - } - return nil -} - -func (r OperationFunc) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { - return r(ctx, next) -} - -type ResponseFunc func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response - -func (r ResponseFunc) ExtensionName() string { - return "InlineResponseFunc" -} - -func (r ResponseFunc) Validate(schema graphql.ExecutableSchema) error { - if r == nil { - return fmt.Errorf("ResponseFunc can not be nil") - } - return nil -} - -func (r ResponseFunc) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { - return r(ctx, next) -} - -type FieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) - -func (f FieldFunc) ExtensionName() string { - return "InlineFieldFunc" -} - -func (f FieldFunc) Validate(schema graphql.ExecutableSchema) error { - if f == nil { - return fmt.Errorf("FieldFunc can not be nil") - } - return nil -} - -func (f FieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - return f(ctx, next) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go deleted file mode 100644 index b1aeaf144dd..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go +++ /dev/null @@ -1,26 +0,0 @@ -package transport - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/99designs/gqlgen/graphql" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -// SendError sends a best effort error to a raw response writer. It assumes the client can understand the standard -// json error response -func SendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) { - w.WriteHeader(code) - b, err := json.Marshal(&graphql.Response{Errors: errors}) - if err != nil { - panic(err) - } - w.Write(b) -} - -// SendErrorf wraps SendError to add formatted messages -func SendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { - SendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)}) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go deleted file mode 100644 index 3874eef4838..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go +++ /dev/null @@ -1,208 +0,0 @@ -package transport - -import ( - "encoding/json" - "io" - "io/ioutil" - "mime" - "net/http" - "os" - "strings" - - "github.com/99designs/gqlgen/graphql" -) - -// MultipartForm the Multipart request spec https://github.com/jaydenseric/graphql-multipart-request-spec -type MultipartForm struct { - // MaxUploadSize sets the maximum number of bytes used to parse a request body - // as multipart/form-data. - MaxUploadSize int64 - - // MaxMemory defines the maximum number of bytes used to parse a request body - // as multipart/form-data in memory, with the remainder stored on disk in - // temporary files. - MaxMemory int64 -} - -var _ graphql.Transport = MultipartForm{} - -func (f MultipartForm) Supports(r *http.Request) bool { - if r.Header.Get("Upgrade") != "" { - return false - } - - mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - if err != nil { - return false - } - - return r.Method == "POST" && mediaType == "multipart/form-data" -} - -func (f MultipartForm) maxUploadSize() int64 { - if f.MaxUploadSize == 0 { - return 32 << 20 - } - return f.MaxUploadSize -} - -func (f MultipartForm) maxMemory() int64 { - if f.MaxMemory == 0 { - return 32 << 20 - } - return f.MaxMemory -} - -func (f MultipartForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { - w.Header().Set("Content-Type", "application/json") - - start := graphql.Now() - - var err error - if r.ContentLength > f.maxUploadSize() { - writeJsonError(w, "failed to parse multipart form, request body too large") - return - } - r.Body = http.MaxBytesReader(w, r.Body, f.maxUploadSize()) - if err = r.ParseMultipartForm(f.maxMemory()); 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() - - var params graphql.RawParams - - if err = jsonDecode(strings.NewReader(r.Form.Get("operations")), ¶ms); err != nil { - w.WriteHeader(http.StatusUnprocessableEntity) - writeJsonError(w, "operations form field could not be decoded") - return - } - - uploadsMap := map[string][]string{} - if err = json.Unmarshal([]byte(r.Form.Get("map")), &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 { - 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() - - 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 { - 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 - } - 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: 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 - } - } - } - } - } - - params.ReadTime = graphql.TraceTiming{ - Start: start, - End: graphql.Now(), - } - - rc, gerr := exec.CreateOperationContext(r.Context(), ¶ms) - if gerr != nil { - resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), gerr) - w.WriteHeader(statusFor(gerr)) - writeJson(w, resp) - return - } - responses, ctx := exec.DispatchOperation(r.Context(), rc) - writeJson(w, responses(ctx)) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go deleted file mode 100644 index d97c89c63fd..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go +++ /dev/null @@ -1,87 +0,0 @@ -package transport - -import ( - "encoding/json" - "io" - "net/http" - "strings" - - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -// GET implements the GET side of the default HTTP transport -// defined in https://github.com/APIs-guru/graphql-over-http#get -type GET struct{} - -var _ graphql.Transport = GET{} - -func (h GET) Supports(r *http.Request) bool { - if r.Header.Get("Upgrade") != "" { - return false - } - - return r.Method == "GET" -} - -func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { - w.Header().Set("Content-Type", "application/json") - - raw := &graphql.RawParams{ - Query: r.URL.Query().Get("query"), - OperationName: r.URL.Query().Get("operationName"), - } - raw.ReadTime.Start = graphql.Now() - - if variables := r.URL.Query().Get("variables"); variables != "" { - if err := jsonDecode(strings.NewReader(variables), &raw.Variables); err != nil { - w.WriteHeader(http.StatusBadRequest) - writeJsonError(w, "variables could not be decoded") - return - } - } - - if extensions := r.URL.Query().Get("extensions"); extensions != "" { - if err := jsonDecode(strings.NewReader(extensions), &raw.Extensions); err != nil { - w.WriteHeader(http.StatusBadRequest) - writeJsonError(w, "extensions could not be decoded") - return - } - } - - raw.ReadTime.End = graphql.Now() - - rc, err := exec.CreateOperationContext(r.Context(), raw) - if err != nil { - w.WriteHeader(statusFor(err)) - resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err) - writeJson(w, resp) - return - } - op := rc.Doc.Operations.ForName(rc.OperationName) - if op.Operation != ast.Query { - w.WriteHeader(http.StatusNotAcceptable) - writeJsonError(w, "GET requests only allow query operations") - return - } - - responses, ctx := exec.DispatchOperation(r.Context(), rc) - writeJson(w, responses(ctx)) -} - -func jsonDecode(r io.Reader, val interface{}) error { - dec := json.NewDecoder(r) - dec.UseNumber() - return dec.Decode(val) -} - -func statusFor(errs gqlerror.List) int { - switch errcode.GetErrorKind(errs) { - case errcode.KindProtocol: - return http.StatusUnprocessableEntity - default: - return http.StatusOK - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go deleted file mode 100644 index deefeb38d00..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go +++ /dev/null @@ -1,53 +0,0 @@ -package transport - -import ( - "mime" - "net/http" - - "github.com/99designs/gqlgen/graphql" -) - -// POST implements the POST side of the default HTTP transport -// defined in https://github.com/APIs-guru/graphql-over-http#post -type POST struct{} - -var _ graphql.Transport = POST{} - -func (h POST) Supports(r *http.Request) bool { - if r.Header.Get("Upgrade") != "" { - return false - } - - mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - if err != nil { - return false - } - - return r.Method == "POST" && mediaType == "application/json" -} - -func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { - w.Header().Set("Content-Type", "application/json") - - var params *graphql.RawParams - start := graphql.Now() - if err := jsonDecode(r.Body, ¶ms); err != nil { - w.WriteHeader(http.StatusBadRequest) - writeJsonErrorf(w, "json body could not be decoded: "+err.Error()) - return - } - params.ReadTime = graphql.TraceTiming{ - Start: start, - End: graphql.Now(), - } - - rc, err := exec.CreateOperationContext(r.Context(), params) - if err != nil { - w.WriteHeader(statusFor(err)) - resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err) - writeJson(w, resp) - return - } - responses, ctx := exec.DispatchOperation(r.Context(), rc) - writeJson(w, responses(ctx)) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go deleted file mode 100644 index 6b725ff3e3e..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go +++ /dev/null @@ -1,26 +0,0 @@ -package transport - -import ( - "net/http" - - "github.com/99designs/gqlgen/graphql" -) - -// Options responds to http OPTIONS and HEAD requests -type Options struct{} - -var _ graphql.Transport = Options{} - -func (o Options) Supports(r *http.Request) bool { - return r.Method == "HEAD" || r.Method == "OPTIONS" -} - -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.WriteHeader(http.StatusOK) - case http.MethodHead: - w.WriteHeader(http.StatusMethodNotAllowed) - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go deleted file mode 100644 index d3261e28335..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go +++ /dev/null @@ -1,25 +0,0 @@ -package transport - -import ( - "errors" - "io" -) - -type bytesReader struct { - s *[]byte - i int64 // current reading index - prevRune int // index of previous rune; or < 0 -} - -func (r *bytesReader) Read(b []byte) (n int, err error) { - if r.s == nil { - return 0, errors.New("byte slice pointer is nil") - } - if r.i >= int64(len(*r.s)) { - return 0, io.EOF - } - r.prevRune = -1 - n = copy(b, (*r.s)[r.i:]) - r.i += int64(n) - return -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go deleted file mode 100644 index ce845c1964c..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go +++ /dev/null @@ -1,30 +0,0 @@ -package transport - -import ( - "encoding/json" - "fmt" - "io" - - "github.com/99designs/gqlgen/graphql" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -func writeJson(w io.Writer, response *graphql.Response) { - b, err := json.Marshal(response) - if err != nil { - panic(err) - } - w.Write(b) -} - -func writeJsonError(w io.Writer, msg string) { - writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: msg}}}) -} - -func writeJsonErrorf(w io.Writer, format string, args ...interface{}) { - writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: fmt.Sprintf(format, args...)}}}) -} - -func writeJsonGraphqlError(w io.Writer, err ...*gqlerror.Error) { - writeJson(w, &graphql.Response{Errors: err}) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go deleted file mode 100644 index 28480a4092b..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go +++ /dev/null @@ -1,415 +0,0 @@ -package transport - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "log" - "net" - "net/http" - "sync" - "time" - - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/errcode" - "github.com/gorilla/websocket" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -type ( - Websocket struct { - Upgrader websocket.Upgrader - InitFunc WebsocketInitFunc - InitTimeout time.Duration - ErrorFunc WebsocketErrorFunc - KeepAlivePingInterval time.Duration - PingPongInterval time.Duration - - didInjectSubprotocols bool - } - wsConnection struct { - Websocket - ctx context.Context - conn *websocket.Conn - me messageExchanger - active map[string]context.CancelFunc - mu sync.Mutex - keepAliveTicker *time.Ticker - pingPongTicker *time.Ticker - exec graphql.GraphExecutor - - initPayload InitPayload - } - - WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, error) - WebsocketErrorFunc func(ctx context.Context, err error) -) - -var errReadTimeout = errors.New("read timeout") - -var _ graphql.Transport = Websocket{} - -func (t Websocket) Supports(r *http.Request) bool { - return r.Header.Get("Upgrade") != "" -} - -func (t Websocket) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { - t.injectGraphQLWSSubprotocols() - ws, err := t.Upgrader.Upgrade(w, r, http.Header{}) - if err != nil { - log.Printf("unable to upgrade %T to websocket %s: ", w, err.Error()) - SendErrorf(w, http.StatusBadRequest, "unable to upgrade") - return - } - - var me messageExchanger - switch ws.Subprotocol() { - default: - msg := websocket.FormatCloseMessage(websocket.CloseProtocolError, fmt.Sprintf("unsupported negotiated subprotocol %s", ws.Subprotocol())) - ws.WriteMessage(websocket.CloseMessage, msg) - return - case graphqlwsSubprotocol, "": - // clients are required to send a subprotocol, to be backward compatible with the previous implementation we select - // "graphql-ws" by default - me = graphqlwsMessageExchanger{c: ws} - case graphqltransportwsSubprotocol: - me = graphqltransportwsMessageExchanger{c: ws} - } - - conn := wsConnection{ - active: map[string]context.CancelFunc{}, - conn: ws, - ctx: r.Context(), - exec: exec, - me: me, - Websocket: t, - } - - if !conn.init() { - return - } - - conn.run() -} - -func (c *wsConnection) handlePossibleError(err error) { - if c.ErrorFunc != nil && err != nil { - c.ErrorFunc(c.ctx, err) - } -} - -func (c *wsConnection) nextMessageWithTimeout(timeout time.Duration) (message, error) { - messages, errs := make(chan message, 1), make(chan error, 1) - - go func() { - if m, err := c.me.NextMessage(); err != nil { - errs <- err - } else { - messages <- m - } - }() - - select { - case m := <-messages: - return m, nil - case err := <-errs: - return message{}, err - case <-time.After(timeout): - return message{}, errReadTimeout - } -} - -func (c *wsConnection) init() bool { - var m message - var err error - - if c.InitTimeout != 0 { - m, err = c.nextMessageWithTimeout(c.InitTimeout) - } else { - m, err = c.me.NextMessage() - } - - if err != nil { - if err == errReadTimeout { - c.close(websocket.CloseProtocolError, "connection initialisation timeout") - return false - } - - if err == errInvalidMsg { - c.sendConnectionError("invalid json") - } - - c.close(websocket.CloseProtocolError, "decoding error") - return false - } - - switch m.t { - case initMessageType: - if len(m.payload) > 0 { - c.initPayload = make(InitPayload) - err := json.Unmarshal(m.payload, &c.initPayload) - if err != nil { - return false - } - } - - if c.InitFunc != nil { - ctx, err := c.InitFunc(c.ctx, c.initPayload) - if err != nil { - c.sendConnectionError(err.Error()) - c.close(websocket.CloseNormalClosure, "terminated") - return false - } - c.ctx = ctx - } - - c.write(&message{t: connectionAckMessageType}) - c.write(&message{t: keepAliveMessageType}) - case connectionCloseMessageType: - c.close(websocket.CloseNormalClosure, "terminated") - return false - default: - c.sendConnectionError("unexpected message %s", m.t) - c.close(websocket.CloseProtocolError, "unexpected message") - return false - } - - return true -} - -func (c *wsConnection) write(msg *message) { - c.mu.Lock() - c.handlePossibleError(c.me.Send(msg)) - c.mu.Unlock() -} - -func (c *wsConnection) run() { - // We create a cancellation that will shutdown the keep-alive when we leave - // this function. - ctx, cancel := context.WithCancel(c.ctx) - defer func() { - cancel() - c.close(websocket.CloseAbnormalClosure, "unexpected closure") - }() - - // If we're running in graphql-ws mode, create a timer that will trigger a - // keep alive message every interval - if (c.conn.Subprotocol() == "" || c.conn.Subprotocol() == graphqlwsSubprotocol) && c.KeepAlivePingInterval != 0 { - c.mu.Lock() - c.keepAliveTicker = time.NewTicker(c.KeepAlivePingInterval) - c.mu.Unlock() - - go c.keepAlive(ctx) - } - - // If we're running in graphql-transport-ws mode, create a timer that will - // trigger a ping message every interval - if c.conn.Subprotocol() == graphqltransportwsSubprotocol && c.PingPongInterval != 0 { - c.mu.Lock() - c.pingPongTicker = time.NewTicker(c.PingPongInterval) - c.mu.Unlock() - - // Note: when the connection is closed by this deadline, the client - // will receive an "invalid close code" - c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) - go c.ping(ctx) - } - - // Close the connection when the context is cancelled. - // Will optionally send a "close reason" that is retrieved from the context. - go c.closeOnCancel(ctx) - - for { - start := graphql.Now() - m, err := c.me.NextMessage() - if err != nil { - // If the connection got closed by us, don't report the error - if !errors.Is(err, net.ErrClosed) { - c.handlePossibleError(err) - } - return - } - - switch m.t { - case startMessageType: - c.subscribe(start, &m) - case stopMessageType: - c.mu.Lock() - closer := c.active[m.id] - c.mu.Unlock() - if closer != nil { - closer() - } - case connectionCloseMessageType: - c.close(websocket.CloseNormalClosure, "terminated") - return - case pingMessageType: - c.write(&message{t: pongMessageType, payload: m.payload}) - case pongMessageType: - c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) - default: - c.sendConnectionError("unexpected message %s", m.t) - c.close(websocket.CloseProtocolError, "unexpected message") - return - } - } -} - -func (c *wsConnection) keepAlive(ctx context.Context) { - for { - select { - case <-ctx.Done(): - c.keepAliveTicker.Stop() - return - case <-c.keepAliveTicker.C: - c.write(&message{t: keepAliveMessageType}) - } - } -} - -func (c *wsConnection) ping(ctx context.Context) { - for { - select { - case <-ctx.Done(): - c.pingPongTicker.Stop() - return - case <-c.pingPongTicker.C: - c.write(&message{t: pingMessageType, payload: json.RawMessage{}}) - } - } -} - -func (c *wsConnection) closeOnCancel(ctx context.Context) { - <-ctx.Done() - - if r := closeReasonForContext(ctx); r != "" { - c.sendConnectionError(r) - } - c.close(websocket.CloseNormalClosure, "terminated") -} - -func (c *wsConnection) subscribe(start time.Time, msg *message) { - ctx := graphql.StartOperationTrace(c.ctx) - var params *graphql.RawParams - if err := jsonDecode(bytes.NewReader(msg.payload), ¶ms); err != nil { - c.sendError(msg.id, &gqlerror.Error{Message: "invalid json"}) - c.complete(msg.id) - return - } - - params.ReadTime = graphql.TraceTiming{ - Start: start, - End: graphql.Now(), - } - - rc, err := c.exec.CreateOperationContext(ctx, params) - if err != nil { - resp := c.exec.DispatchError(graphql.WithOperationContext(ctx, rc), err) - switch errcode.GetErrorKind(err) { - case errcode.KindProtocol: - c.sendError(msg.id, resp.Errors...) - default: - c.sendResponse(msg.id, &graphql.Response{Errors: err}) - } - - c.complete(msg.id) - return - } - - ctx = graphql.WithOperationContext(ctx, rc) - - if c.initPayload != nil { - ctx = withInitPayload(ctx, c.initPayload) - } - - ctx, cancel := context.WithCancel(ctx) - c.mu.Lock() - c.active[msg.id] = cancel - c.mu.Unlock() - - go func() { - defer func() { - if r := recover(); r != nil { - err := rc.Recover(ctx, r) - var gqlerr *gqlerror.Error - if !errors.As(err, &gqlerr) { - gqlerr = &gqlerror.Error{} - if err != nil { - gqlerr.Message = err.Error() - } - } - c.sendError(msg.id, gqlerr) - } - c.complete(msg.id) - c.mu.Lock() - delete(c.active, msg.id) - c.mu.Unlock() - cancel() - }() - - responses, ctx := c.exec.DispatchOperation(ctx, rc) - for { - response := responses(ctx) - if response == nil { - break - } - - c.sendResponse(msg.id, response) - } - c.complete(msg.id) - - c.mu.Lock() - delete(c.active, msg.id) - c.mu.Unlock() - cancel() - }() -} - -func (c *wsConnection) sendResponse(id string, response *graphql.Response) { - b, err := json.Marshal(response) - if err != nil { - panic(err) - } - c.write(&message{ - payload: b, - id: id, - t: dataMessageType, - }) -} - -func (c *wsConnection) complete(id string) { - c.write(&message{id: id, t: completeMessageType}) -} - -func (c *wsConnection) sendError(id string, errors ...*gqlerror.Error) { - errs := make([]error, len(errors)) - for i, err := range errors { - errs[i] = err - } - b, err := json.Marshal(errs) - if err != nil { - panic(err) - } - c.write(&message{t: errorMessageType, id: id, payload: b}) -} - -func (c *wsConnection) sendConnectionError(format string, args ...interface{}) { - b, err := json.Marshal(&gqlerror.Error{Message: fmt.Sprintf(format, args...)}) - if err != nil { - panic(err) - } - - c.write(&message{t: connectionErrorMessageType, payload: b}) -} - -func (c *wsConnection) close(closeCode int, message string) { - c.mu.Lock() - _ = c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(closeCode, message)) - for _, closer := range c.active { - closer() - } - c.mu.Unlock() - _ = c.conn.Close() -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go deleted file mode 100644 index c8217debe74..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go +++ /dev/null @@ -1,22 +0,0 @@ -package transport - -import ( - "context" -) - -// A private key for context that only this package can access. This is important -// to prevent collisions between different context uses -var closeReasonCtxKey = &wsCloseReasonContextKey{"close-reason"} - -type wsCloseReasonContextKey struct { - name string -} - -func AppendCloseReason(ctx context.Context, reason string) context.Context { - return context.WithValue(ctx, closeReasonCtxKey, reason) -} - -func closeReasonForContext(ctx context.Context) string { - reason, _ := ctx.Value(closeReasonCtxKey).(string) - return reason -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go deleted file mode 100644 index 9b82082a2df..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go +++ /dev/null @@ -1,149 +0,0 @@ -package transport - -import ( - "encoding/json" - "fmt" - - "github.com/gorilla/websocket" -) - -// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md -const ( - graphqltransportwsSubprotocol = "graphql-transport-ws" - - graphqltransportwsConnectionInitMsg = graphqltransportwsMessageType("connection_init") - graphqltransportwsConnectionAckMsg = graphqltransportwsMessageType("connection_ack") - graphqltransportwsSubscribeMsg = graphqltransportwsMessageType("subscribe") - graphqltransportwsNextMsg = graphqltransportwsMessageType("next") - graphqltransportwsErrorMsg = graphqltransportwsMessageType("error") - graphqltransportwsCompleteMsg = graphqltransportwsMessageType("complete") - graphqltransportwsPingMsg = graphqltransportwsMessageType("ping") - graphqltransportwsPongMsg = graphqltransportwsMessageType("pong") -) - -var allGraphqltransportwsMessageTypes = []graphqltransportwsMessageType{ - graphqltransportwsConnectionInitMsg, - graphqltransportwsConnectionAckMsg, - graphqltransportwsSubscribeMsg, - graphqltransportwsNextMsg, - graphqltransportwsErrorMsg, - graphqltransportwsCompleteMsg, - graphqltransportwsPingMsg, - graphqltransportwsPongMsg, -} - -type ( - graphqltransportwsMessageExchanger struct { - c *websocket.Conn - } - - graphqltransportwsMessage struct { - Payload json.RawMessage `json:"payload,omitempty"` - ID string `json:"id,omitempty"` - Type graphqltransportwsMessageType `json:"type"` - noOp bool - } - - graphqltransportwsMessageType string -) - -func (me graphqltransportwsMessageExchanger) NextMessage() (message, error) { - _, r, err := me.c.NextReader() - if err != nil { - return message{}, handleNextReaderError(err) - } - - var graphqltransportwsMessage graphqltransportwsMessage - if err := jsonDecode(r, &graphqltransportwsMessage); err != nil { - return message{}, errInvalidMsg - } - - return graphqltransportwsMessage.toMessage() -} - -func (me graphqltransportwsMessageExchanger) Send(m *message) error { - msg := &graphqltransportwsMessage{} - if err := msg.fromMessage(m); err != nil { - return err - } - - if msg.noOp { - return nil - } - - return me.c.WriteJSON(msg) -} - -func (t *graphqltransportwsMessageType) UnmarshalText(text []byte) (err error) { - var found bool - for _, candidate := range allGraphqltransportwsMessageTypes { - if string(candidate) == string(text) { - *t = candidate - found = true - break - } - } - - if !found { - err = fmt.Errorf("invalid message type %s", string(text)) - } - - return err -} - -func (t graphqltransportwsMessageType) MarshalText() ([]byte, error) { - return []byte(string(t)), nil -} - -func (m graphqltransportwsMessage) toMessage() (message, error) { - var t messageType - var err error - switch m.Type { - default: - err = fmt.Errorf("invalid client->server message type %s", m.Type) - case graphqltransportwsConnectionInitMsg: - t = initMessageType - case graphqltransportwsSubscribeMsg: - t = startMessageType - case graphqltransportwsCompleteMsg: - t = stopMessageType - case graphqltransportwsPingMsg: - t = pingMessageType - case graphqltransportwsPongMsg: - t = pongMessageType - } - - return message{ - payload: m.Payload, - id: m.ID, - t: t, - }, err -} - -func (m *graphqltransportwsMessage) fromMessage(msg *message) (err error) { - m.ID = msg.id - m.Payload = msg.payload - - switch msg.t { - default: - err = fmt.Errorf("invalid server->client message type %s", msg.t) - case connectionAckMessageType: - m.Type = graphqltransportwsConnectionAckMsg - case keepAliveMessageType: - m.noOp = true - case connectionErrorMessageType: - m.noOp = true - case dataMessageType: - m.Type = graphqltransportwsNextMsg - case completeMessageType: - m.Type = graphqltransportwsCompleteMsg - case errorMessageType: - m.Type = graphqltransportwsErrorMsg - case pingMessageType: - m.Type = graphqltransportwsPingMsg - case pongMessageType: - m.Type = graphqltransportwsPongMsg - } - - return err -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go deleted file mode 100644 index 49ed1ee8031..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go +++ /dev/null @@ -1,171 +0,0 @@ -package transport - -import ( - "encoding/json" - "fmt" - - "github.com/gorilla/websocket" -) - -// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md -const ( - graphqlwsSubprotocol = "graphql-ws" - - graphqlwsConnectionInitMsg = graphqlwsMessageType("connection_init") - graphqlwsConnectionTerminateMsg = graphqlwsMessageType("connection_terminate") - graphqlwsStartMsg = graphqlwsMessageType("start") - graphqlwsStopMsg = graphqlwsMessageType("stop") - graphqlwsConnectionAckMsg = graphqlwsMessageType("connection_ack") - graphqlwsConnectionErrorMsg = graphqlwsMessageType("connection_error") - graphqlwsDataMsg = graphqlwsMessageType("data") - graphqlwsErrorMsg = graphqlwsMessageType("error") - graphqlwsCompleteMsg = graphqlwsMessageType("complete") - graphqlwsConnectionKeepAliveMsg = graphqlwsMessageType("ka") -) - -var allGraphqlwsMessageTypes = []graphqlwsMessageType{ - graphqlwsConnectionInitMsg, - graphqlwsConnectionTerminateMsg, - graphqlwsStartMsg, - graphqlwsStopMsg, - graphqlwsConnectionAckMsg, - graphqlwsConnectionErrorMsg, - graphqlwsDataMsg, - graphqlwsErrorMsg, - graphqlwsCompleteMsg, - graphqlwsConnectionKeepAliveMsg, -} - -type ( - graphqlwsMessageExchanger struct { - c *websocket.Conn - } - - graphqlwsMessage struct { - Payload json.RawMessage `json:"payload,omitempty"` - ID string `json:"id,omitempty"` - Type graphqlwsMessageType `json:"type"` - noOp bool - } - - graphqlwsMessageType string -) - -func (me graphqlwsMessageExchanger) NextMessage() (message, error) { - _, r, err := me.c.NextReader() - if err != nil { - return message{}, handleNextReaderError(err) - } - - var graphqlwsMessage graphqlwsMessage - if err := jsonDecode(r, &graphqlwsMessage); err != nil { - return message{}, errInvalidMsg - } - - return graphqlwsMessage.toMessage() -} - -func (me graphqlwsMessageExchanger) Send(m *message) error { - msg := &graphqlwsMessage{} - if err := msg.fromMessage(m); err != nil { - return err - } - - if msg.noOp { - return nil - } - - return me.c.WriteJSON(msg) -} - -func (t *graphqlwsMessageType) UnmarshalText(text []byte) (err error) { - var found bool - for _, candidate := range allGraphqlwsMessageTypes { - if string(candidate) == string(text) { - *t = candidate - found = true - break - } - } - - if !found { - err = fmt.Errorf("invalid message type %s", string(text)) - } - - return err -} - -func (t graphqlwsMessageType) MarshalText() ([]byte, error) { - return []byte(string(t)), nil -} - -func (m graphqlwsMessage) toMessage() (message, error) { - var t messageType - var err error - switch m.Type { - default: - err = fmt.Errorf("invalid client->server message type %s", m.Type) - case graphqlwsConnectionInitMsg: - t = initMessageType - case graphqlwsConnectionTerminateMsg: - t = connectionCloseMessageType - case graphqlwsStartMsg: - t = startMessageType - case graphqlwsStopMsg: - t = stopMessageType - case graphqlwsConnectionAckMsg: - t = connectionAckMessageType - case graphqlwsConnectionErrorMsg: - t = connectionErrorMessageType - case graphqlwsDataMsg: - t = dataMessageType - case graphqlwsErrorMsg: - t = errorMessageType - case graphqlwsCompleteMsg: - t = completeMessageType - case graphqlwsConnectionKeepAliveMsg: - t = keepAliveMessageType - } - - return message{ - payload: m.Payload, - id: m.ID, - t: t, - }, err -} - -func (m *graphqlwsMessage) fromMessage(msg *message) (err error) { - m.ID = msg.id - m.Payload = msg.payload - - switch msg.t { - default: - err = fmt.Errorf("invalid server->client message type %s", msg.t) - case initMessageType: - m.Type = graphqlwsConnectionInitMsg - case connectionAckMessageType: - m.Type = graphqlwsConnectionAckMsg - case keepAliveMessageType: - m.Type = graphqlwsConnectionKeepAliveMsg - case connectionErrorMessageType: - m.Type = graphqlwsConnectionErrorMsg - case connectionCloseMessageType: - m.Type = graphqlwsConnectionTerminateMsg - case startMessageType: - m.Type = graphqlwsStartMsg - case stopMessageType: - m.Type = graphqlwsStopMsg - case dataMessageType: - m.Type = graphqlwsDataMsg - case completeMessageType: - m.Type = graphqlwsCompleteMsg - case errorMessageType: - m.Type = graphqlwsErrorMsg - case pingMessageType: - m.noOp = true - case pongMessageType: - m.noOp = true - } - - return err -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go deleted file mode 100644 index a5f84ba2dc6..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go +++ /dev/null @@ -1,57 +0,0 @@ -package transport - -import "context" - -type key string - -const ( - initpayload key = "ws_initpayload_context" -) - -// InitPayload is a structure that is parsed from the websocket init message payload. TO use -// request headers for non-websocket, instead wrap the graphql handler in a middleware. -type InitPayload map[string]interface{} - -// GetString safely gets a string value from the payload. It returns an empty string if the -// payload is nil or the value isn't set. -func (p InitPayload) GetString(key string) string { - if p == nil { - return "" - } - - if value, ok := p[key]; ok { - res, _ := value.(string) - return res - } - - return "" -} - -// Authorization is a short hand for getting the Authorization header from the -// payload. -func (p InitPayload) Authorization() string { - if value := p.GetString("Authorization"); value != "" { - return value - } - - if value := p.GetString("authorization"); value != "" { - return value - } - - return "" -} - -func withInitPayload(ctx context.Context, payload InitPayload) context.Context { - return context.WithValue(ctx, initpayload, payload) -} - -// GetInitPayload gets a map of the data sent with the connection_init message, which is used by -// graphql clients as a stand-in for HTTP headers. -func GetInitPayload(ctx context.Context) InitPayload { - payload, ok := ctx.Value(initpayload).(InitPayload) - if !ok { - return nil - } - - return payload -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go deleted file mode 100644 index c02098a88e5..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go +++ /dev/null @@ -1,116 +0,0 @@ -package transport - -import ( - "encoding/json" - "errors" - - "github.com/gorilla/websocket" -) - -const ( - initMessageType messageType = iota - connectionAckMessageType - keepAliveMessageType - connectionErrorMessageType - connectionCloseMessageType - startMessageType - stopMessageType - dataMessageType - completeMessageType - errorMessageType - pingMessageType - pongMessageType -) - -var ( - supportedSubprotocols = []string{ - graphqlwsSubprotocol, - graphqltransportwsSubprotocol, - } - - errWsConnClosed = errors.New("websocket connection closed") - errInvalidMsg = errors.New("invalid message received") -) - -type ( - messageType int - message struct { - payload json.RawMessage - id string - t messageType - } - messageExchanger interface { - NextMessage() (message, error) - Send(m *message) error - } -) - -func (t messageType) String() string { - var text string - switch t { - default: - text = "unknown" - case initMessageType: - text = "init" - case connectionAckMessageType: - text = "connection ack" - case keepAliveMessageType: - text = "keep alive" - case connectionErrorMessageType: - text = "connection error" - case connectionCloseMessageType: - text = "connection close" - case startMessageType: - text = "start" - case stopMessageType: - text = "stop subscription" - case dataMessageType: - text = "data" - case completeMessageType: - text = "complete" - case errorMessageType: - text = "error" - case pingMessageType: - text = "ping" - case pongMessageType: - text = "pong" - } - return text -} - -func contains(list []string, elem string) bool { - for _, e := range list { - if e == elem { - return true - } - } - - return false -} - -func (t *Websocket) injectGraphQLWSSubprotocols() { - // the list of subprotocols is specified by the consumer of the Websocket struct, - // in order to preserve backward compatibility, we inject the graphql specific subprotocols - // at runtime - if !t.didInjectSubprotocols { - defer func() { - t.didInjectSubprotocols = true - }() - - for _, subprotocol := range supportedSubprotocols { - if !contains(t.Upgrader.Subprotocols, subprotocol) { - t.Upgrader.Subprotocols = append(t.Upgrader.Subprotocols, subprotocol) - } - } - } -} - -func handleNextReaderError(err error) error { - // TODO: should we consider all closure scenarios here for the ws connection? - // for now we only list the error codes from the previous implementation - if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) { - return errWsConnClosed - } - - return err -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/id.go b/vendor/github.com/99designs/gqlgen/graphql/id.go deleted file mode 100644 index b24605d1d8f..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/id.go +++ /dev/null @@ -1,58 +0,0 @@ -package graphql - -import ( - "encoding/json" - "fmt" - "io" - "strconv" -) - -func MarshalID(s string) Marshaler { - return MarshalString(s) -} - -func UnmarshalID(v interface{}) (string, error) { - switch v := v.(type) { - case string: - return v, nil - case json.Number: - return string(v), nil - case int: - return strconv.Itoa(v), nil - case int64: - return strconv.FormatInt(v, 10), nil - case float64: - return fmt.Sprintf("%f", v), nil - case bool: - if v { - return "true", nil - } else { - return "false", nil - } - case nil: - return "null", nil - default: - return "", fmt.Errorf("%T is not a string", v) - } -} - -func MarshalIntID(i int) Marshaler { - return WriterFunc(func(w io.Writer) { - writeQuotedString(w, strconv.Itoa(i)) - }) -} - -func UnmarshalIntID(v interface{}) (int, error) { - switch v := v.(type) { - case string: - return strconv.Atoi(v) - case int: - return v, nil - case int64: - return int(v), nil - case json.Number: - return strconv.Atoi(string(v)) - default: - return 0, fmt.Errorf("%T is not an int", v) - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/int.go b/vendor/github.com/99designs/gqlgen/graphql/int.go deleted file mode 100644 index 57d0d589bae..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/int.go +++ /dev/null @@ -1,79 +0,0 @@ -package graphql - -import ( - "encoding/json" - "fmt" - "io" - "strconv" -) - -func MarshalInt(i int) Marshaler { - return WriterFunc(func(w io.Writer) { - io.WriteString(w, strconv.Itoa(i)) - }) -} - -func UnmarshalInt(v interface{}) (int, error) { - switch v := v.(type) { - case string: - return strconv.Atoi(v) - case int: - return v, nil - case int64: - return int(v), nil - case json.Number: - return strconv.Atoi(string(v)) - default: - return 0, fmt.Errorf("%T is not an int", v) - } -} - -func MarshalInt64(i int64) Marshaler { - return WriterFunc(func(w io.Writer) { - io.WriteString(w, strconv.FormatInt(i, 10)) - }) -} - -func UnmarshalInt64(v interface{}) (int64, error) { - switch v := v.(type) { - case string: - return strconv.ParseInt(v, 10, 64) - case int: - return int64(v), nil - case int64: - return v, nil - case json.Number: - return strconv.ParseInt(string(v), 10, 64) - default: - return 0, fmt.Errorf("%T is not an int", v) - } -} - -func MarshalInt32(i int32) Marshaler { - return WriterFunc(func(w io.Writer) { - io.WriteString(w, strconv.FormatInt(int64(i), 10)) - }) -} - -func UnmarshalInt32(v interface{}) (int32, error) { - switch v := v.(type) { - case string: - iv, err := strconv.ParseInt(v, 10, 32) - if err != nil { - return 0, err - } - return int32(iv), nil - case int: - return int32(v), nil - case int64: - return int32(v), nil - case json.Number: - iv, err := strconv.ParseInt(string(v), 10, 32) - if err != nil { - return 0, err - } - return int32(iv), nil - default: - return 0, fmt.Errorf("%T is not an int", v) - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go deleted file mode 100644 index 8482d62a861..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go +++ /dev/null @@ -1,101 +0,0 @@ -// introspection implements the spec defined in https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#schema-introspection -package introspection - -import "github.com/vektah/gqlparser/v2/ast" - -type ( - Directive struct { - Name string - description string - Locations []string - Args []InputValue - IsRepeatable bool - } - - EnumValue struct { - Name string - description string - deprecation *ast.Directive - } - - Field struct { - Name string - description string - Type *Type - Args []InputValue - deprecation *ast.Directive - } - - InputValue struct { - Name string - description string - DefaultValue *string - Type *Type - } -) - -func WrapSchema(schema *ast.Schema) *Schema { - return &Schema{schema: schema} -} - -func (f *EnumValue) Description() *string { - if f.description == "" { - return nil - } - return &f.description -} - -func (f *EnumValue) IsDeprecated() bool { - return f.deprecation != nil -} - -func (f *EnumValue) DeprecationReason() *string { - if f.deprecation == nil { - return nil - } - - reason := f.deprecation.Arguments.ForName("reason") - if reason == nil { - return nil - } - - return &reason.Value.Raw -} - -func (f *Field) Description() *string { - if f.description == "" { - return nil - } - return &f.description -} - -func (f *Field) IsDeprecated() bool { - return f.deprecation != nil -} - -func (f *Field) DeprecationReason() *string { - if f.deprecation == nil { - return nil - } - - reason := f.deprecation.Arguments.ForName("reason") - if reason == nil { - return nil - } - - return &reason.Value.Raw -} - -func (f *InputValue) Description() *string { - if f.description == "" { - return nil - } - return &f.description -} - -func (f *Directive) Description() *string { - if f.description == "" { - return nil - } - return &f.description -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go deleted file mode 100644 index 389a5d85c0c..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go +++ /dev/null @@ -1,106 +0,0 @@ -package introspection - -// Query is the query generated by graphiql to determine type information -const Query = ` -query IntrospectionQuery { - __schema { - description - queryType { - name - } - mutationType { - name - } - subscriptionType { - name - } - types { - ...FullType - } - directives { - name - description - locations - args { - ...InputValue - } - } - } -} - -fragment FullType on __Type { - kind - name - description - specifiedByURL - fields(includeDeprecated: true) { - name - description - args { - ...InputValue - } - type { - ...TypeRef - } - isDeprecated - deprecationReason - } - inputFields { - ...InputValue - } - interfaces { - ...TypeRef - } - enumValues(includeDeprecated: true) { - name - description - isDeprecated - deprecationReason - } - possibleTypes { - ...TypeRef - } -} - -fragment InputValue on __InputValue { - name - description - type { - ...TypeRef - } - defaultValue -} - -fragment TypeRef on __Type { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - } - } - } - } - } - } - } -} -` diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go deleted file mode 100644 index b7b0ad94e0d..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go +++ /dev/null @@ -1,93 +0,0 @@ -package introspection - -import ( - "sort" - "strings" - - "github.com/vektah/gqlparser/v2/ast" -) - -type Schema struct { - schema *ast.Schema -} - -func (s *Schema) Description() *string { - if s.schema.Description == "" { - return nil - } - return &s.schema.Description -} - -func (s *Schema) Types() []Type { - typeIndex := map[string]Type{} - typeNames := make([]string, 0, len(s.schema.Types)) - for _, typ := range s.schema.Types { - if strings.HasPrefix(typ.Name, "__") { - continue - } - typeNames = append(typeNames, typ.Name) - typeIndex[typ.Name] = *WrapTypeFromDef(s.schema, typ) - } - sort.Strings(typeNames) - - types := make([]Type, len(typeNames)) - for i, t := range typeNames { - types[i] = typeIndex[t] - } - return types -} - -func (s *Schema) QueryType() *Type { - return WrapTypeFromDef(s.schema, s.schema.Query) -} - -func (s *Schema) MutationType() *Type { - return WrapTypeFromDef(s.schema, s.schema.Mutation) -} - -func (s *Schema) SubscriptionType() *Type { - return WrapTypeFromDef(s.schema, s.schema.Subscription) -} - -func (s *Schema) Directives() []Directive { - dIndex := map[string]Directive{} - dNames := make([]string, 0, len(s.schema.Directives)) - - for _, d := range s.schema.Directives { - dNames = append(dNames, d.Name) - dIndex[d.Name] = s.directiveFromDef(d) - } - sort.Strings(dNames) - - res := make([]Directive, len(dNames)) - for i, d := range dNames { - res[i] = dIndex[d] - } - - return res -} - -func (s *Schema) directiveFromDef(d *ast.DirectiveDefinition) Directive { - locs := make([]string, len(d.Locations)) - for i, loc := range d.Locations { - locs[i] = string(loc) - } - - args := make([]InputValue, len(d.Arguments)) - for i, arg := range d.Arguments { - args[i] = InputValue{ - Name: arg.Name, - description: arg.Description, - DefaultValue: defaultValue(arg.DefaultValue), - Type: WrapTypeFromType(s.schema, arg.Type), - } - } - - return Directive{ - Name: d.Name, - description: d.Description, - Locations: locs, - Args: args, - IsRepeatable: d.IsRepeatable, - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go deleted file mode 100644 index c50733d0dfb..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go +++ /dev/null @@ -1,191 +0,0 @@ -package introspection - -import ( - "strings" - - "github.com/vektah/gqlparser/v2/ast" -) - -type Type struct { - schema *ast.Schema - def *ast.Definition - typ *ast.Type -} - -func WrapTypeFromDef(s *ast.Schema, def *ast.Definition) *Type { - if def == nil { - return nil - } - return &Type{schema: s, def: def} -} - -func WrapTypeFromType(s *ast.Schema, typ *ast.Type) *Type { - if typ == nil { - return nil - } - - if !typ.NonNull && typ.NamedType != "" { - return &Type{schema: s, def: s.Types[typ.NamedType]} - } - return &Type{schema: s, typ: typ} -} - -func (t *Type) Kind() string { - if t.typ != nil { - if t.typ.NonNull { - return "NON_NULL" - } - - if t.typ.Elem != nil { - return "LIST" - } - } else { - return string(t.def.Kind) - } - - panic("UNKNOWN") -} - -func (t *Type) Name() *string { - if t.def == nil { - return nil - } - return &t.def.Name -} - -func (t *Type) Description() *string { - if t.def == nil || t.def.Description == "" { - return nil - } - return &t.def.Description -} - -func (t *Type) Fields(includeDeprecated bool) []Field { - if t.def == nil || (t.def.Kind != ast.Object && t.def.Kind != ast.Interface) { - return []Field{} - } - fields := []Field{} - for _, f := range t.def.Fields { - if strings.HasPrefix(f.Name, "__") { - continue - } - - if !includeDeprecated && f.Directives.ForName("deprecated") != nil { - continue - } - - var args []InputValue - for _, arg := range f.Arguments { - args = append(args, InputValue{ - Type: WrapTypeFromType(t.schema, arg.Type), - Name: arg.Name, - description: arg.Description, - DefaultValue: defaultValue(arg.DefaultValue), - }) - } - - fields = append(fields, Field{ - Name: f.Name, - description: f.Description, - Args: args, - Type: WrapTypeFromType(t.schema, f.Type), - deprecation: f.Directives.ForName("deprecated"), - }) - } - return fields -} - -func (t *Type) InputFields() []InputValue { - if t.def == nil || t.def.Kind != ast.InputObject { - return []InputValue{} - } - - res := []InputValue{} - for _, f := range t.def.Fields { - res = append(res, InputValue{ - Name: f.Name, - description: f.Description, - Type: WrapTypeFromType(t.schema, f.Type), - DefaultValue: defaultValue(f.DefaultValue), - }) - } - return res -} - -func defaultValue(value *ast.Value) *string { - if value == nil { - return nil - } - val := value.String() - return &val -} - -func (t *Type) Interfaces() []Type { - if t.def == nil || t.def.Kind != ast.Object { - return []Type{} - } - - res := []Type{} - for _, intf := range t.def.Interfaces { - res = append(res, *WrapTypeFromDef(t.schema, t.schema.Types[intf])) - } - - return res -} - -func (t *Type) PossibleTypes() []Type { - if t.def == nil || (t.def.Kind != ast.Interface && t.def.Kind != ast.Union) { - return []Type{} - } - - res := []Type{} - for _, pt := range t.schema.GetPossibleTypes(t.def) { - res = append(res, *WrapTypeFromDef(t.schema, pt)) - } - return res -} - -func (t *Type) EnumValues(includeDeprecated bool) []EnumValue { - if t.def == nil || t.def.Kind != ast.Enum { - return []EnumValue{} - } - - res := []EnumValue{} - for _, val := range t.def.EnumValues { - if !includeDeprecated && val.Directives.ForName("deprecated") != nil { - continue - } - - res = append(res, EnumValue{ - Name: val.Name, - description: val.Description, - deprecation: val.Directives.ForName("deprecated"), - }) - } - return res -} - -func (t *Type) OfType() *Type { - if t.typ == nil { - return nil - } - if t.typ.NonNull { - // fake non null nodes - cpy := *t.typ - cpy.NonNull = false - - return WrapTypeFromType(t.schema, &cpy) - } - return WrapTypeFromType(t.schema, t.typ.Elem) -} - -func (t *Type) SpecifiedByURL() *string { - directive := t.def.Directives.ForName("specifiedBy") - if t.def.Kind != ast.Scalar || directive == nil { - return nil - } - // def: directive @specifiedBy(url: String!) on SCALAR - // the argument "url" is required. - url := directive.Arguments.ForName("url") - return &url.Value.Raw -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go deleted file mode 100644 index 54e293f1ad0..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go +++ /dev/null @@ -1,93 +0,0 @@ -package graphql - -import ( - "context" - "io" -) - -var ( - nullLit = []byte(`null`) - trueLit = []byte(`true`) - falseLit = []byte(`false`) - openBrace = []byte(`{`) - closeBrace = []byte(`}`) - openBracket = []byte(`[`) - closeBracket = []byte(`]`) - colon = []byte(`:`) - comma = []byte(`,`) -) - -var ( - Null = &lit{nullLit} - True = &lit{trueLit} - False = &lit{falseLit} -) - -type Marshaler interface { - MarshalGQL(w io.Writer) -} - -type Unmarshaler interface { - UnmarshalGQL(v interface{}) error -} - -type ContextMarshaler interface { - MarshalGQLContext(ctx context.Context, w io.Writer) error -} - -type ContextUnmarshaler interface { - UnmarshalGQLContext(ctx context.Context, v interface{}) error -} - -type contextMarshalerAdapter struct { - Context context.Context - ContextMarshaler -} - -func WrapContextMarshaler(ctx context.Context, m ContextMarshaler) Marshaler { - return contextMarshalerAdapter{Context: ctx, ContextMarshaler: m} -} - -func (a contextMarshalerAdapter) MarshalGQL(w io.Writer) { - err := a.MarshalGQLContext(a.Context, w) - if err != nil { - AddError(a.Context, err) - Null.MarshalGQL(w) - } -} - -type WriterFunc func(writer io.Writer) - -func (f WriterFunc) MarshalGQL(w io.Writer) { - f(w) -} - -type ContextWriterFunc func(ctx context.Context, writer io.Writer) error - -func (f ContextWriterFunc) MarshalGQLContext(ctx context.Context, w io.Writer) error { - return f(ctx, w) -} - -type Array []Marshaler - -func (a Array) MarshalGQL(writer io.Writer) { - writer.Write(openBracket) - for i, val := range a { - if i != 0 { - writer.Write(comma) - } - val.MarshalGQL(writer) - } - writer.Write(closeBracket) -} - -type lit struct{ b []byte } - -func (l lit) MarshalGQL(w io.Writer) { - w.Write(l.b) -} - -func (l lit) MarshalGQLContext(ctx context.Context, w io.Writer) error { - w.Write(l.b) - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/map.go b/vendor/github.com/99designs/gqlgen/graphql/map.go deleted file mode 100644 index 1e91d1d98c1..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/map.go +++ /dev/null @@ -1,24 +0,0 @@ -package graphql - -import ( - "encoding/json" - "fmt" - "io" -) - -func MarshalMap(val map[string]interface{}) Marshaler { - return WriterFunc(func(w io.Writer) { - err := json.NewEncoder(w).Encode(val) - if err != nil { - panic(err) - } - }) -} - -func UnmarshalMap(v interface{}) (map[string]interface{}, error) { - if m, ok := v.(map[string]interface{}); ok { - return m, nil - } - - return nil, fmt.Errorf("%T is not a map", v) -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/oneshot.go b/vendor/github.com/99designs/gqlgen/graphql/oneshot.go deleted file mode 100644 index 01fa15f896b..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/oneshot.go +++ /dev/null @@ -1,16 +0,0 @@ -package graphql - -import "context" - -func OneShot(resp *Response) ResponseHandler { - var oneshot bool - - return func(context context.Context) *Response { - if oneshot { - return nil - } - oneshot = true - - return resp - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go b/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go deleted file mode 100644 index 1b04a20daf7..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go +++ /dev/null @@ -1,73 +0,0 @@ -package playground - -import ( - "html/template" - "net/http" -) - -var page = template.Must(template.New("graphiql").Parse(` - - - {{.title}} - - - -
- - - - - - - - -`)) - -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=", - }) - if err != nil { - panic(err) - } - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/recovery.go b/vendor/github.com/99designs/gqlgen/graphql/recovery.go deleted file mode 100644 index 9bc0e47e1df..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/recovery.go +++ /dev/null @@ -1,20 +0,0 @@ -package graphql - -import ( - "context" - "fmt" - "os" - "runtime/debug" - - "github.com/vektah/gqlparser/v2/gqlerror" -) - -type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error) - -func DefaultRecover(ctx context.Context, err interface{}) error { - fmt.Fprintln(os.Stderr, err) - fmt.Fprintln(os.Stderr) - debug.PrintStack() - - return gqlerror.Errorf("internal system error") -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/response.go b/vendor/github.com/99designs/gqlgen/graphql/response.go deleted file mode 100644 index 0d36049a336..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/response.go +++ /dev/null @@ -1,24 +0,0 @@ -package graphql - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/vektah/gqlparser/v2/gqlerror" -) - -// Errors are intentionally serialized first based on the advice in -// https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107 -// and https://github.com/facebook/graphql/pull/384 -type Response struct { - Errors gqlerror.List `json:"errors,omitempty"` - Data json.RawMessage `json:"data"` - Extensions map[string]interface{} `json:"extensions,omitempty"` -} - -func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response { - return &Response{ - Errors: gqlerror.List{{Message: fmt.Sprintf(messagef, args...)}}, - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/root.go b/vendor/github.com/99designs/gqlgen/graphql/root.go deleted file mode 100644 index 3405d18054d..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/root.go +++ /dev/null @@ -1,7 +0,0 @@ -package graphql - -type Query struct{} - -type Mutation struct{} - -type Subscription struct{} diff --git a/vendor/github.com/99designs/gqlgen/graphql/stats.go b/vendor/github.com/99designs/gqlgen/graphql/stats.go deleted file mode 100644 index a52e143ebe4..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/stats.go +++ /dev/null @@ -1,60 +0,0 @@ -package graphql - -import ( - "context" - "fmt" - "time" -) - -type Stats struct { - OperationStart time.Time - Read TraceTiming - Parsing TraceTiming - Validation TraceTiming - - // Stats collected by handler extensions. Dont use directly, the extension should provide a type safe way to - // access this. - extension map[string]interface{} -} - -type TraceTiming struct { - Start time.Time - End time.Time -} - -var ctxTraceStart key = "trace_start" - -// StartOperationTrace captures the current time and stores it in context. This will eventually be added to request -// context but we want to grab it as soon as possible. For transports that can only handle a single graphql query -// per http requests you dont need to call this at all, the server will do it for you. For transports that handle -// multiple (eg batching, subscriptions) this should be called before decoding each request. -func StartOperationTrace(ctx context.Context) context.Context { - return context.WithValue(ctx, ctxTraceStart, Now()) -} - -// GetStartTime should only be called by the handler package, it will be set into request context -// as Stats.Start -func GetStartTime(ctx context.Context) time.Time { - t, ok := ctx.Value(ctxTraceStart).(time.Time) - if !ok { - panic(fmt.Sprintf("missing start time: %T", ctx.Value(ctxTraceStart))) - } - return t -} - -func (c *Stats) SetExtension(name string, data interface{}) { - if c.extension == nil { - c.extension = map[string]interface{}{} - } - c.extension[name] = data -} - -func (c *Stats) GetExtension(name string) interface{} { - if c.extension == nil { - return nil - } - return c.extension[name] -} - -// Now is time.Now, except in tests. Then it can be whatever you want it to be. -var Now = time.Now diff --git a/vendor/github.com/99designs/gqlgen/graphql/string.go b/vendor/github.com/99designs/gqlgen/graphql/string.go deleted file mode 100644 index 742e50cc3b7..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/string.go +++ /dev/null @@ -1,70 +0,0 @@ -package graphql - -import ( - "fmt" - "io" - "strconv" -) - -const encodeHex = "0123456789ABCDEF" - -func MarshalString(s string) Marshaler { - return WriterFunc(func(w io.Writer) { - writeQuotedString(w, s) - }) -} - -func writeQuotedString(w io.Writer, s string) { - start := 0 - io.WriteString(w, `"`) - - for i, c := range s { - if c < 0x20 || c == '\\' || c == '"' { - io.WriteString(w, s[start:i]) - - switch c { - case '\t': - io.WriteString(w, `\t`) - case '\r': - io.WriteString(w, `\r`) - case '\n': - io.WriteString(w, `\n`) - case '\\': - io.WriteString(w, `\\`) - case '"': - io.WriteString(w, `\"`) - default: - io.WriteString(w, `\u00`) - w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]}) - } - - start = i + 1 - } - } - - io.WriteString(w, s[start:]) - io.WriteString(w, `"`) -} - -func UnmarshalString(v interface{}) (string, error) { - switch v := v.(type) { - case string: - return v, nil - case int: - return strconv.Itoa(v), nil - case int64: - return strconv.FormatInt(v, 10), nil - case float64: - return fmt.Sprintf("%f", v), nil - case bool: - if v { - return "true", nil - } else { - return "false", nil - } - case nil: - return "null", nil - default: - return "", fmt.Errorf("%T is not a string", v) - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/time.go b/vendor/github.com/99designs/gqlgen/graphql/time.go deleted file mode 100644 index ef3d17da329..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/time.go +++ /dev/null @@ -1,25 +0,0 @@ -package graphql - -import ( - "errors" - "io" - "strconv" - "time" -) - -func MarshalTime(t time.Time) Marshaler { - if t.IsZero() { - return Null - } - - return WriterFunc(func(w io.Writer) { - io.WriteString(w, strconv.Quote(t.Format(time.RFC3339Nano))) - }) -} - -func UnmarshalTime(v interface{}) (time.Time, error) { - if tmpStr, ok := v.(string); ok { - return time.Parse(time.RFC3339Nano, tmpStr) - } - return time.Time{}, errors.New("time should be RFC3339Nano formatted string") -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/uint.go b/vendor/github.com/99designs/gqlgen/graphql/uint.go deleted file mode 100644 index 9349c2f4d24..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/uint.go +++ /dev/null @@ -1,81 +0,0 @@ -package graphql - -import ( - "encoding/json" - "fmt" - "io" - "strconv" -) - -func MarshalUint(i uint) Marshaler { - return WriterFunc(func(w io.Writer) { - _, _ = io.WriteString(w, strconv.FormatUint(uint64(i), 10)) - }) -} - -func UnmarshalUint(v interface{}) (uint, error) { - switch v := v.(type) { - case string: - u64, err := strconv.ParseUint(v, 10, 64) - return uint(u64), err - case int: - return uint(v), nil - case int64: - return uint(v), nil - case json.Number: - u64, err := strconv.ParseUint(string(v), 10, 64) - return uint(u64), err - default: - return 0, fmt.Errorf("%T is not an uint", v) - } -} - -func MarshalUint64(i uint64) Marshaler { - return WriterFunc(func(w io.Writer) { - _, _ = io.WriteString(w, strconv.FormatUint(i, 10)) - }) -} - -func UnmarshalUint64(v interface{}) (uint64, error) { - switch v := v.(type) { - case string: - return strconv.ParseUint(v, 10, 64) - case int: - return uint64(v), nil - case int64: - return uint64(v), nil - case json.Number: - return strconv.ParseUint(string(v), 10, 64) - default: - return 0, fmt.Errorf("%T is not an uint", v) - } -} - -func MarshalUint32(i uint32) Marshaler { - return WriterFunc(func(w io.Writer) { - _, _ = io.WriteString(w, strconv.FormatUint(uint64(i), 10)) - }) -} - -func UnmarshalUint32(v interface{}) (uint32, error) { - switch v := v.(type) { - case string: - iv, err := strconv.ParseInt(v, 10, 32) - if err != nil { - return 0, err - } - return uint32(iv), nil - case int: - return uint32(v), nil - case int64: - return uint32(v), nil - case json.Number: - iv, err := strconv.ParseUint(string(v), 10, 32) - if err != nil { - return 0, err - } - return uint32(iv), nil - default: - return 0, fmt.Errorf("%T is not an uint", v) - } -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/upload.go b/vendor/github.com/99designs/gqlgen/graphql/upload.go deleted file mode 100644 index 62f71c0dc0d..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/upload.go +++ /dev/null @@ -1,27 +0,0 @@ -package graphql - -import ( - "fmt" - "io" -) - -type Upload struct { - File io.Reader - Filename string - Size int64 - ContentType string -} - -func MarshalUpload(f Upload) Marshaler { - return WriterFunc(func(w io.Writer) { - io.Copy(w, f.File) - }) -} - -func UnmarshalUpload(v interface{}) (Upload, error) { - upload, ok := v.(Upload) - if !ok { - return Upload{}, fmt.Errorf("%T is not an Upload", v) - } - return upload, nil -} diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go deleted file mode 100644 index d2845efc7fc..00000000000 --- a/vendor/github.com/99designs/gqlgen/graphql/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package graphql - -const Version = "v0.17.2" diff --git a/vendor/github.com/99designs/gqlgen/init-templates/gqlgen.yml.gotmpl b/vendor/github.com/99designs/gqlgen/init-templates/gqlgen.yml.gotmpl deleted file mode 100644 index 589ce6ca5fc..00000000000 --- a/vendor/github.com/99designs/gqlgen/init-templates/gqlgen.yml.gotmpl +++ /dev/null @@ -1,56 +0,0 @@ -# Where are all the schema files located? globs are supported eg src/**/*.graphqls -schema: - - graph/*.graphqls - -# Where should the generated server code go? -exec: - filename: graph/generated/generated.go - package: generated - -# Uncomment to enable federation -# federation: -# filename: graph/generated/federation.go -# package: generated - -# Where should any generated models go? -model: - filename: graph/model/models_gen.go - package: model - -# Where should the resolver implementations go? -resolver: - layout: follow-schema - dir: graph - package: graph - -# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models -# struct_tag: json - -# Optional: turn on to use []Thing instead of []*Thing -# omit_slice_element_pointers: false - -# Optional: set to speed up generation time by not performing a final validation pass. -# skip_validation: true - -# gqlgen will search for any type names in the schema in these go packages -# if they match it will use them, otherwise it will generate them. -autobind: -# - "{{.}}/graph/model" - -# This section declares type mapping between the GraphQL and go type systems -# -# The first line in each type will be used as defaults for resolver arguments and -# modelgen, the others will be allowed when binding to fields. Configure them to -# your liking -models: - ID: - model: - - github.com/99designs/gqlgen/graphql.ID - - github.com/99designs/gqlgen/graphql.Int - - github.com/99designs/gqlgen/graphql.Int64 - - github.com/99designs/gqlgen/graphql.Int32 - Int: - model: - - github.com/99designs/gqlgen/graphql.Int - - github.com/99designs/gqlgen/graphql.Int64 - - github.com/99designs/gqlgen/graphql.Int32 diff --git a/vendor/github.com/99designs/gqlgen/init-templates/schema.graphqls b/vendor/github.com/99designs/gqlgen/init-templates/schema.graphqls deleted file mode 100644 index c6a91bb4808..00000000000 --- a/vendor/github.com/99designs/gqlgen/init-templates/schema.graphqls +++ /dev/null @@ -1,28 +0,0 @@ -# GraphQL schema example -# -# https://gqlgen.com/getting-started/ - -type Todo { - id: ID! - text: String! - done: Boolean! - user: User! -} - -type User { - id: ID! - name: String! -} - -type Query { - todos: [Todo!]! -} - -input NewTodo { - text: String! - userId: String! -} - -type Mutation { - createTodo(input: NewTodo!): Todo! -} diff --git a/vendor/github.com/99designs/gqlgen/internal/code/compare.go b/vendor/github.com/99designs/gqlgen/internal/code/compare.go deleted file mode 100644 index 1150a24e48c..00000000000 --- a/vendor/github.com/99designs/gqlgen/internal/code/compare.go +++ /dev/null @@ -1,161 +0,0 @@ -package code - -import ( - "fmt" - "go/types" -) - -// CompatibleTypes isnt a strict comparison, it allows for pointer differences -func CompatibleTypes(expected types.Type, actual types.Type) error { - // Special case to deal with pointer mismatches - { - expectedPtr, expectedIsPtr := expected.(*types.Pointer) - actualPtr, actualIsPtr := actual.(*types.Pointer) - - if expectedIsPtr && actualIsPtr { - return CompatibleTypes(expectedPtr.Elem(), actualPtr.Elem()) - } - if expectedIsPtr && !actualIsPtr { - return CompatibleTypes(expectedPtr.Elem(), actual) - } - if !expectedIsPtr && actualIsPtr { - return CompatibleTypes(expected, actualPtr.Elem()) - } - } - - switch expected := expected.(type) { - case *types.Slice: - if actual, ok := actual.(*types.Slice); ok { - return CompatibleTypes(expected.Elem(), actual.Elem()) - } - - case *types.Array: - if actual, ok := actual.(*types.Array); ok { - if expected.Len() != actual.Len() { - return fmt.Errorf("array length differs") - } - - return CompatibleTypes(expected.Elem(), actual.Elem()) - } - - case *types.Basic: - if actual, ok := actual.(*types.Basic); ok { - if actual.Kind() != expected.Kind() { - return fmt.Errorf("basic kind differs, %s != %s", expected.Name(), actual.Name()) - } - - return nil - } - - case *types.Struct: - if actual, ok := actual.(*types.Struct); ok { - if expected.NumFields() != actual.NumFields() { - return fmt.Errorf("number of struct fields differ") - } - - for i := 0; i < expected.NumFields(); i++ { - if expected.Field(i).Name() != actual.Field(i).Name() { - return fmt.Errorf("struct field %d name differs, %s != %s", i, expected.Field(i).Name(), actual.Field(i).Name()) - } - if err := CompatibleTypes(expected.Field(i).Type(), actual.Field(i).Type()); err != nil { - return err - } - } - return nil - } - - case *types.Tuple: - if actual, ok := actual.(*types.Tuple); ok { - if expected.Len() != actual.Len() { - return fmt.Errorf("tuple length differs, %d != %d", expected.Len(), actual.Len()) - } - - for i := 0; i < expected.Len(); i++ { - if err := CompatibleTypes(expected.At(i).Type(), actual.At(i).Type()); err != nil { - return err - } - } - - return nil - } - - case *types.Signature: - if actual, ok := actual.(*types.Signature); ok { - if err := CompatibleTypes(expected.Params(), actual.Params()); err != nil { - return err - } - if err := CompatibleTypes(expected.Results(), actual.Results()); err != nil { - return err - } - - return nil - } - case *types.Interface: - if actual, ok := actual.(*types.Interface); ok { - if expected.NumMethods() != actual.NumMethods() { - return fmt.Errorf("interface method count differs, %d != %d", expected.NumMethods(), actual.NumMethods()) - } - - for i := 0; i < expected.NumMethods(); i++ { - if expected.Method(i).Name() != actual.Method(i).Name() { - return fmt.Errorf("interface method %d name differs, %s != %s", i, expected.Method(i).Name(), actual.Method(i).Name()) - } - if err := CompatibleTypes(expected.Method(i).Type(), actual.Method(i).Type()); err != nil { - return err - } - } - - return nil - } - - case *types.Map: - if actual, ok := actual.(*types.Map); ok { - if err := CompatibleTypes(expected.Key(), actual.Key()); err != nil { - return err - } - - if err := CompatibleTypes(expected.Elem(), actual.Elem()); err != nil { - return err - } - - return nil - } - - case *types.Chan: - if actual, ok := actual.(*types.Chan); ok { - return CompatibleTypes(expected.Elem(), actual.Elem()) - } - - case *types.Named: - if actual, ok := actual.(*types.Named); ok { - if NormalizeVendor(expected.Obj().Pkg().Path()) != NormalizeVendor(actual.Obj().Pkg().Path()) { - return fmt.Errorf( - "package name of named type differs, %s != %s", - NormalizeVendor(expected.Obj().Pkg().Path()), - NormalizeVendor(actual.Obj().Pkg().Path()), - ) - } - - if expected.Obj().Name() != actual.Obj().Name() { - return fmt.Errorf( - "named type name differs, %s != %s", - NormalizeVendor(expected.Obj().Name()), - NormalizeVendor(actual.Obj().Name()), - ) - } - - return nil - } - - // Before models are generated all missing references will be Invalid Basic references. - // lets assume these are valid too. - if actual, ok := actual.(*types.Basic); ok && actual.Kind() == types.Invalid { - return nil - } - - default: - return fmt.Errorf("missing support for %T", expected) - } - - return fmt.Errorf("type mismatch %T != %T", expected, actual) -} diff --git a/vendor/github.com/99designs/gqlgen/internal/code/imports.go b/vendor/github.com/99designs/gqlgen/internal/code/imports.go deleted file mode 100644 index a46ad2c6b9f..00000000000 --- a/vendor/github.com/99designs/gqlgen/internal/code/imports.go +++ /dev/null @@ -1,151 +0,0 @@ -package code - -import ( - "go/build" - "go/parser" - "go/token" - "io/ioutil" - "path/filepath" - "regexp" - "strings" -) - -var gopaths []string - -func init() { - gopaths = filepath.SplitList(build.Default.GOPATH) - for i, p := range gopaths { - gopaths[i] = filepath.ToSlash(filepath.Join(p, "src")) - } -} - -// NameForDir manually looks for package stanzas in files located in the given directory. This can be -// much faster than having to consult go list, because we already know exactly where to look. -func NameForDir(dir string) string { - dir, err := filepath.Abs(dir) - if err != nil { - return SanitizePackageName(filepath.Base(dir)) - } - files, err := ioutil.ReadDir(dir) - if err != nil { - return SanitizePackageName(filepath.Base(dir)) - } - fset := token.NewFileSet() - for _, file := range files { - if !strings.HasSuffix(strings.ToLower(file.Name()), ".go") { - continue - } - - filename := filepath.Join(dir, file.Name()) - if src, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly); err == nil { - return src.Name.Name - } - } - - return SanitizePackageName(filepath.Base(dir)) -} - -type goModuleSearchResult struct { - path string - goModPath string - moduleName string -} - -var goModuleRootCache = map[string]goModuleSearchResult{} - -// goModuleRoot returns the root of the current go module if there is a go.mod file in the directory tree -// If not, it returns false -func goModuleRoot(dir string) (string, bool) { - dir, err := filepath.Abs(dir) - if err != nil { - panic(err) - } - dir = filepath.ToSlash(dir) - - dirs := []string{dir} - result := goModuleSearchResult{} - - for { - modDir := dirs[len(dirs)-1] - - if val, ok := goModuleRootCache[dir]; ok { - result = val - break - } - - if content, err := ioutil.ReadFile(filepath.Join(modDir, "go.mod")); err == nil { - moduleName := string(modregex.FindSubmatch(content)[1]) - result = goModuleSearchResult{ - path: moduleName, - goModPath: modDir, - moduleName: moduleName, - } - goModuleRootCache[modDir] = result - break - } - - if modDir == "" || modDir == "." || modDir == "/" || strings.HasSuffix(modDir, "\\") { - // Reached the top of the file tree which means go.mod file is not found - // Set root folder with a sentinel cache value - goModuleRootCache[modDir] = result - break - } - - dirs = append(dirs, filepath.Dir(modDir)) - } - - // create a cache for each path in a tree traversed, except the top one as it is already cached - for _, d := range dirs[:len(dirs)-1] { - if result.moduleName == "" { - // go.mod is not found in the tree, so the same sentinel value fits all the directories in a tree - goModuleRootCache[d] = result - } else { - if relPath, err := filepath.Rel(result.goModPath, d); err != nil { - panic(err) - } else { - path := result.moduleName - relPath := filepath.ToSlash(relPath) - if !strings.HasSuffix(relPath, "/") { - path += "/" - } - path += relPath - - goModuleRootCache[d] = goModuleSearchResult{ - path: path, - goModPath: result.goModPath, - moduleName: result.moduleName, - } - } - } - } - - res := goModuleRootCache[dir] - if res.moduleName == "" { - return "", false - } - return res.path, true -} - -// ImportPathForDir takes a path and returns a golang import path for the package -func ImportPathForDir(dir string) (res string) { - dir, err := filepath.Abs(dir) - if err != nil { - panic(err) - } - dir = filepath.ToSlash(dir) - - modDir, ok := goModuleRoot(dir) - if ok { - return modDir - } - - for _, gopath := range gopaths { - if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) { - return dir[len(gopath)+1:] - } - } - - return "" -} - -var modregex = regexp.MustCompile(`module ([^\s]*)`) diff --git a/vendor/github.com/99designs/gqlgen/internal/code/packages.go b/vendor/github.com/99designs/gqlgen/internal/code/packages.go deleted file mode 100644 index c800d3d84f2..00000000000 --- a/vendor/github.com/99designs/gqlgen/internal/code/packages.go +++ /dev/null @@ -1,223 +0,0 @@ -package code - -import ( - "bytes" - "errors" - "fmt" - "os" - "os/exec" - "path/filepath" - - "golang.org/x/tools/go/packages" -) - -var mode = packages.NeedName | - packages.NeedFiles | - packages.NeedImports | - packages.NeedTypes | - packages.NeedSyntax | - packages.NeedTypesInfo | - 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. -type Packages struct { - packages map[string]*packages.Package - importToName map[string]string - loadErrors []error - - numLoadCalls int // stupid test steam. ignore. - numNameCalls int // stupid test steam. ignore. -} - -// ReloadAll will call LoadAll after clearing the package cache, so we can reload -// packages in the case that the packages have changed -func (p *Packages) ReloadAll(importPaths ...string) []*packages.Package { - p.packages = nil - return p.LoadAll(importPaths...) -} - -func (p *Packages) checkModuleLoaded(pkgs []*packages.Package) bool { - for i := range pkgs { - if pkgs[i] == nil || pkgs[i].Module == nil { - return false - } - } - return true -} - -// LoadAll will call packages.Load and return the package data for the given packages, -// but if the package already have been loaded it will return cached values instead. -func (p *Packages) LoadAll(importPaths ...string) []*packages.Package { - if p.packages == nil { - p.packages = map[string]*packages.Package{} - } - - missing := make([]string, 0, len(importPaths)) - for _, path := range importPaths { - if _, ok := p.packages[path]; ok { - continue - } - missing = append(missing, path) - } - - if len(missing) > 0 { - p.numLoadCalls++ - pkgs, err := packages.Load(&packages.Config{Mode: mode}, missing...) - - // Sometimes packages.Load not loaded the module info. Call it again to reload it. - if !p.checkModuleLoaded(pkgs) { - fmt.Println("reloading module info") - pkgs, err = packages.Load(&packages.Config{Mode: mode}, missing...) - } - - if err != nil { - p.loadErrors = append(p.loadErrors, err) - } - - for _, pkg := range pkgs { - p.addToCache(pkg) - } - } - - res := make([]*packages.Package, 0, len(importPaths)) - for _, path := range importPaths { - res = append(res, p.packages[NormalizeVendor(path)]) - } - return res -} - -func (p *Packages) addToCache(pkg *packages.Package) { - imp := NormalizeVendor(pkg.PkgPath) - p.packages[imp] = pkg - for _, imp := range pkg.Imports { - if _, found := p.packages[NormalizeVendor(imp.PkgPath)]; !found { - p.addToCache(imp) - } - } -} - -// Load works the same as LoadAll, except a single package at a time. -func (p *Packages) Load(importPath string) *packages.Package { - // Quick cache check first to avoid expensive allocations of LoadAll() - if p.packages != nil { - if pkg, ok := p.packages[importPath]; ok { - return pkg - } - } - - pkgs := p.LoadAll(importPath) - if len(pkgs) == 0 { - return nil - } - return pkgs[0] -} - -// LoadWithTypes tries a standard load, which may not have enough type info (TypesInfo== nil) available if the imported package is a -// second order dependency. Fortunately this doesnt happen very often, so we can just issue a load when we detect it. -func (p *Packages) LoadWithTypes(importPath string) *packages.Package { - pkg := p.Load(importPath) - if pkg == nil || pkg.TypesInfo == nil { - p.numLoadCalls++ - pkgs, err := packages.Load(&packages.Config{Mode: mode}, importPath) - if err != nil { - p.loadErrors = append(p.loadErrors, err) - return nil - } - p.addToCache(pkgs[0]) - pkg = pkgs[0] - } - return pkg -} - -// NameForPackage looks up the package name from the package stanza in the go files at the given import path. -func (p *Packages) NameForPackage(importPath string) string { - if importPath == "" { - panic(errors.New("import path can not be empty")) - } - if p.importToName == nil { - p.importToName = map[string]string{} - } - - importPath = NormalizeVendor(importPath) - - // if its in the name cache use it - if name := p.importToName[importPath]; name != "" { - return name - } - - // otherwise we might have already loaded the full package data for it cached - pkg := p.packages[importPath] - - if pkg == nil { - // otherwise do a name only lookup for it but dont put it in the package cache. - p.numNameCalls++ - pkgs, err := packages.Load(&packages.Config{Mode: packages.NeedName}, importPath) - if err != nil { - p.loadErrors = append(p.loadErrors, err) - } else { - pkg = pkgs[0] - } - } - - if pkg == nil || pkg.Name == "" { - return SanitizePackageName(filepath.Base(importPath)) - } - - p.importToName[importPath] = pkg.Name - - return pkg.Name -} - -// Evict removes a given package import path from the cache, along with any packages that depend on it. Further calls -// to Load will fetch it from disk. -func (p *Packages) Evict(importPath string) { - delete(p.packages, importPath) - - for _, pkg := range p.packages { - for _, imported := range pkg.Imports { - if imported.PkgPath == importPath { - p.Evict(pkg.PkgPath) - } - } - } -} - -func (p *Packages) ModTidy() error { - p.packages = nil - tidyCmd := exec.Command("go", "mod", "tidy") - tidyCmd.Stdout = os.Stdout - tidyCmd.Stderr = os.Stdout - if err := tidyCmd.Run(); err != nil { - return fmt.Errorf("go mod tidy failed: %w", err) - } - return nil -} - -// Errors returns any errors that were returned by Load, either from the call itself or any of the loaded packages. -func (p *Packages) Errors() PkgErrors { - var res []error //nolint:prealloc - res = append(res, p.loadErrors...) - for _, pkg := range p.packages { - for _, err := range pkg.Errors { - res = append(res, err) - } - } - return res -} - -func (p *Packages) Count() int { - return len(p.packages) -} - -type PkgErrors []error - -func (p PkgErrors) Error() string { - var b bytes.Buffer - b.WriteString("packages.Load: ") - for _, e := range p { - b.WriteString(e.Error() + "\n") - } - return b.String() -} diff --git a/vendor/github.com/99designs/gqlgen/internal/code/util.go b/vendor/github.com/99designs/gqlgen/internal/code/util.go deleted file mode 100644 index cbe40858e24..00000000000 --- a/vendor/github.com/99designs/gqlgen/internal/code/util.go +++ /dev/null @@ -1,61 +0,0 @@ -package code - -import ( - "go/build" - "os" - "path/filepath" - "regexp" - "strings" -) - -// take a string in the form github.com/package/blah.Type and split it into package and type -func PkgAndType(name string) (string, string) { - parts := strings.Split(name, ".") - if len(parts) == 1 { - return "", name - } - - return strings.Join(parts[:len(parts)-1], "."), parts[len(parts)-1] -} - -var modsRegex = regexp.MustCompile(`^(\*|\[\])*`) - -// NormalizeVendor takes a qualified package path and turns it into normal one. -// eg . -// github.com/foo/vendor/github.com/99designs/gqlgen/graphql becomes -// github.com/99designs/gqlgen/graphql -func NormalizeVendor(pkg string) string { - modifiers := modsRegex.FindAllString(pkg, 1)[0] - pkg = strings.TrimPrefix(pkg, modifiers) - parts := strings.Split(pkg, "/vendor/") - return modifiers + parts[len(parts)-1] -} - -// QualifyPackagePath takes an import and fully qualifies it with a vendor dir, if one is required. -// eg . -// github.com/99designs/gqlgen/graphql becomes -// github.com/foo/vendor/github.com/99designs/gqlgen/graphql -// -// x/tools/packages only supports 'qualified package paths' so this will need to be done prior to calling it -// See https://github.com/golang/go/issues/30289 -func QualifyPackagePath(importPath string) string { - wd, _ := os.Getwd() - - // in go module mode, the import path doesn't need fixing - if _, ok := goModuleRoot(wd); ok { - return importPath - } - - pkg, err := build.Import(importPath, wd, 0) - if err != nil { - return importPath - } - - return pkg.ImportPath -} - -var invalidPackageNameChar = regexp.MustCompile(`[^\w]`) - -func SanitizePackageName(pkg string) string { - return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_") -} diff --git a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go deleted file mode 100644 index d42a4157913..00000000000 --- a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go +++ /dev/null @@ -1,100 +0,0 @@ -// Wrapper around x/tools/imports that only removes imports, never adds new ones. - -package imports - -import ( - "bytes" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "strings" - - "github.com/99designs/gqlgen/internal/code" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/imports" -) - -type visitFn func(node ast.Node) - -func (fn visitFn) Visit(node ast.Node) ast.Visitor { - fn(node) - return fn -} - -// Prune removes any unused imports -func Prune(filename string, src []byte, packages *code.Packages) ([]byte, error) { - fset := token.NewFileSet() - - file, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.AllErrors) - if err != nil { - return nil, err - } - - unused := getUnusedImports(file, packages) - for ipath, name := range unused { - astutil.DeleteNamedImport(fset, file, name, ipath) - } - printConfig := &printer.Config{Mode: printer.TabIndent, Tabwidth: 8} - - var buf bytes.Buffer - if err := printConfig.Fprint(&buf, fset, file); err != nil { - return nil, err - } - - return imports.Process(filename, buf.Bytes(), &imports.Options{FormatOnly: true, Comments: true, TabIndent: true, TabWidth: 8}) -} - -func getUnusedImports(file ast.Node, packages *code.Packages) map[string]string { - imported := map[string]*ast.ImportSpec{} - used := map[string]bool{} - - ast.Walk(visitFn(func(node ast.Node) { - if node == nil { - return - } - switch v := node.(type) { - case *ast.ImportSpec: - if v.Name != nil { - imported[v.Name.Name] = v - break - } - ipath := strings.Trim(v.Path.Value, `"`) - if ipath == "C" { - break - } - - local := packages.NameForPackage(ipath) - - imported[local] = v - case *ast.SelectorExpr: - xident, ok := v.X.(*ast.Ident) - if !ok { - break - } - if xident.Obj != nil { - // if the parser can resolve it, it's not a package ref - break - } - used[xident.Name] = true - } - }), file) - - for pkg := range used { - delete(imported, pkg) - } - - unusedImport := map[string]string{} - for pkg, is := range imported { - if !used[pkg] && pkg != "_" && pkg != "." { - name := "" - if is.Name != nil { - name = is.Name.Name - } - unusedImport[strings.Trim(is.Path.Value, `"`)] = name - } - } - - return unusedImport -} diff --git a/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go b/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go deleted file mode 100644 index f70fbdc1d59..00000000000 --- a/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go +++ /dev/null @@ -1,195 +0,0 @@ -package rewrite - -import ( - "bytes" - "fmt" - "go/ast" - "go/token" - "io/ioutil" - "path/filepath" - "strconv" - "strings" - - "github.com/99designs/gqlgen/internal/code" - "golang.org/x/tools/go/packages" -) - -type Rewriter struct { - pkg *packages.Package - files map[string]string - copied map[ast.Decl]bool -} - -func New(dir string) (*Rewriter, error) { - importPath := code.ImportPathForDir(dir) - if importPath == "" { - return nil, fmt.Errorf("import path not found for directory: %q", dir) - } - pkgs, err := packages.Load(&packages.Config{ - Mode: packages.NeedSyntax | packages.NeedTypes, - }, importPath) - if err != nil { - return nil, err - } - if len(pkgs) == 0 { - return nil, fmt.Errorf("package not found for importPath: %s", importPath) - } - - return &Rewriter{ - pkg: pkgs[0], - files: map[string]string{}, - copied: map[ast.Decl]bool{}, - }, nil -} - -func (r *Rewriter) getSource(start, end token.Pos) string { - startPos := r.pkg.Fset.Position(start) - endPos := r.pkg.Fset.Position(end) - - if startPos.Filename != endPos.Filename { - panic("cant get source spanning multiple files") - } - - file := r.getFile(startPos.Filename) - return file[startPos.Offset:endPos.Offset] -} - -func (r *Rewriter) getFile(filename string) string { - if _, ok := r.files[filename]; !ok { - b, err := ioutil.ReadFile(filename) - if err != nil { - panic(fmt.Errorf("unable to load file, already exists: %w", err)) - } - - r.files[filename] = string(b) - - } - - return r.files[filename] -} - -func (r *Rewriter) GetMethodBody(structname string, methodname string) string { - for _, f := range r.pkg.Syntax { - for _, d := range f.Decls { - d, isFunc := d.(*ast.FuncDecl) - if !isFunc { - continue - } - if d.Name.Name != methodname { - continue - } - if d.Recv == nil || len(d.Recv.List) == 0 { - continue - } - recv := d.Recv.List[0].Type - if star, isStar := recv.(*ast.StarExpr); isStar { - recv = star.X - } - ident, ok := recv.(*ast.Ident) - if !ok { - continue - } - - if ident.Name != structname { - continue - } - - r.copied[d] = true - - return r.getSource(d.Body.Pos()+1, d.Body.End()-1) - } - } - - return "" -} - -func (r *Rewriter) MarkStructCopied(name string) { - for _, f := range r.pkg.Syntax { - for _, d := range f.Decls { - d, isGen := d.(*ast.GenDecl) - if !isGen { - continue - } - if d.Tok != token.TYPE || len(d.Specs) == 0 { - continue - } - - spec, isTypeSpec := d.Specs[0].(*ast.TypeSpec) - if !isTypeSpec { - continue - } - - if spec.Name.Name != name { - continue - } - - r.copied[d] = true - } - } -} - -func (r *Rewriter) ExistingImports(filename string) []Import { - filename, err := filepath.Abs(filename) - if err != nil { - panic(err) - } - for _, f := range r.pkg.Syntax { - pos := r.pkg.Fset.Position(f.Pos()) - - if filename != pos.Filename { - continue - } - - var imps []Import - for _, i := range f.Imports { - name := "" - if i.Name != nil { - name = i.Name.Name - } - path, err := strconv.Unquote(i.Path.Value) - if err != nil { - panic(err) - } - imps = append(imps, Import{name, path}) - } - return imps - } - return nil -} - -func (r *Rewriter) RemainingSource(filename string) string { - filename, err := filepath.Abs(filename) - if err != nil { - panic(err) - } - for _, f := range r.pkg.Syntax { - pos := r.pkg.Fset.Position(f.Pos()) - - if filename != pos.Filename { - continue - } - - var buf bytes.Buffer - - for _, d := range f.Decls { - if r.copied[d] { - continue - } - - if d, isGen := d.(*ast.GenDecl); isGen && d.Tok == token.IMPORT { - continue - } - - buf.WriteString(r.getSource(d.Pos(), d.End())) - buf.WriteString("\n") - } - - return strings.TrimSpace(buf.String()) - } - return "" -} - -type Import struct { - Alias string - ImportPath string -} diff --git a/vendor/github.com/99designs/gqlgen/main.go b/vendor/github.com/99designs/gqlgen/main.go deleted file mode 100644 index 82c4f1924bd..00000000000 --- a/vendor/github.com/99designs/gqlgen/main.go +++ /dev/null @@ -1,190 +0,0 @@ -package main - -import ( - "bytes" - _ "embed" - "errors" - "fmt" - "html/template" - "io/fs" - "io/ioutil" - "log" - "os" - "path/filepath" - - "github.com/99designs/gqlgen/api" - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/internal/code" - "github.com/99designs/gqlgen/plugin/servergen" - "github.com/urfave/cli/v2" -) - -//go:embed init-templates/schema.graphqls -var schemaFileContent string - -//go:embed init-templates/gqlgen.yml.gotmpl -var configFileTemplate string - -func getConfigFileContent(pkgName string) string { - var buf bytes.Buffer - if err := template.Must(template.New("gqlgen.yml").Parse(configFileTemplate)).Execute(&buf, pkgName); err != nil { - panic(err) - } - return buf.String() -} - -func fileExists(filename string) bool { - _, err := os.Stat(filename) - return !errors.Is(err, fs.ErrNotExist) -} - -func initFile(filename, contents string) error { - if err := os.MkdirAll(filepath.Dir(filename), 0o755); err != nil { - return fmt.Errorf("unable to create directory for file '%s': %w\n", filename, err) - } - if err := ioutil.WriteFile(filename, []byte(contents), 0o644); err != nil { - return fmt.Errorf("unable to write file '%s': %w\n", filename, err) - } - - return nil -} - -var initCmd = &cli.Command{ - Name: "init", - Usage: "create a new gqlgen project", - Flags: []cli.Flag{ - &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, - &cli.StringFlag{Name: "config, c", Usage: "the config filename", Value: "gqlgen.yml"}, - &cli.StringFlag{Name: "server", Usage: "where to write the server stub to", Value: "server.go"}, - &cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "graph/schema.graphqls"}, - }, - Action: func(ctx *cli.Context) error { - configFilename := ctx.String("config") - serverFilename := ctx.String("server") - schemaFilename := ctx.String("schema") - - pkgName := code.ImportPathForDir(".") - if pkgName == "" { - return fmt.Errorf("unable to determine import path for current directory, you probably need to run 'go mod init' first") - } - - // check schema and config don't already exist - for _, filename := range []string{configFilename, schemaFilename, serverFilename} { - if fileExists(filename) { - return fmt.Errorf("%s already exists", filename) - } - } - _, err := config.LoadConfigFromDefaultLocations() - if err == nil { - return fmt.Errorf("gqlgen.yml already exists in a parent directory\n") - } - - // create config - fmt.Println("Creating", configFilename) - if err := initFile(configFilename, getConfigFileContent(pkgName)); err != nil { - return err - } - - // create schema - fmt.Println("Creating", schemaFilename) - - if err := initFile(schemaFilename, schemaFileContent); err != nil { - return err - } - - // create the package directory with a temporary file so that go recognises it as a package - // and autobinding doesn't error out - tmpPackageNameFile := "graph/model/_tmp_gqlgen_init.go" - if err := initFile(tmpPackageNameFile, "package model"); err != nil { - return err - } - defer os.Remove(tmpPackageNameFile) - - var cfg *config.Config - if cfg, err = config.LoadConfig(configFilename); err != nil { - panic(err) - } - - fmt.Println("Creating", serverFilename) - fmt.Println("Generating...") - if err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename))); err != nil { - return err - } - - fmt.Printf("\nExec \"go run ./%s\" to start GraphQL server\n", serverFilename) - return nil - }, -} - -var generateCmd = &cli.Command{ - Name: "generate", - Usage: "generate a graphql server based on schema", - Flags: []cli.Flag{ - &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, - &cli.StringFlag{Name: "config, c", Usage: "the config filename"}, - }, - Action: func(ctx *cli.Context) error { - var cfg *config.Config - var err error - if configFilename := ctx.String("config"); configFilename != "" { - cfg, err = config.LoadConfig(configFilename) - if err != nil { - return err - } - } else { - cfg, err = config.LoadConfigFromDefaultLocations() - if errors.Is(err, fs.ErrNotExist) { - cfg, err = config.LoadDefaultConfig() - } - - if err != nil { - return err - } - } - - if err = api.Generate(cfg); err != nil { - return err - } - return nil - }, -} - -var versionCmd = &cli.Command{ - Name: "version", - Usage: "print the version string", - Action: func(ctx *cli.Context) error { - fmt.Println(graphql.Version) - return nil - }, -} - -func main() { - app := cli.NewApp() - app.Name = "gqlgen" - app.Usage = generateCmd.Usage - app.Description = "This is a library for quickly creating strictly typed graphql servers in golang. See https://gqlgen.com/ for a getting started guide." - app.HideVersion = true - app.Flags = generateCmd.Flags - app.Version = graphql.Version - app.Before = func(context *cli.Context) error { - if context.Bool("verbose") { - log.SetFlags(0) - } else { - log.SetOutput(ioutil.Discard) - } - return nil - } - - app.Action = generateCmd.Action - app.Commands = []*cli.Command{ - generateCmd, - initCmd, - versionCmd, - } - - if err := app.Run(os.Args); err != nil { - fmt.Fprint(os.Stderr, err.Error()+"\n") - os.Exit(1) - } -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go deleted file mode 100644 index 55160bac512..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go +++ /dev/null @@ -1,378 +0,0 @@ -package federation - -import ( - "fmt" - "sort" - "strings" - - "github.com/vektah/gqlparser/v2/ast" - - "github.com/99designs/gqlgen/codegen" - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/99designs/gqlgen/plugin" - "github.com/99designs/gqlgen/plugin/federation/fieldset" -) - -type federation struct { - Entities []*Entity -} - -// New returns a federation plugin that injects -// federated directives and types into the schema -func New() plugin.Plugin { - return &federation{} -} - -// Name returns the plugin name -func (f *federation) Name() string { - return "federation" -} - -// MutateConfig mutates the configuration -func (f *federation) MutateConfig(cfg *config.Config) error { - builtins := config.TypeMap{ - "_Service": { - Model: config.StringList{ - "github.com/99designs/gqlgen/plugin/federation/fedruntime.Service", - }, - }, - "_Entity": { - Model: config.StringList{ - "github.com/99designs/gqlgen/plugin/federation/fedruntime.Entity", - }, - }, - "Entity": { - Model: config.StringList{ - "github.com/99designs/gqlgen/plugin/federation/fedruntime.Entity", - }, - }, - "_Any": { - 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) - } - cfg.Models[typeName] = entry - } - cfg.Directives["external"] = config.DirectiveConfig{SkipRuntime: true} - cfg.Directives["requires"] = config.DirectiveConfig{SkipRuntime: true} - cfg.Directives["provides"] = config.DirectiveConfig{SkipRuntime: true} - cfg.Directives["key"] = config.DirectiveConfig{SkipRuntime: true} - cfg.Directives["extends"] = config.DirectiveConfig{SkipRuntime: true} - - return nil -} - -func (f *federation) InjectSourceEarly() *ast.Source { - 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 -`, - BuiltIn: true, - } -} - -// InjectSources creates a GraphQL Entity type with all -// the fields that had the @key directive -func (f *federation) InjectSourceLate(schema *ast.Schema) *ast.Source { - f.setEntities(schema) - - var entities, resolvers, entityResolverInputDefinitions string - for i, e := range f.Entities { - if i != 0 { - entities += " | " - } - entities += e.Name - - for _, r := range e.Resolvers { - if e.Multi { - if entityResolverInputDefinitions != "" { - entityResolverInputDefinitions += "\n\n" - } - entityResolverInputDefinitions += "input " + r.InputType + " {\n" - for _, keyField := range r.KeyFields { - entityResolverInputDefinitions += fmt.Sprintf("\t%s: %s\n", keyField.Field.ToGo(), keyField.Definition.Type.String()) - } - entityResolverInputDefinitions += "}" - resolvers += fmt.Sprintf("\t%s(reps: [%s!]!): [%s]\n", r.ResolverName, r.InputType, e.Name) - } else { - resolverArgs := "" - for _, keyField := range r.KeyFields { - resolverArgs += fmt.Sprintf("%s: %s,", keyField.Field.ToGoPrivate(), keyField.Definition.Type.String()) - } - resolvers += fmt.Sprintf("\t%s(%s): %s!\n", r.ResolverName, resolverArgs, e.Name) - } - } - } - - var blocks []string - if entities != "" { - entities = `# a union of all types that use the @key directive -union _Entity = ` + entities - blocks = append(blocks, entities) - } - - // resolvers can be empty if a service defines only "empty - // extend" types. This should be rare. - if resolvers != "" { - if entityResolverInputDefinitions != "" { - blocks = append(blocks, entityResolverInputDefinitions) - } - resolvers = `# fake type to build resolver interfaces for users to implement -type Entity { - ` + resolvers + ` -}` - blocks = append(blocks, resolvers) - } - - _serviceTypeDef := `type _Service { - sdl: String -}` - blocks = append(blocks, _serviceTypeDef) - - var additionalQueryFields string - // Quote from the Apollo Federation subgraph specification: - // If no types are annotated with the key directive, then the - // _Entity union and _entities field should be removed from the schema - if len(f.Entities) > 0 { - additionalQueryFields += ` _entities(representations: [_Any!]!): [_Entity]! -` - } - // _service field is required in any case - additionalQueryFields += ` _service: _Service!` - - extendTypeQueryDef := `extend type ` + schema.Query.Name + ` { -` + additionalQueryFields + ` -}` - blocks = append(blocks, extendTypeQueryDef) - - return &ast.Source{ - Name: "federation/entity.graphql", - BuiltIn: true, - Input: "\n" + strings.Join(blocks, "\n\n") + "\n", - } -} - -// Entity represents a federated type -// that was declared in the GQL schema. -type Entity struct { - Name string // The same name as the type declaration - Def *ast.Definition - Resolvers []*EntityResolver - Requires []*Requires - Multi bool -} - -type EntityResolver struct { - ResolverName string // The resolver name, such as FindUserByID - KeyFields []*KeyField // The fields declared in @key. - InputType string // The Go generated input type for multi entity resolvers -} - -type KeyField struct { - Definition *ast.FieldDefinition - Field fieldset.Field // len > 1 for nested fields - Type *config.TypeReference // The Go representation of that field type -} - -// Requires represents an @requires clause -type Requires struct { - Name string // the name of the field - Field fieldset.Field // source Field, len > 1 for nested fields - Type *config.TypeReference // The Go representation of that field type -} - -func (e *Entity) allFieldsAreExternal() bool { - for _, field := range e.Def.Fields { - if field.Directives.ForName("external") == nil { - return false - } - } - return true -} - -func (f *federation) GenerateCode(data *codegen.Data) error { - if len(f.Entities) > 0 { - if data.Objects.ByName("Entity") != nil { - data.Objects.ByName("Entity").Root = true - } - for _, e := range f.Entities { - obj := data.Objects.ByName(e.Def.Name) - - for _, r := range e.Resolvers { - // fill in types for key fields - // - for _, keyField := range r.KeyFields { - if len(keyField.Field) == 0 { - fmt.Println( - "skipping @key field " + keyField.Definition.Name + " in " + r.ResolverName + " in " + e.Def.Name, - ) - continue - } - cgField := keyField.Field.TypeReference(obj, data.Objects) - keyField.Type = cgField.TypeReference - } - } - - // fill in types for requires fields - // - for _, reqField := range e.Requires { - if len(reqField.Field) == 0 { - fmt.Println("skipping @requires field " + reqField.Name + " in " + e.Def.Name) - continue - } - cgField := reqField.Field.TypeReference(obj, data.Objects) - reqField.Type = cgField.TypeReference - } - } - } - - return templates.Render(templates.Options{ - PackageName: data.Config.Federation.Package, - Filename: data.Config.Federation.Filename, - Data: f, - GeneratedHeader: true, - Packages: data.Config.Packages, - }) -} - -func (f *federation) setEntities(schema *ast.Schema) { - for _, schemaType := range schema.Types { - keys, ok := isFederatedEntity(schemaType) - if !ok { - continue - } - e := &Entity{ - Name: schemaType.Name, - Def: schemaType, - Resolvers: nil, - Requires: nil, - } - - // Let's process custom entity resolver settings. - dir := schemaType.Directives.ForName("entityResolver") - if dir != nil { - if dirArg := dir.Arguments.ForName("multi"); dirArg != nil { - if dirVal, err := dirArg.Value.Value(nil); err == nil { - e.Multi = dirVal.(bool) - } - } - } - - // If our schema has a field with a type defined in - // another service, then we need to define an "empty - // extend" of that type in this service, so this service - // knows what the type is like. But the graphql-server - // will never ask us to actually resolve this "empty - // extend", so we don't require a resolver function for - // it. (Well, it will never ask in practice; it's - // unclear whether the spec guarantees this. See - // https://github.com/apollographql/apollo-server/issues/3852 - // ). Example: - // type MyType { - // myvar: TypeDefinedInOtherService - // } - // // Federation needs this type, but - // // it doesn't need a resolver for it! - // extend TypeDefinedInOtherService @key(fields: "id") { - // id: ID @external - // } - 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.") - } - arg := dir.Arguments[0] - keyFieldSet := fieldset.New(arg.Value.Raw, nil) - - keyFields := make([]*KeyField, len(keyFieldSet)) - resolverFields := []string{} - for i, field := range keyFieldSet { - def := field.FieldDefinition(schemaType, schema) - - if def == nil { - panic(fmt.Sprintf("no field for %v", field)) - } - - keyFields[i] = &KeyField{Definition: def, Field: field} - resolverFields = append(resolverFields, keyFields[i].Field.ToGo()) - } - - resolverFieldsToGo := schemaType.Name + "By" + strings.Join(resolverFields, "And") - var resolverName string - if e.Multi { - resolverFieldsToGo += "s" // Pluralize for better API readability - resolverName = fmt.Sprintf("findMany%s", resolverFieldsToGo) - } else { - resolverName = fmt.Sprintf("find%s", resolverFieldsToGo) - } - - e.Resolvers = append(e.Resolvers, &EntityResolver{ - ResolverName: resolverName, - KeyFields: keyFields, - InputType: resolverFieldsToGo + "Input", - }) - } - - e.Requires = []*Requires{} - for _, f := range schemaType.Fields { - dir := f.Directives.ForName("requires") - if dir == nil { - continue - } - if len(dir.Arguments) != 1 || dir.Arguments[0].Name != "fields" { - panic("Exactly one `fields` argument needed for @requires declaration.") - } - requiresFieldSet := fieldset.New(dir.Arguments[0].Value.Raw, nil) - for _, field := range requiresFieldSet { - e.Requires = append(e.Requires, &Requires{ - Name: field.ToGoPrivate(), - Field: field, - }) - } - } - } - f.Entities = append(f.Entities, e) - } - - // make sure order remains stable across multiple builds - sort.Slice(f.Entities, func(i, j int) bool { - return f.Entities[i].Name < f.Entities[j].Name - }) -} - -func isFederatedEntity(schemaType *ast.Definition) ([]*ast.Directive, bool) { - switch schemaType.Kind { - case ast.Object: - keys := schemaType.Directives.ForNames("key") - if len(keys) > 0 { - return keys, true - } - case ast.Interface: - // TODO: support @key and @extends for interfaces - if dir := schemaType.Directives.ForName("key"); dir != nil { - fmt.Printf("@key directive found on \"interface %s\". Will be ignored.\n", schemaType.Name) - } - if dir := schemaType.Directives.ForName("extends"); dir != nil { - panic( - fmt.Sprintf( - "@extends directive is not currently supported for interfaces, use \"extend interface %s\" instead.", - schemaType.Name, - )) - } - default: - // ignore - } - return nil, false -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl deleted file mode 100644 index 4a30b6c9787..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl +++ /dev/null @@ -1,259 +0,0 @@ -{{ reserveImport "context" }} -{{ reserveImport "errors" }} -{{ reserveImport "fmt" }} -{{ reserveImport "strings" }} -{{ reserveImport "sync" }} - -{{ reserveImport "github.com/99designs/gqlgen/plugin/federation/fedruntime" }} - -var ( - ErrUnknownType = errors.New("unknown type") - ErrTypeNotFound = errors.New("type not found") -) - -func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { - if ec.DisableIntrospection { - return fedruntime.Service{}, errors.New("federated introspection disabled") - } - - var sdl []string - - for _, src := range sources { - if src.BuiltIn { - continue - } - sdl = append(sdl, src.Input) - } - - return fedruntime.Service{ - SDL: strings.Join(sdl, "\n"), - }, nil -} - -{{if .Entities}} -func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { - list := make([]fedruntime.Entity, len(representations)) - - repsMap := map[string]struct { - i []int - r []map[string]interface{} - }{} - - // We group entities by typename so that we can parallelize their resolution. - // This is particularly helpful when there are entity groups in multi mode. - buildRepresentationGroups := func(reps []map[string]interface{}) { - for i, rep := range reps { - typeName, ok := rep["__typename"].(string) - if !ok { - // If there is no __typename, we just skip the representation; - // we just won't be resolving these unknown types. - ec.Error(ctx, errors.New("__typename must be an existing string")) - continue - } - - _r := repsMap[typeName] - _r.i = append(_r.i, i) - _r.r = append(_r.r, rep) - repsMap[typeName] = _r - } - } - - isMulti := func(typeName string) bool { - switch typeName { - {{- range .Entities -}} - {{- if .Resolvers -}} - {{- if .Multi -}} - case "{{.Def.Name}}": - return true - {{ end }} - {{- end -}} - {{- end -}} - default: - return false - } - } - - resolveEntity := func(ctx context.Context, typeName string, rep map[string]interface{}, idx []int, i int) (err error) { - // we need to do our own panic handling, because we may be called in a - // goroutine, where the usual panic handling can't catch us - defer func () { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - } - }() - - switch typeName { - {{ range $_, $entity := .Entities }} - {{- if and .Resolvers (not .Multi) -}} - case "{{.Def.Name}}": - resolverName, err := entityResolverNameFor{{.Def.Name}}(ctx, rep) - if err != nil { - return fmt.Errorf(`finding resolver for Entity "{{.Def.Name}}": %w`, err) - } - switch resolverName { - {{ range $i, $resolver := .Resolvers }} - case "{{.ResolverName}}": - {{- range $j, $keyField := .KeyFields }} - id{{$j}}, err := ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) - if err != nil { - return fmt.Errorf(`unmarshalling param {{$j}} for {{$resolver.ResolverName}}(): %w`, err) - } - {{- end}} - entity, err := ec.resolvers.Entity().{{.ResolverName | go}}(ctx, {{- range $j, $_ := .KeyFields -}} id{{$j}}, {{end}}) - if err != nil { - return fmt.Errorf(`resolving Entity "{{$entity.Def.Name}}": %w`, err) - } - {{ range $entity.Requires }} - entity.{{.Field.JoinGo `.`}}, err = ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) - if err != nil { - return err - } - {{- end }} - list[idx[i]] = entity - return nil - {{- end }} - } - {{ end }} - {{- end }} - } - return fmt.Errorf("%w: %s", ErrUnknownType, typeName) - } - - resolveManyEntities := func(ctx context.Context, typeName string, reps []map[string]interface{}, idx []int) (err error) { - // we need to do our own panic handling, because we may be called in a - // goroutine, where the usual panic handling can't catch us - defer func () { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - } - }() - - switch typeName { - {{ range $_, $entity := .Entities }} - {{ if and .Resolvers .Multi -}} - case "{{.Def.Name}}": - {{range $i, $_ := .Resolvers -}} - _reps := make([]*{{.InputType}}, len(reps)) - - for i, rep := range reps { - {{ range $i, $keyField := .KeyFields -}} - id{{$i}}, err := ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) - if err != nil { - return errors.New(fmt.Sprintf("Field %s undefined in schema.", "{{.Definition.Name}}")) - } - {{end}} - - _reps[i] = &{{.InputType}} { - {{ range $i, $keyField := .KeyFields -}} - {{$keyField.Field.ToGo}}: id{{$i}}, - {{end}} - } - } - - entities, err := ec.resolvers.Entity().{{.ResolverName | go}}(ctx, _reps) - if err != nil { - return err - } - - for i, entity := range entities { - {{- range $entity.Requires }} - entity.{{.Field.JoinGo `.`}}, err = ec.{{.Type.UnmarshalFunc}}(ctx, reps[i]["{{.Field.Join `"].(map[string]interface{})["`}}"]) - if err != nil { - return err - } - {{- end}} - list[idx[i]] = entity - } - return nil - {{ end }} - {{ end }} - {{- end }} - default: - return errors.New("unknown type: "+typeName) - } - } - - resolveEntityGroup := func(typeName string, reps []map[string]interface{}, idx []int) { - if isMulti(typeName) { - err := resolveManyEntities(ctx, typeName, reps, idx) - if err != nil { - ec.Error(ctx, err) - } - } else { - // if there are multiple entities to resolve, parallelize (similar to - // graphql.FieldSet.Dispatch) - var e sync.WaitGroup - e.Add(len(reps)) - for i, rep := range reps { - i, rep := i, rep - go func(i int, rep map[string]interface{}) { - err := resolveEntity(ctx, typeName, rep, idx, i) - if err != nil { - ec.Error(ctx, err) - } - e.Done() - }(i, rep) - } - e.Wait() - } - } - buildRepresentationGroups(representations) - - switch len(repsMap) { - case 0: - return list - case 1: - for typeName, reps := range repsMap { - resolveEntityGroup(typeName, reps.r, reps.i) - } - return list - default: - var g sync.WaitGroup - g.Add(len(repsMap)) - for typeName, reps := range repsMap { - go func(typeName string, reps []map[string]interface{}, idx []int) { - resolveEntityGroup(typeName, reps, idx) - g.Done() - }(typeName, reps.r, reps.i) - } - g.Wait() - return list - } -} - -{{- /* Make sure the required fields are in the given entity representation and return the name of the proper resolver. */ -}} - -{{ range $_, $entity := .Entities }} - {{- if .Resolvers }} - - func entityResolverNameFor{{$entity.Name}}(ctx context.Context, rep map[string]interface{}) (string, error) { - {{- range .Resolvers }} - for { - var ( - m map[string]interface{} - val interface{} - ok bool - ) - _ = val - {{- range $_, $keyField := .KeyFields }} - m = rep - {{- range $i, $field := .Field }} - if {{ if (ne $i $keyField.Field.LastIndex ) -}}val{{- else -}}_{{- end -}}, ok = m["{{.}}"]; !ok { - break - } - {{- if (ne $i $keyField.Field.LastIndex ) }} - if m, ok = val.(map[string]interface{}); !ok { - break - } - {{- end}} - {{- end}} - {{- end }} - return "{{.ResolverName}}", nil - } - {{- end }} - return "", fmt.Errorf("%w for {{$entity.Name}}", ErrTypeNotFound) - } - {{- end }} -{{- end }} - -{{end}} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go b/vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go deleted file mode 100644 index 35616cbea3e..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go +++ /dev/null @@ -1,193 +0,0 @@ -package fieldset - -import ( - "fmt" - "strings" - - "github.com/99designs/gqlgen/codegen" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -// Set represents a FieldSet that is used in federation directives @key and @requires. -// Would be happier to reuse FieldSet parsing from gqlparser, but this suits for now. -// -type Set []Field - -// Field represents a single field in a FieldSet -// -type Field []string - -// New parses a FieldSet string into a TinyFieldSet. -// -func New(raw string, prefix []string) Set { - if !strings.Contains(raw, "{") { - return parseUnnestedKeyFieldSet(raw, prefix) - } - - var ( - ret = Set{} - subPrefix = prefix - ) - before, during, after := extractSubs(raw) - - if before != "" { - befores := New(before, prefix) - if len(befores) > 0 { - subPrefix = befores[len(befores)-1] - ret = append(ret, befores[:len(befores)-1]...) - } - } - if during != "" { - ret = append(ret, New(during, subPrefix)...) - } - if after != "" { - ret = append(ret, New(after, prefix)...) - } - return ret -} - -// FieldDefinition looks up a field in the type. -// -func (f Field) FieldDefinition(schemaType *ast.Definition, schema *ast.Schema) *ast.FieldDefinition { - objType := schemaType - def := objType.Fields.ForName(f[0]) - - for _, part := range f[1:] { - if objType.Kind != ast.Object { - panic(fmt.Sprintf(`invalid sub-field reference "%s" in %v: `, objType.Name, f)) - } - x := def.Type.Name() - objType = schema.Types[x] - if objType == nil { - panic("invalid schema type: " + x) - } - def = objType.Fields.ForName(part) - } - if def == nil { - return nil - } - ret := *def // shallow copy - ret.Name = f.ToGoPrivate() - - return &ret -} - -// TypeReference looks up the type of a field. -// -func (f Field) TypeReference(obj *codegen.Object, objects codegen.Objects) *codegen.Field { - var def *codegen.Field - - for _, part := range f { - def = fieldByName(obj, part) - if def == nil { - panic("unable to find field " + f[0]) - } - obj = objects.ByName(def.TypeReference.Definition.Name) - } - return def -} - -// ToGo converts a (possibly nested) field into a proper public Go name. -// -func (f Field) ToGo() string { - var ret string - - for _, field := range f { - ret += templates.ToGo(field) - } - return ret -} - -// ToGoPrivate converts a (possibly nested) field into a proper private Go name. -// -func (f Field) ToGoPrivate() string { - var ret string - - for i, field := range f { - if i == 0 { - ret += templates.ToGoPrivate(field) - continue - } - ret += templates.ToGo(field) - } - return ret -} - -// Join concatenates the field parts with a string separator between. Useful in templates. -// -func (f Field) Join(str string) string { - return strings.Join(f, str) -} - -// JoinGo concatenates the Go name of field parts with a string separator between. Useful in templates. -// -func (f Field) JoinGo(str string) string { - strs := []string{} - - for _, s := range f { - strs = append(strs, templates.ToGo(s)) - } - return strings.Join(strs, str) -} - -func (f Field) LastIndex() int { - return len(f) - 1 -} - -// local functions - -// parseUnnestedKeyFieldSet // handles simple case where none of the fields are nested. -// -func parseUnnestedKeyFieldSet(raw string, prefix []string) Set { - ret := Set{} - - for _, s := range strings.Fields(raw) { - next := append(prefix[:], s) //nolint:gocritic // slicing out on purpose - ret = append(ret, next) - } - return ret -} - -// extractSubs splits out and trims sub-expressions from before, inside, and after "{}". -// -func extractSubs(str string) (string, string, string) { - start := strings.Index(str, "{") - end := matchingBracketIndex(str, start) - - if start < 0 || end < 0 { - panic("invalid key fieldSet: " + str) - } - return strings.TrimSpace(str[:start]), strings.TrimSpace(str[start+1 : end]), strings.TrimSpace(str[end+1:]) -} - -// matchingBracketIndex returns the index of the closing bracket, assuming an open bracket at start. -// -func matchingBracketIndex(str string, start int) int { - if start < 0 || len(str) <= start+1 { - return -1 - } - var depth int - - for i, c := range str[start+1:] { - switch c { - case '{': - depth++ - case '}': - if depth == 0 { - return start + 1 + i - } - depth-- - } - } - return -1 -} - -func fieldByName(obj *codegen.Object, name string) *codegen.Field { - for _, field := range obj.Fields { - if field.Name == name { - return field - } - } - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/readme.md b/vendor/github.com/99designs/gqlgen/plugin/federation/readme.md deleted file mode 100644 index 4333ed47979..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/federation/readme.md +++ /dev/null @@ -1,39 +0,0 @@ -# Federation plugin - -Add support for graphql federation in your graphql Go server! - -TODO(miguel): add details. - -# Tests -There are several different tests. Some will process the configuration file directly. You can see those in the `federation_test.go`. There are also tests for entity resolvers, which will simulate requests from a federation server like Apollo Federation. - -Running entity resolver tests. -1. Go to `plugin/federation` -2. Run the command `go generate` -3. Run the tests with `go test ./...`. - -# Architecture - -TODO(miguel): add details. - -# Entity resolvers - GetMany entities - -The federation plugin implements `GetMany` semantics in which entity resolvers get the entire list of representations that need to be resolved. This functionality is currently optin tho, and to enable it you need to specify the directive `@entityResolver` in the federated entity you want this feature for. E.g. - -``` -directive @entityResolver(multi: Boolean) on OBJECT - -type MultiHello @key(fields: "name") @entityResolver(multi: true) { - name: String! -} -``` - -That allows the federation plugin to generate `GetMany` resolver function that can take a list of representations to be resolved. - -From that entity type, the resolver function would be - -``` -func (r *entityResolver) FindManyMultiHellosByName(ctx context.Context, reps []*generated.ManyMultiHellosByNameInput) ([]*generated.MultiHello, error) { - /// -} -``` diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go deleted file mode 100644 index 898010d657d..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go +++ /dev/null @@ -1,305 +0,0 @@ -package modelgen - -import ( - "fmt" - "go/types" - "sort" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/99designs/gqlgen/plugin" - "github.com/vektah/gqlparser/v2/ast" -) - -type BuildMutateHook = func(b *ModelBuild) *ModelBuild - -type FieldMutateHook = func(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) - -// defaultFieldMutateHook is the default hook for the Plugin which applies the GoTagFieldHook. -func defaultFieldMutateHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) { - return GoTagFieldHook(td, fd, f) -} - -func defaultBuildMutateHook(b *ModelBuild) *ModelBuild { - return b -} - -type ModelBuild struct { - PackageName string - Interfaces []*Interface - Models []*Object - Enums []*Enum - Scalars []string -} - -type Interface struct { - Description string - Name string - Implements []string -} - -type Object struct { - Description string - Name string - Fields []*Field - Implements []string -} - -type Field struct { - Description string - Name string - Type types.Type - Tag string -} - -type Enum struct { - Description string - Name string - Values []*EnumValue -} - -type EnumValue struct { - Description string - Name string -} - -func New() plugin.Plugin { - return &Plugin{ - MutateHook: defaultBuildMutateHook, - FieldHook: defaultFieldMutateHook, - } -} - -type Plugin struct { - MutateHook BuildMutateHook - FieldHook FieldMutateHook -} - -var _ plugin.ConfigMutator = &Plugin{} - -func (m *Plugin) Name() string { - return "modelgen" -} - -func (m *Plugin) MutateConfig(cfg *config.Config) error { - binder := cfg.NewBinder() - - b := &ModelBuild{ - PackageName: cfg.Model.Package, - } - - for _, schemaType := range cfg.Schema.Types { - if cfg.Models.UserDefined(schemaType.Name) { - continue - } - switch schemaType.Kind { - case ast.Interface, ast.Union: - it := &Interface{ - Description: schemaType.Description, - Name: schemaType.Name, - Implements: schemaType.Interfaces, - } - - b.Interfaces = append(b.Interfaces, it) - case ast.Object, ast.InputObject: - if schemaType == cfg.Schema.Query || schemaType == cfg.Schema.Mutation || schemaType == cfg.Schema.Subscription { - continue - } - it := &Object{ - Description: schemaType.Description, - Name: schemaType.Name, - } - - // If Interface A implements interface B, and Interface C also implements interface B - // then both A and C have methods of B. - // The reason for checking unique is to prevent the same method B from being generated twice. - uniqueMap := map[string]bool{} - for _, implementor := range cfg.Schema.GetImplements(schemaType) { - if !uniqueMap[implementor.Name] { - it.Implements = append(it.Implements, implementor.Name) - uniqueMap[implementor.Name] = true - } - // for interface implements - for _, iface := range implementor.Interfaces { - if !uniqueMap[iface] { - it.Implements = append(it.Implements, iface) - uniqueMap[iface] = true - } - } - } - - for _, field := range schemaType.Fields { - var typ types.Type - fieldDef := cfg.Schema.Types[field.Type.Name()] - - if cfg.Models.UserDefined(field.Type.Name()) { - var err error - typ, err = binder.FindTypeFromName(cfg.Models[field.Type.Name()].Model[0]) - if err != nil { - return err - } - } else { - switch fieldDef.Kind { - case ast.Scalar: - // no user defined model, referencing a default scalar - typ = types.NewNamed( - types.NewTypeName(0, cfg.Model.Pkg(), "string", nil), - nil, - nil, - ) - - case ast.Interface, ast.Union: - // no user defined model, referencing a generated interface type - typ = types.NewNamed( - types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil), - types.NewInterfaceType([]*types.Func{}, []types.Type{}), - nil, - ) - - case ast.Enum: - // no user defined model, must reference a generated enum - typ = types.NewNamed( - types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil), - nil, - nil, - ) - - case ast.Object, ast.InputObject: - // no user defined model, must reference a generated struct - typ = types.NewNamed( - types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil), - types.NewStruct(nil, nil), - nil, - ) - - default: - panic(fmt.Errorf("unknown ast type %s", fieldDef.Kind)) - } - } - - name := field.Name - if nameOveride := cfg.Models[schemaType.Name].Fields[field.Name].FieldName; nameOveride != "" { - name = nameOveride - } - - typ = binder.CopyModifiersFromAst(field.Type, typ) - - if isStruct(typ) && (fieldDef.Kind == ast.Object || fieldDef.Kind == ast.InputObject) { - typ = types.NewPointer(typ) - } - - f := &Field{ - Name: name, - Type: typ, - Description: field.Description, - Tag: `json:"` + field.Name + `"`, - } - - if m.FieldHook != nil { - mf, err := m.FieldHook(schemaType, field, f) - if err != nil { - return fmt.Errorf("generror: field %v.%v: %w", it.Name, field.Name, err) - } - f = mf - } - - it.Fields = append(it.Fields, f) - } - - b.Models = append(b.Models, it) - case ast.Enum: - it := &Enum{ - Name: schemaType.Name, - Description: schemaType.Description, - } - - for _, v := range schemaType.EnumValues { - it.Values = append(it.Values, &EnumValue{ - Name: v.Name, - Description: v.Description, - }) - } - - b.Enums = append(b.Enums, it) - case ast.Scalar: - b.Scalars = append(b.Scalars, schemaType.Name) - } - } - sort.Slice(b.Enums, func(i, j int) bool { return b.Enums[i].Name < b.Enums[j].Name }) - sort.Slice(b.Models, func(i, j int) bool { return b.Models[i].Name < b.Models[j].Name }) - sort.Slice(b.Interfaces, func(i, j int) bool { return b.Interfaces[i].Name < b.Interfaces[j].Name }) - - for _, it := range b.Enums { - cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name)) - } - for _, it := range b.Models { - cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name)) - } - for _, it := range b.Interfaces { - cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name)) - } - for _, it := range b.Scalars { - cfg.Models.Add(it, "github.com/99designs/gqlgen/graphql.String") - } - - if len(b.Models) == 0 && len(b.Enums) == 0 && len(b.Interfaces) == 0 && len(b.Scalars) == 0 { - return nil - } - - if m.MutateHook != nil { - b = m.MutateHook(b) - } - - err := templates.Render(templates.Options{ - PackageName: cfg.Model.Package, - Filename: cfg.Model.Filename, - Data: b, - GeneratedHeader: true, - Packages: cfg.Packages, - }) - if err != nil { - return err - } - - // We may have generated code in a package we already loaded, so we reload all packages - // to allow packages to be compared correctly - cfg.ReloadAllPackages() - - return nil -} - -// GoTagFieldHook applies the goTag directive to the generated Field f. When applying the Tag to the field, the field -// name is used when no value argument is present. -func GoTagFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) { - args := make([]string, 0) - for _, goTag := range fd.Directives.ForNames("goTag") { - key := "" - value := fd.Name - - if arg := goTag.Arguments.ForName("key"); arg != nil { - if k, err := arg.Value.Value(nil); err == nil { - key = k.(string) - } - } - - if arg := goTag.Arguments.ForName("value"); arg != nil { - if v, err := arg.Value.Value(nil); err == nil { - value = v.(string) - } - } - - args = append(args, key+":\""+value+"\"") - } - - if len(args) > 0 { - f.Tag = f.Tag + " " + strings.Join(args, " ") - } - - return f, nil -} - -func isStruct(t types.Type) bool { - _, is := t.Underlying().(*types.Struct) - return is -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl deleted file mode 100644 index 8f425e58eb4..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl +++ /dev/null @@ -1,88 +0,0 @@ -{{ reserveImport "context" }} -{{ reserveImport "fmt" }} -{{ reserveImport "io" }} -{{ reserveImport "strconv" }} -{{ reserveImport "time" }} -{{ reserveImport "sync" }} -{{ reserveImport "errors" }} -{{ reserveImport "bytes" }} - -{{ reserveImport "github.com/vektah/gqlparser/v2" }} -{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} - -{{- range $model := .Interfaces }} - {{ with .Description }} {{.|prefixLines "// "}} {{ end }} - type {{.Name|go }} interface { - {{- range $impl := .Implements }} - {{ $impl|go }} - {{- end }} - Is{{.Name|go }}() - } -{{- end }} - -{{ range $model := .Models }} - {{with .Description }} {{.|prefixLines "// "}} {{end}} - type {{ .Name|go }} struct { - {{- range $field := .Fields }} - {{- with .Description }} - {{.|prefixLines "// "}} - {{- end}} - {{ $field.Name|go }} {{$field.Type | ref}} `{{$field.Tag}}` - {{- end }} - } - - {{- range $iface := .Implements }} - func ({{ $model.Name|go }}) Is{{ $iface|go }}() {} - {{- end }} -{{- end}} - -{{ range $enum := .Enums }} - {{ with .Description }} {{.|prefixLines "// "}} {{end}} - type {{.Name|go }} string - const ( - {{- range $value := .Values}} - {{- with .Description}} - {{.|prefixLines "// "}} - {{- end}} - {{ $enum.Name|go }}{{ .Name|go }} {{$enum.Name|go }} = {{.Name|quote}} - {{- end }} - ) - - var All{{.Name|go }} = []{{ .Name|go }}{ - {{- range $value := .Values}} - {{$enum.Name|go }}{{ .Name|go }}, - {{- end }} - } - - func (e {{.Name|go }}) IsValid() bool { - switch e { - case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.Name|go }}{{ $element.Name|go }}{{end}}: - return true - } - return false - } - - func (e {{.Name|go }}) String() string { - return string(e) - } - - func (e *{{.Name|go }}) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = {{ .Name|go }}(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid {{ .Name }}", str) - } - return nil - } - - func (e {{.Name|go }}) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) - } - -{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/plugin/plugin.go b/vendor/github.com/99designs/gqlgen/plugin/plugin.go deleted file mode 100644 index 7de36bd8cd5..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/plugin.go +++ /dev/null @@ -1,31 +0,0 @@ -// plugin package interfaces are EXPERIMENTAL. - -package plugin - -import ( - "github.com/99designs/gqlgen/codegen" - "github.com/99designs/gqlgen/codegen/config" - "github.com/vektah/gqlparser/v2/ast" -) - -type Plugin interface { - Name() string -} - -type ConfigMutator interface { - MutateConfig(cfg *config.Config) error -} - -type CodeGenerator interface { - GenerateCode(cfg *codegen.Data) error -} - -// EarlySourceInjector is used to inject things that are required for user schema files to compile. -type EarlySourceInjector interface { - InjectSourceEarly() *ast.Source -} - -// LateSourceInjector is used to inject more sources, after we have loaded the users schema. -type LateSourceInjector interface { - InjectSourceLate(schema *ast.Schema) *ast.Source -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go deleted file mode 100644 index 538aa714b1e..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go +++ /dev/null @@ -1,212 +0,0 @@ -package resolvergen - -import ( - "errors" - "io/fs" - "os" - "path/filepath" - "strings" - - "github.com/99designs/gqlgen/codegen" - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/99designs/gqlgen/internal/rewrite" - "github.com/99designs/gqlgen/plugin" -) - -func New() plugin.Plugin { - return &Plugin{} -} - -type Plugin struct{} - -var _ plugin.CodeGenerator = &Plugin{} - -func (m *Plugin) Name() string { - return "resolvergen" -} - -func (m *Plugin) GenerateCode(data *codegen.Data) error { - if !data.Config.Resolver.IsDefined() { - return nil - } - - switch data.Config.Resolver.Layout { - case config.LayoutSingleFile: - return m.generateSingleFile(data) - case config.LayoutFollowSchema: - return m.generatePerSchema(data) - } - - return nil -} - -func (m *Plugin) generateSingleFile(data *codegen.Data) error { - file := File{} - - if _, err := os.Stat(data.Config.Resolver.Filename); err == nil { - // file already exists and we dont support updating resolvers with layout = single so just return - return nil - } - - for _, o := range data.Objects { - if o.HasResolvers() { - file.Objects = append(file.Objects, o) - } - for _, f := range o.Fields { - if !f.IsResolver { - continue - } - - resolver := Resolver{o, f, `panic("not implemented")`} - file.Resolvers = append(file.Resolvers, &resolver) - } - } - - resolverBuild := &ResolverBuild{ - File: &file, - PackageName: data.Config.Resolver.Package, - ResolverType: data.Config.Resolver.Type, - HasRoot: true, - } - - return templates.Render(templates.Options{ - PackageName: data.Config.Resolver.Package, - FileNotice: `// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.`, - Filename: data.Config.Resolver.Filename, - Data: resolverBuild, - Packages: data.Config.Packages, - }) -} - -func (m *Plugin) generatePerSchema(data *codegen.Data) error { - rewriter, err := rewrite.New(data.Config.Resolver.Dir()) - if err != nil { - return err - } - - files := map[string]*File{} - - objects := make(codegen.Objects, len(data.Objects)+len(data.Inputs)) - copy(objects, data.Objects) - copy(objects[len(data.Objects):], data.Inputs) - - for _, o := range objects { - if o.HasResolvers() { - fn := gqlToResolverName(data.Config.Resolver.Dir(), o.Position.Src.Name, data.Config.Resolver.FilenameTemplate) - if files[fn] == nil { - files[fn] = &File{} - } - - rewriter.MarkStructCopied(templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)) - rewriter.GetMethodBody(data.Config.Resolver.Type, strings.Title(o.Name)) - files[fn].Objects = append(files[fn].Objects, o) - } - for _, f := range o.Fields { - if !f.IsResolver { - continue - } - - structName := templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type) - implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName)) - if implementation == "" { - implementation = `panic(fmt.Errorf("not implemented"))` - } - - resolver := Resolver{o, f, implementation} - fn := gqlToResolverName(data.Config.Resolver.Dir(), f.Position.Src.Name, data.Config.Resolver.FilenameTemplate) - if files[fn] == nil { - files[fn] = &File{} - } - - files[fn].Resolvers = append(files[fn].Resolvers, &resolver) - } - } - - for filename, file := range files { - file.imports = rewriter.ExistingImports(filename) - file.RemainingSource = rewriter.RemainingSource(filename) - } - - for filename, file := range files { - resolverBuild := &ResolverBuild{ - File: file, - PackageName: data.Config.Resolver.Package, - ResolverType: data.Config.Resolver.Type, - } - - err := templates.Render(templates.Options{ - PackageName: data.Config.Resolver.Package, - FileNotice: ` - // This file will be automatically regenerated based on the schema, any resolver implementations - // will be copied through when generating and any unknown code will be moved to the end.`, - Filename: filename, - Data: resolverBuild, - Packages: data.Config.Packages, - }) - if err != nil { - return err - } - } - - if _, err := os.Stat(data.Config.Resolver.Filename); errors.Is(err, fs.ErrNotExist) { - err := templates.Render(templates.Options{ - PackageName: data.Config.Resolver.Package, - FileNotice: ` - // This file will not be regenerated automatically. - // - // It serves as dependency injection for your app, add any dependencies you require here.`, - Template: `type {{.}} struct {}`, - Filename: data.Config.Resolver.Filename, - Data: data.Config.Resolver.Type, - Packages: data.Config.Packages, - }) - if err != nil { - return err - } - } - return nil -} - -type ResolverBuild struct { - *File - HasRoot bool - PackageName string - ResolverType string -} - -type File struct { - // These are separated because the type definition of the resolver object may live in a different file from the - // resolver method implementations, for example when extending a type in a different graphql schema file - Objects []*codegen.Object - Resolvers []*Resolver - imports []rewrite.Import - RemainingSource string -} - -func (f *File) Imports() string { - for _, imp := range f.imports { - if imp.Alias == "" { - _, _ = templates.CurrentImports.Reserve(imp.ImportPath) - } else { - _, _ = templates.CurrentImports.Reserve(imp.ImportPath, imp.Alias) - } - } - return "" -} - -type Resolver struct { - Object *codegen.Object - Field *codegen.Field - Implementation string -} - -func gqlToResolverName(base string, gqlname, filenameTmpl string) string { - gqlname = filepath.Base(gqlname) - ext := filepath.Ext(gqlname) - if filenameTmpl == "" { - filenameTmpl = "{name}.resolvers.go" - } - filename := strings.ReplaceAll(filenameTmpl, "{name}", strings.TrimSuffix(gqlname, ext)) - return filepath.Join(base, filename) -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl deleted file mode 100644 index 16c684d6283..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl +++ /dev/null @@ -1,45 +0,0 @@ -{{ reserveImport "context" }} -{{ reserveImport "fmt" }} -{{ reserveImport "io" }} -{{ reserveImport "strconv" }} -{{ reserveImport "time" }} -{{ reserveImport "sync" }} -{{ reserveImport "errors" }} -{{ reserveImport "bytes" }} - -{{ reserveImport "github.com/vektah/gqlparser/v2" }} -{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} - -{{ .Imports }} - -{{ if .HasRoot }} - type {{.ResolverType}} struct {} -{{ end }} - -{{ range $resolver := .Resolvers -}} - func (r *{{lcFirst $resolver.Object.Name}}{{ucFirst $.ResolverType}}) {{$resolver.Field.GoFieldName}}{{ $resolver.Field.ShortResolverDeclaration }} { - {{ $resolver.Implementation }} - } - -{{ end }} - -{{ range $object := .Objects -}} - // {{ucFirst $object.Name}} returns {{ $object.ResolverInterface | ref }} implementation. - func (r *{{$.ResolverType}}) {{ucFirst $object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} } -{{ end }} - -{{ range $object := .Objects -}} - type {{lcFirst $object.Name}}{{ucFirst $.ResolverType}} struct { *{{$.ResolverType}} } -{{ end }} - -{{ if (ne .RemainingSource "") }} - // !!! WARNING !!! - // The code below was going to be deleted when updating resolvers. It has been copied here so you have - // one last chance to move it out of harms way if you want. There are two reasons this happens: - // - When renaming or deleting a resolver the old code will be put in here. You can safely delete - // it when you're done. - // - You have helper methods in this file. Move them out to keep these resolver files clean. - {{ .RemainingSource }} -{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go deleted file mode 100644 index d9b35fe4178..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go +++ /dev/null @@ -1,52 +0,0 @@ -package servergen - -import ( - "errors" - "io/fs" - "log" - "os" - - "github.com/99designs/gqlgen/codegen" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/99designs/gqlgen/plugin" -) - -func New(filename string) plugin.Plugin { - return &Plugin{filename} -} - -type Plugin struct { - filename string -} - -var _ plugin.CodeGenerator = &Plugin{} - -func (m *Plugin) Name() string { - return "servergen" -} - -func (m *Plugin) GenerateCode(data *codegen.Data) error { - serverBuild := &ServerBuild{ - ExecPackageName: data.Config.Exec.ImportPath(), - ResolverPackageName: data.Config.Resolver.ImportPath(), - } - - if _, err := os.Stat(m.filename); errors.Is(err, fs.ErrNotExist) { - return templates.Render(templates.Options{ - PackageName: "main", - Filename: m.filename, - Data: serverBuild, - Packages: data.Config.Packages, - }) - } - - log.Printf("Skipped server: %s already exists\n", m.filename) - return nil -} - -type ServerBuild struct { - codegen.Data - - ExecPackageName string - ResolverPackageName string -} diff --git a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl deleted file mode 100644 index a3ae2a877a8..00000000000 --- a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl +++ /dev/null @@ -1,23 +0,0 @@ -{{ reserveImport "context" }} -{{ reserveImport "log" }} -{{ reserveImport "net/http" }} -{{ reserveImport "os" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql/playground" }} -{{ reserveImport "github.com/99designs/gqlgen/graphql/handler" }} - -const defaultPort = "8080" - -func main() { - port := os.Getenv("PORT") - if port == "" { - port = defaultPort - } - - srv := handler.NewDefaultServer({{ lookupImport .ExecPackageName }}.NewExecutableSchema({{ lookupImport .ExecPackageName}}.Config{Resolvers: &{{ lookupImport .ResolverPackageName}}.Resolver{}})) - - http.Handle("/", playground.Handler("GraphQL playground", "/query")) - http.Handle("/query", srv) - - log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) - log.Fatal(http.ListenAndServe(":" + port, nil)) -} diff --git a/vendor/github.com/99designs/gqlgen/tools.go b/vendor/github.com/99designs/gqlgen/tools.go deleted file mode 100644 index ef46208c161..00000000000 --- a/vendor/github.com/99designs/gqlgen/tools.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build tools -// +build tools - -package main - -import ( - _ "github.com/matryer/moq" -) diff --git a/vendor/github.com/WithoutPants/sortorder/LICENSE b/vendor/github.com/WithoutPants/sortorder/LICENSE deleted file mode 100644 index 5c695fb590f..00000000000 --- a/vendor/github.com/WithoutPants/sortorder/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -The MIT License (MIT) -Copyright (c) 2015 Frits van Bommel -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/WithoutPants/sortorder/casefolded/README.md b/vendor/github.com/WithoutPants/sortorder/casefolded/README.md deleted file mode 100644 index fd2d84f2e94..00000000000 --- a/vendor/github.com/WithoutPants/sortorder/casefolded/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# casefolded [![PkgGoDev](https://pkg.go.dev/badge/github.com/fvbommel/sortorder/casefolded)](https://pkg.go.dev/github.com/fvbommel/sortorder/casefolded) - - import "github.com/fvbommel/sortorder/casefolded" - -Case-folded sort orders and comparison functions. - -These sort characters as the lowest unicode value that is equivalent to that character, ignoring case. - -Not all Unicode special cases are supported. - -This is a separate sub-package because this needs to pull in the Unicode tables in the standard library, -which can add significantly to the size of binaries. diff --git a/vendor/github.com/WithoutPants/sortorder/casefolded/natsort.go b/vendor/github.com/WithoutPants/sortorder/casefolded/natsort.go deleted file mode 100644 index cf7cd92227a..00000000000 --- a/vendor/github.com/WithoutPants/sortorder/casefolded/natsort.go +++ /dev/null @@ -1,190 +0,0 @@ -package casefolded - -import ( - "unicode" - "unicode/utf8" -) - -// Natural implements sort.Interface to sort strings in natural order. This -// means that e.g. "abc2" < "abc12". -// -// This is the simple case-folded version, -// which means that letters are considered equal if strings.SimpleFold says they are. -// For example, "abc2" < "ABC12" < "abc100" and 'k' == '\u212a' (the Kelvin symbol). -// -// Non-digit sequences and numbers are compared separately. -// The former are compared rune-by-rune using the lowest equivalent runes, -// while digits are compared numerically -// (except that the number of leading zeros is used as a tie-breaker, so e.g. "2" < "02") -// -// Limitations: -// - only ASCII digits (0-9) are considered. -// - comparisons are done on a rune-by-rune basis, -// so some special case equivalences like 'ß' == 'SS" are not supported. -// - Special cases like Turkish 'i' == 'İ' (and not regular dotless 'I') -// are not supported either. -type Natural []string - -func (n Natural) Len() int { return len(n) } -func (n Natural) Swap(i, j int) { n[i], n[j] = n[j], n[i] } -func (n Natural) Less(i, j int) bool { return NaturalLess(n[i], n[j]) } - -func isDigit(b rune) bool { return '0' <= b && b <= '9' } - -// caseFold returns the lowest-numbered rune equivalent to the parameter. -func caseFold(r rune) rune { - // Iterate until SimpleFold returns a lower value. - // This will be the lowest-numbered equivalent rune. - var prev rune = -1 - for r > prev { - prev, r = r, unicode.SimpleFold(r) - } - return r -} - -// NaturalLess compares two strings using natural ordering. This means that e.g. -// "abc2" < "abc12". -// -// This is the simple case-folded version, -// which means that letters are considered equal if strings.SimpleFold says they are. -// For example, "abc2" < "ABC12" < "abc100" and 'k' == '\u212a' (the Kelvin symbol). -// -// Non-digit sequences and numbers are compared separately. -// The former are compared rune-by-rune using the lowest equivalent runes, -// while digits are compared numerically -// (except that the number of leading zeros is used as a tie-breaker, so e.g. "2" < "02") -// -// Limitations: -// - only ASCII digits (0-9) are considered. -// - comparisons are done on a rune-by-rune basis, -// so some special case equivalences like 'ß' == 'SS" are not supported. -// - Special cases like Turkish 'i' == 'İ' (and not regular dotless 'I') -// are not supported either. -func NaturalLess(str1, str2 string) bool { - // ASCII fast path. - idx1, idx2 := 0, 0 - for idx1 < len(str1) && idx2 < len(str2) { - c1, c2 := rune(str1[idx1]), rune(str2[idx2]) - - // Bail out to full Unicode support? - if c1|c2 >= utf8.RuneSelf { - goto hasUnicode - } - - dig1, dig2 := isDigit(c1), isDigit(c2) - switch { - case !dig1 || !dig2: - // For ASCII it suffices to normalize letters to upper-case, - // because upper-cased ASCII compares lexicographically. - // Note: this does not account for regional special cases - // like Turkish dotted capital 'İ'. - - // Canonicalize to upper-case. - c1 = unicode.ToUpper(c1) - c2 = unicode.ToUpper(c2) - // Identical upper-cased ASCII runes are equal. - if c1 == c2 { - idx1++ - idx2++ - continue - } - return c1 < c2 - default: // Digits - // Eat zeros. - for ; idx1 < len(str1) && str1[idx1] == '0'; idx1++ { - } - for ; idx2 < len(str2) && str2[idx2] == '0'; idx2++ { - } - // Eat all digits. - nonZero1, nonZero2 := idx1, idx2 - for ; idx1 < len(str1) && isDigit(rune(str1[idx1])); idx1++ { - } - for ; idx2 < len(str2) && isDigit(rune(str2[idx2])); idx2++ { - } - // If lengths of numbers with non-zero prefix differ, the shorter - // one is less. - if len1, len2 := idx1-nonZero1, idx2-nonZero2; len1 != len2 { - return len1 < len2 - } - // If they're equally long, string comparison is correct. - if nr1, nr2 := str1[nonZero1:idx1], str2[nonZero2:idx2]; nr1 != nr2 { - return nr1 < nr2 - } - // Otherwise, the one with less zeros is less. - // Because everything up to the number is equal, comparing the index - // after the zeros is sufficient. - if nonZero1 != nonZero2 { - return nonZero1 < nonZero2 - } - } - // They're identical so far, so continue comparing. - } - // So far they are identical. At least one is ended. If the other continues, - // it sorts last. - return len(str1) < len(str2) - -hasUnicode: - for idx1 < len(str1) && idx2 < len(str2) { - c1, delta1 := utf8.DecodeRuneInString(str1[idx1:]) - c2, delta2 := utf8.DecodeRuneInString(str2[idx2:]) - - dig1, dig2 := isDigit(c1), isDigit(c2) - switch { - case !dig1 || !dig2: - idx1 += delta1 - idx2 += delta2 - // Fast path: identical runes are equal. - if c1 == c2 { - continue - } - // ASCII fast path: ASCII characters compare by their upper-case equivalent (if any) - // because 'A' < 'a', so upper-case them. - if c1 <= unicode.MaxASCII && c2 <= unicode.MaxASCII { - c1 = unicode.ToUpper(c1) - c2 = unicode.ToUpper(c2) - if c1 != c2 { - return c1 < c2 - } - continue - } - // Compare lowest equivalent characters. - c1 = caseFold(c1) - c2 = caseFold(c2) - if c1 == c2 { - continue - } - return c1 < c2 - default: // Digits - // Eat zeros. - for ; idx1 < len(str1) && str1[idx1] == '0'; idx1++ { - } - for ; idx2 < len(str2) && str2[idx2] == '0'; idx2++ { - } - // Eat all digits. - nonZero1, nonZero2 := idx1, idx2 - for ; idx1 < len(str1) && isDigit(rune(str1[idx1])); idx1++ { - } - for ; idx2 < len(str2) && isDigit(rune(str2[idx2])); idx2++ { - } - // If lengths of numbers with non-zero prefix differ, the shorter - // one is less. - if len1, len2 := idx1-nonZero1, idx2-nonZero2; len1 != len2 { - return len1 < len2 - } - // If they're equally long, string comparison is correct. - if nr1, nr2 := str1[nonZero1:idx1], str2[nonZero2:idx2]; nr1 != nr2 { - return nr1 < nr2 - } - // Otherwise, the one with less zeros is less. - // Because everything up to the number is equal, comparing the index - // after the zeros is sufficient. - if nonZero1 != nonZero2 { - return nonZero1 < nonZero2 - } - } - // They're identical so far, so continue comparing. - } - // So far they are identical. At least one is ended. If the other continues, - // it sorts last. - return len(str1[idx1:]) < len(str2[idx2:]) -} diff --git a/vendor/github.com/Yamashou/gqlgenc/.gitignore b/vendor/github.com/Yamashou/gqlgenc/.gitignore deleted file mode 100644 index 35a663521a2..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.gqlgenc.yml -/models_gen.go -/**/.graphqlconfig -/schema.graphql -/client.go -/query/ -/.idea/ - -coverage.out diff --git a/vendor/github.com/Yamashou/gqlgenc/.golangci.yml b/vendor/github.com/Yamashou/gqlgenc/.golangci.yml deleted file mode 100644 index 1dd68463b98..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/.golangci.yml +++ /dev/null @@ -1,93 +0,0 @@ -# See https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml -run: -linters-settings: - govet: - enable-all: true - disable: - - shadow - unused: - check-exported: true - unparam: - check-exported: true - varcheck: - exported-fields: true - structcheck: - exported-fields: true - nakedret: - max-func-lines: 1 - -linters: - enable-all: true - disable: - - testpackage - - nestif - - godot - - wsl - - lll - - dupl - - funlen - - gochecknoinits - - gochecknoglobals - - godox - - maligned - - gocognit - - gocyclo - - interfacer - - gomnd - - goerr113 - - exhaustivestruct - - errorlint # TODO able this lint - - forbidigo - - cyclop - - govet - - errname - - varnamelen - - nilnil - - structcheck - fast: false - -issues: - exclude-rules: - # Test - - path: _test\.go - text: "Using the variable on range scope `tt` in function literal" - linters: - - scopelint - - path: _test\.go - linters: - - unused - - structcheck - - path: introspection/type.go - linters: - - structcheck # These types fits IntrospectionQuery - - path: config/config.go - text: "`Query` is unused" # used in main.go - linters: - - structcheck - - path: graphqljson/graphql.go - text: "`Extensions` is unused" # used in line 48 - linters: - - structcheck - - path: introspection/query.go - text: "`Introspection` is unused" # used in config/config.go - linters: - - varcheck - - path: config/config.go - text: "`ClientV2` is unused" # used in config/config.go - linters: - - structcheck - - path: graphqljson/graphql.go - text: "append to slice `frontier` with non-zero initialized length" # used in config/config.go - linters: - - makezero - - path: clientv2/client_test.go - text: "should not use basic type string as key in context.WithValue" - linters: - - golint - - path: clientv2/client_test.go - text: "should not use built-in type string as key for value; define your own type to avoid collisions" - linters: - - staticcheck - - path: clientv2/client_test.go - linters: - - revive diff --git a/vendor/github.com/Yamashou/gqlgenc/LICENSE b/vendor/github.com/Yamashou/gqlgenc/LICENSE deleted file mode 100644 index e16053d8f45..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Yamashou - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Yamashou/gqlgenc/Makefile b/vendor/github.com/Yamashou/gqlgenc/Makefile deleted file mode 100644 index c0ff3adcc00..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -MAKEFLAGS=--no-builtin-rules --no-builtin-variables --always-make - -fmt: - gofumports -local github.com/Yamashou/gqlgenc -w . - -lint: - golangci-lint cache clean && golangci-lint run - -test: - go test -v ./... diff --git a/vendor/github.com/Yamashou/gqlgenc/README.md b/vendor/github.com/Yamashou/gqlgenc/README.md deleted file mode 100644 index 664ce89ec42..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# gqlgenc - -## What is gqlgenc ? - -This is Go library for building GraphQL client with [gqlgen](https://github.com/99designs/gqlgen) - -## Motivation - -Now, if you build GraphQL api client for Go, have choice: - - - [github.com/shurcooL/graphql](https://github.com/shurcooL/graphql) - - [github.com/machinebox/graphql](https://github.com/machinebox/graphql) - -These libraries are very simple and easy to handle. -However, as I work with [gqlgen](https://github.com/99designs/gqlgen) and [graphql-code-generator](https://graphql-code-generator.com/) every day, I find out the beauty of automatic generation. -So I want to automatically generate types. - -## Installation - -```shell script -go get -u github.com/Yamashou/gqlgenc -``` - -## How to use - -### Client Codes Only - -gqlgenc base is gqlgen with [plugins](https://gqlgen.com/reference/plugins/). So the setting is yaml in each format. -gqlgenc can be configured using a `.gqlgenc.yml` file - -Load a schema from a remote server: - -```yaml -model: - package: generated - filename: ./models_gen.go # https://github.com/99designs/gqlgen/tree/master/plugin/modelgen -client: - package: generated - filename: ./client.go # Where should any generated client go? -models: - Int: - model: github.com/99designs/gqlgen/graphql.Int64 - Date: - model: github.com/99designs/gqlgen/graphql.Time -endpoint: - url: https://api.annict.com/graphql # Where do you want to send your request? - headers: # If you need header for getting introspection query, set it - Authorization: "Bearer ${ANNICT_KEY}" # support environment variables -query: - - "./query/*.graphql" # Where are all the query files located? -``` - -Load a schema from a local file: - -```yaml -model: - package: generated - filename: ./models_gen.go # https://github.com/99designs/gqlgen/tree/master/plugin/modelgen -client: - package: generated - filename: ./client.go # Where should any generated client go? -models: - Int: - model: github.com/99designs/gqlgen/graphql.Int64 - Date: - model: github.com/99designs/gqlgen/graphql.Time -schema: - - "schema/**/*.graphql" # Where are all the schema files located? -query: - - "./query/*.graphql" # Where are all the query files located? -``` - -Execute the following command on same directory for .gqlgenc.yml - -```shell script -gqlgenc -``` - -### With gqlgen - -Do this when creating a server and client for Go. -You create your own entrypoint for gqlgen. -This use case is very useful for testing your server. - - -```go -package main - -import ( - "fmt" - "os" - - "github.com/Yamashou/gqlgenc/clientgen" - - "github.com/99designs/gqlgen/api" - "github.com/99designs/gqlgen/codegen/config" -) - -func main() { - cfg, err := config.LoadConfigFromDefaultLocations() - if err != nil { - fmt.Fprintln(os.Stderr, "failed to load config", err.Error()) - os.Exit(2) - } - queries := []string{"client.query", "fragemt.query"} - clientPackage := config.PackageConfig{ - Filename: "./client.go", - Package: "gen", - } - - clientPlugin := clientgen.New(queries, clientPackage) - err = api.Generate(cfg, - api.AddPlugin(clientPlugin), - ) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(3) - } -} -``` - -## Documents - -- [How to configure gqlgen using gqlgen.yml](https://gqlgen.com/config/) -- [How to write plugins for gqlgen](https://gqlgen.com/reference/plugins/) - - -## Comments - -### Japanese Comments -These codes have Japanese comments. Replace with English. - -### Subscription - -This client does not support subscription. If you need a subscription, please create an issue or pull request. - -### Pre-conditions - -[clientgen](https://github.com/Yamashou/gqlgenc/tree/master/clientgen) is created based on [modelgen](https://github.com/99designs/gqlgen/tree/master/plugin/modelgen). So if you don't have a modelgen, it may be a mysterious move. diff --git a/vendor/github.com/Yamashou/gqlgenc/TESTING.md b/vendor/github.com/Yamashou/gqlgenc/TESTING.md deleted file mode 100644 index c474dfd0048..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/TESTING.md +++ /dev/null @@ -1,19 +0,0 @@ -# Run tests - -To run tests simply run - -```shell script -go test ./... -coverprofile=coverage.out -``` - -To deep dive into test coverage, run the following command to see the result in your terminal - -```shell script -go tool cover -func=coverage.out -``` - -or the following to see the result in your browser - -```shell script -go tool cover -html=coverage.out -``` diff --git a/vendor/github.com/Yamashou/gqlgenc/client/client.go b/vendor/github.com/Yamashou/gqlgenc/client/client.go deleted file mode 100644 index 4f049b34f83..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/client/client.go +++ /dev/null @@ -1,182 +0,0 @@ -package client - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/Yamashou/gqlgenc/graphqljson" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -// HTTPRequestOption represents the options applicable to the http client -type HTTPRequestOption func(req *http.Request) - -// Client is the http client wrapper -type Client struct { - Client *http.Client - BaseURL string - HTTPRequestOptions []HTTPRequestOption -} - -// Request represents an outgoing GraphQL request -type Request struct { - Query string `json:"query"` - Variables map[string]interface{} `json:"variables,omitempty"` - OperationName string `json:"operationName,omitempty"` -} - -// NewClient creates a new http client wrapper -func NewClient(client *http.Client, baseURL string, options ...HTTPRequestOption) *Client { - return &Client{ - Client: client, - BaseURL: baseURL, - HTTPRequestOptions: options, - } -} - -func (c *Client) newRequest(ctx context.Context, operationName, query string, vars map[string]interface{}, httpRequestOptions []HTTPRequestOption) (*http.Request, error) { - r := &Request{ - Query: query, - Variables: vars, - OperationName: operationName, - } - - requestBody, err := json.Marshal(r) - if err != nil { - return nil, fmt.Errorf("encode: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.BaseURL, bytes.NewBuffer(requestBody)) - if err != nil { - return nil, fmt.Errorf("create request struct failed: %w", err) - } - - for _, httpRequestOption := range c.HTTPRequestOptions { - httpRequestOption(req) - } - for _, httpRequestOption := range httpRequestOptions { - httpRequestOption(req) - } - - return req, nil -} - -// GqlErrorList is the struct of a standard graphql error response -type GqlErrorList struct { - Errors gqlerror.List `json:"errors"` -} - -func (e *GqlErrorList) Error() string { - return e.Errors.Error() -} - -// HTTPError is the error when a GqlErrorList cannot be parsed -type HTTPError struct { - Code int `json:"code"` - Message string `json:"message"` -} - -// ErrorResponse represent an handled error -type ErrorResponse struct { - // populated when http status code is not OK - NetworkError *HTTPError `json:"networkErrors"` - // populated when http status code is OK but the server returned at least one graphql error - GqlErrors *gqlerror.List `json:"graphqlErrors"` -} - -// HasErrors returns true when at least one error is declared -func (er *ErrorResponse) HasErrors() bool { - return er.NetworkError != nil || er.GqlErrors != nil -} - -func (er *ErrorResponse) Error() string { - content, err := json.Marshal(er) - if err != nil { - return err.Error() - } - - return string(content) -} - -// Post sends a http POST request to the graphql endpoint with the given query then unpacks -// the response into the given object. -func (c *Client) Post(ctx context.Context, operationName, query string, respData interface{}, vars map[string]interface{}, httpRequestOptions ...HTTPRequestOption) error { - req, err := c.newRequest(ctx, operationName, query, vars, httpRequestOptions) - if err != nil { - return fmt.Errorf("don't create request: %w", err) - } - req.Header.Set("Content-Type", "application/json; charset=utf-8") - req.Header.Set("Accept", "application/json; charset=utf-8") - - resp, err := c.Client.Do(req) - if err != nil { - return fmt.Errorf("request failed: %w", err) - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("failed to read response body: %w", err) - } - - return parseResponse(body, resp.StatusCode, respData) -} - -func parseResponse(body []byte, httpCode int, result interface{}) error { - errResponse := &ErrorResponse{} - isKOCode := httpCode < 200 || 299 < httpCode - if isKOCode { - errResponse.NetworkError = &HTTPError{ - Code: httpCode, - Message: fmt.Sprintf("Response body %s", string(body)), - } - } - - // some servers return a graphql error with a non OK http code, try anyway to parse the body - if err := unmarshal(body, result); err != nil { - if gqlErr, ok := err.(*GqlErrorList); ok { - errResponse.GqlErrors = &gqlErr.Errors - } else if !isKOCode { // if is KO code there is already the http error, this error should not be returned - return err - } - } - - if errResponse.HasErrors() { - return errResponse - } - - return nil -} - -// response is a GraphQL layer response from a handler. -type response struct { - Data json.RawMessage `json:"data"` - Errors json.RawMessage `json:"errors"` -} - -func unmarshal(data []byte, res interface{}) error { - resp := response{} - if err := json.Unmarshal(data, &resp); err != nil { - return fmt.Errorf("failed to decode data %s: %w", string(data), err) - } - - if resp.Errors != nil && len(resp.Errors) > 0 { - // try to parse standard graphql error - errors := &GqlErrorList{} - if e := json.Unmarshal(data, errors); e != nil { - return fmt.Errorf("faild to parse graphql errors. Response content %s - %w ", string(data), e) - } - - return errors - } - - if err := graphqljson.UnmarshalData(resp.Data, res); err != nil { - return fmt.Errorf("failed to decode data into response %s: %w", string(data), err) - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/client.go b/vendor/github.com/Yamashou/gqlgenc/clientgen/client.go deleted file mode 100644 index bffeb5168d6..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/client.go +++ /dev/null @@ -1,85 +0,0 @@ -package clientgen - -import ( - "fmt" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/plugin" - gqlgencConfig "github.com/Yamashou/gqlgenc/config" -) - -var _ plugin.ConfigMutator = &Plugin{} - -type Plugin struct { - queryFilePaths []string - Client config.PackageConfig - GenerateConfig *gqlgencConfig.GenerateConfig -} - -func New(queryFilePaths []string, client config.PackageConfig, generateConfig *gqlgencConfig.GenerateConfig) *Plugin { - return &Plugin{ - queryFilePaths: queryFilePaths, - Client: client, - GenerateConfig: generateConfig, - } -} - -func (p *Plugin) Name() string { - return "clientgen" -} - -func (p *Plugin) MutateConfig(cfg *config.Config) error { - querySources, err := LoadQuerySources(p.queryFilePaths) - if err != nil { - return fmt.Errorf("load query sources failed: %w", err) - } - - // 1. 全体のqueryDocumentを1度にparse - // 1. Parse document from source of query - queryDocument, err := ParseQueryDocuments(cfg.Schema, querySources, p.GenerateConfig) - if err != nil { - return fmt.Errorf(": %w", err) - } - - // 2. OperationごとのqueryDocumentを作成 - // 2. Separate documents for each operation - queryDocuments, err := QueryDocumentsByOperations(cfg.Schema, queryDocument.Operations) - if err != nil { - return fmt.Errorf("parse query document failed: %w", err) - } - - // 3. テンプレートと情報ソースを元にコード生成 - // 3. Generate code from template and document source - sourceGenerator := NewSourceGenerator(cfg, p.Client) - source := NewSource(cfg.Schema, queryDocument, sourceGenerator, p.GenerateConfig) - query, err := source.Query() - if err != nil { - return fmt.Errorf("generating query object: %w", err) - } - - mutation, err := source.Mutation() - if err != nil { - return fmt.Errorf("generating mutation object: %w", err) - } - - fragments, err := source.Fragments() - if err != nil { - return fmt.Errorf("generating fragment failed: %w", err) - } - - operationResponses, err := source.OperationResponses() - if err != nil { - return fmt.Errorf("generating operation response failed: %w", err) - } - - operations, err := source.Operations(queryDocuments) - if err != nil { - return fmt.Errorf("generating operation failed: %w", err) - } - - if err := RenderTemplate(cfg, query, mutation, fragments, operations, operationResponses, p.GenerateConfig, p.Client); err != nil { - return fmt.Errorf("template failed: %w", err) - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/query.go b/vendor/github.com/Yamashou/gqlgenc/clientgen/query.go deleted file mode 100644 index 2b651938bfa..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/query.go +++ /dev/null @@ -1,118 +0,0 @@ -package clientgen - -import ( - "fmt" - - "github.com/Yamashou/gqlgenc/config" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/parser" - "github.com/vektah/gqlparser/v2/validator" -) - -type merger struct { - document ast.QueryDocument - unamedIndex int - unamedPattern string -} - -func newMerger(generateConfig *config.GenerateConfig) *merger { - unamedPattern := "Unamed" - if generateConfig != nil && generateConfig.UnamedPattern != "" { - unamedPattern = generateConfig.UnamedPattern - } - - return &merger{unamedPattern: unamedPattern} -} - -func ParseQueryDocuments(schema *ast.Schema, querySources []*ast.Source, generateConfig *config.GenerateConfig) (*ast.QueryDocument, error) { - merger := newMerger(generateConfig) - for _, querySource := range querySources { - query, gqlerr := parser.ParseQuery(querySource) - if gqlerr != nil { - return nil, fmt.Errorf(": %w", gqlerr) - } - - merger.mergeQueryDocument(query) - } - - if errs := validator.Validate(schema, &merger.document); errs != nil { - return nil, fmt.Errorf(": %w", errs) - } - - return &merger.document, nil -} - -func (m *merger) mergeQueryDocument(other *ast.QueryDocument) { - for _, operation := range other.Operations { - if operation.Name == "" { - // We increment first so unamed queries will start at 1 - m.unamedIndex++ - operation.Name = fmt.Sprintf("%s%d", m.unamedPattern, m.unamedIndex) - } - } - - m.document.Operations = append(m.document.Operations, other.Operations...) - m.document.Fragments = append(m.document.Fragments, other.Fragments...) -} - -func QueryDocumentsByOperations(schema *ast.Schema, operations ast.OperationList) ([]*ast.QueryDocument, error) { - queryDocuments := make([]*ast.QueryDocument, 0, len(operations)) - for _, operation := range operations { - fragments := fragmentsInOperationDefinition(operation) - - queryDocument := &ast.QueryDocument{ - Operations: ast.OperationList{operation}, - Fragments: fragments, - Position: nil, - } - - if errs := validator.Validate(schema, queryDocument); errs != nil { - return nil, fmt.Errorf(": %w", errs) - } - - queryDocuments = append(queryDocuments, queryDocument) - } - - return queryDocuments, nil -} - -func fragmentsInOperationDefinition(operation *ast.OperationDefinition) ast.FragmentDefinitionList { - fragments := fragmentsInOperationWalker(operation.SelectionSet) - uniqueFragments := fragmentsUnique(fragments) - - return uniqueFragments -} - -func fragmentsUnique(fragments ast.FragmentDefinitionList) ast.FragmentDefinitionList { - uniqueMap := make(map[string]*ast.FragmentDefinition) - for _, fragment := range fragments { - uniqueMap[fragment.Name] = fragment - } - - uniqueFragments := make(ast.FragmentDefinitionList, 0, len(uniqueMap)) - for _, fragment := range uniqueMap { - uniqueFragments = append(uniqueFragments, fragment) - } - - return uniqueFragments -} - -func fragmentsInOperationWalker(selectionSet ast.SelectionSet) ast.FragmentDefinitionList { - var fragments ast.FragmentDefinitionList - for _, selection := range selectionSet { - var selectionSet ast.SelectionSet - switch selection := selection.(type) { - case *ast.Field: - selectionSet = selection.SelectionSet - case *ast.InlineFragment: - selectionSet = selection.SelectionSet - case *ast.FragmentSpread: - fragments = append(fragments, selection.Definition) - selectionSet = selection.Definition.SelectionSet - } - - fragments = append(fragments, fragmentsInOperationWalker(selectionSet)...) - } - - return fragments -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/query_source.go b/vendor/github.com/Yamashou/gqlgenc/clientgen/query_source.go deleted file mode 100644 index bc42490956d..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/query_source.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright (c) 2020 gqlgen authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package clientgen - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/vektah/gqlparser/v2/ast" -) - -var path2regex = strings.NewReplacer( - `.`, `\.`, - `*`, `.+`, - `\`, `[\\/]`, - `/`, `[\\/]`, -) - -// LoadQuerySourceなどは、gqlgenがLoadConfigでSchemaを読み込む時の実装をコピーして一部修正している -// **/test/*.graphqlなどに対応している -func LoadQuerySources(queryFileNames []string) ([]*ast.Source, error) { - var noGlobQueryFileNames config.StringList - - var err error - preGlobbing := queryFileNames - for _, f := range preGlobbing { - var matches []string - - // for ** we want to override default globbing patterns and walk all - // subdirectories to match schema files. - if strings.Contains(f, "**") { - pathParts := strings.SplitN(f, "**", 2) - rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`) - // turn the rest of the glob into a regex, anchored only at the end because ** allows - // for any number of dirs in between and walk will let us match against the full path name - globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`) - - if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) { - matches = append(matches, path) - } - - return nil - }); err != nil { - return nil, fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) - } - } else { - matches, err = filepath.Glob(f) - if err != nil { - return nil, fmt.Errorf("failed to glob schema filename %v: %w", f, err) - } - } - - for _, m := range matches { - if noGlobQueryFileNames.Has(m) { - continue - } - - noGlobQueryFileNames = append(noGlobQueryFileNames, m) - } - } - - querySources := make([]*ast.Source, 0, len(noGlobQueryFileNames)) - for _, filename := range noGlobQueryFileNames { - filename = filepath.ToSlash(filename) - var err error - var schemaRaw []byte - schemaRaw, err = ioutil.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to open schema: %w", err) - } - - querySources = append(querySources, &ast.Source{Name: filename, Input: string(schemaRaw)}) - } - - return querySources, nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/source.go b/vendor/github.com/Yamashou/gqlgenc/clientgen/source.go deleted file mode 100644 index 1d059f3af6a..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/source.go +++ /dev/null @@ -1,238 +0,0 @@ -package clientgen - -import ( - "bytes" - "fmt" - "go/types" - - "github.com/99designs/gqlgen/codegen/templates" - "github.com/Yamashou/gqlgenc/config" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/formatter" -) - -type Source struct { - schema *ast.Schema - queryDocument *ast.QueryDocument - sourceGenerator *SourceGenerator - generateConfig *config.GenerateConfig -} - -func NewSource(schema *ast.Schema, queryDocument *ast.QueryDocument, sourceGenerator *SourceGenerator, generateConfig *config.GenerateConfig) *Source { - return &Source{ - schema: schema, - queryDocument: queryDocument, - sourceGenerator: sourceGenerator, - generateConfig: generateConfig, - } -} - -type Fragment struct { - Name string - Type types.Type -} - -func (s *Source) Fragments() ([]*Fragment, error) { - fragments := make([]*Fragment, 0, len(s.queryDocument.Fragments)) - for _, fragment := range s.queryDocument.Fragments { - responseFields := s.sourceGenerator.NewResponseFields(fragment.SelectionSet) - if s.sourceGenerator.cfg.Models.Exists(fragment.Name) { - return nil, fmt.Errorf("%s is duplicated", fragment.Name) - } - - fragment := &Fragment{ - Name: fragment.Name, - Type: responseFields.StructType(), - } - - fragments = append(fragments, fragment) - } - - for _, fragment := range fragments { - name := fragment.Name - s.sourceGenerator.cfg.Models.Add( - name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(name)), - ) - } - - return fragments, nil -} - -type Operation struct { - Name string - ResponseStructName string - Operation string - Args []*Argument - VariableDefinitions ast.VariableDefinitionList -} - -func NewOperation(operation *ast.OperationDefinition, queryDocument *ast.QueryDocument, args []*Argument, generateConfig *config.GenerateConfig) *Operation { - return &Operation{ - Name: operation.Name, - ResponseStructName: getResponseStructName(operation, generateConfig), - Operation: queryString(queryDocument), - Args: args, - VariableDefinitions: operation.VariableDefinitions, - } -} - -func (s *Source) Operations(queryDocuments []*ast.QueryDocument) ([]*Operation, error) { - operations := make([]*Operation, 0, len(s.queryDocument.Operations)) - - operationNames := make(map[string]struct{}) - - queryDocumentsMap := queryDocumentMapByOperationName(queryDocuments) - operationArgsMap := s.operationArgsMapByOperationName() - for _, operation := range s.queryDocument.Operations { - queryDocument := queryDocumentsMap[operation.Name] - - _, exist := operationNames[templates.ToGo(operation.Name)] - if exist { - return nil, fmt.Errorf("duplicate operation: %s", operation.Name) - } - operationNames[templates.ToGo(operation.Name)] = struct{}{} - - args := operationArgsMap[operation.Name] - operations = append(operations, NewOperation( - operation, - queryDocument, - args, - s.generateConfig, - )) - } - - return operations, nil -} - -func (s *Source) operationArgsMapByOperationName() map[string][]*Argument { - operationArgsMap := make(map[string][]*Argument) - for _, operation := range s.queryDocument.Operations { - operationArgsMap[operation.Name] = s.sourceGenerator.OperationArguments(operation.VariableDefinitions) - } - - return operationArgsMap -} - -func queryDocumentMapByOperationName(queryDocuments []*ast.QueryDocument) map[string]*ast.QueryDocument { - queryDocumentMap := make(map[string]*ast.QueryDocument) - for _, queryDocument := range queryDocuments { - operation := queryDocument.Operations[0] - queryDocumentMap[operation.Name] = queryDocument - } - - return queryDocumentMap -} - -func queryString(queryDocument *ast.QueryDocument) string { - var buf bytes.Buffer - astFormatter := formatter.NewFormatter(&buf) - astFormatter.FormatQueryDocument(queryDocument) - - return buf.String() -} - -type OperationResponse struct { - Name string - Type types.Type -} - -func (s *Source) OperationResponses() ([]*OperationResponse, error) { - operationResponse := make([]*OperationResponse, 0, len(s.queryDocument.Operations)) - for _, operation := range s.queryDocument.Operations { - responseFields := s.sourceGenerator.NewResponseFields(operation.SelectionSet) - name := getResponseStructName(operation, s.generateConfig) - if s.sourceGenerator.cfg.Models.Exists(name) { - return nil, fmt.Errorf("%s is duplicated", name) - } - operationResponse = append(operationResponse, &OperationResponse{ - Name: name, - Type: responseFields.StructType(), - }) - } - - for _, operationResponse := range operationResponse { - name := operationResponse.Name - s.sourceGenerator.cfg.Models.Add( - name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(name)), - ) - } - - return operationResponse, nil -} - -type Query struct { - Name string - Type types.Type -} - -func (s *Source) Query() (*Query, error) { - fields, err := s.sourceGenerator.NewResponseFieldsByDefinition(s.schema.Query) - if err != nil { - return nil, fmt.Errorf("generate failed for query struct type : %w", err) - } - - s.sourceGenerator.cfg.Models.Add( - s.schema.Query.Name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(s.schema.Query.Name)), - ) - - return &Query{ - Name: s.schema.Query.Name, - Type: fields.StructType(), - }, nil -} - -type Mutation struct { - Name string - Type types.Type -} - -func (s *Source) Mutation() (*Mutation, error) { - if s.schema.Mutation == nil { - return nil, nil - } - - fields, err := s.sourceGenerator.NewResponseFieldsByDefinition(s.schema.Mutation) - if err != nil { - return nil, fmt.Errorf("generate failed for mutation struct type : %w", err) - } - - s.sourceGenerator.cfg.Models.Add( - s.schema.Mutation.Name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(s.schema.Mutation.Name)), - ) - - return &Mutation{ - Name: s.schema.Mutation.Name, - Type: fields.StructType(), - }, nil -} - -func getResponseStructName(operation *ast.OperationDefinition, generateConfig *config.GenerateConfig) string { - name := operation.Name - if generateConfig != nil { - if generateConfig.Prefix != nil { - if operation.Operation == ast.Mutation { - name = fmt.Sprintf("%s%s", generateConfig.Prefix.Mutation, name) - } - - if operation.Operation == ast.Query { - name = fmt.Sprintf("%s%s", generateConfig.Prefix.Query, name) - } - } - - if generateConfig.Suffix != nil { - if operation.Operation == ast.Mutation { - name = fmt.Sprintf("%s%s", name, generateConfig.Suffix.Mutation) - } - - if operation.Operation == ast.Query { - name = fmt.Sprintf("%s%s", name, generateConfig.Suffix.Query) - } - } - } - - return name -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/source_generator.go b/vendor/github.com/Yamashou/gqlgenc/clientgen/source_generator.go deleted file mode 100644 index a43308a3e86..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/source_generator.go +++ /dev/null @@ -1,231 +0,0 @@ -package clientgen - -import ( - "fmt" - "go/types" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -type Argument struct { - Variable string - Type types.Type -} - -type ResponseField struct { - Name string - IsFragmentSpread bool - IsInlineFragment bool - Type types.Type - Tags []string - ResponseFields ResponseFieldList -} - -type ResponseFieldList []*ResponseField - -func (rs ResponseFieldList) StructType() *types.Struct { - vars := make([]*types.Var, 0) - structTags := make([]string, 0) - for _, filed := range rs { - // クエリーのフィールドの子階層がFragmentの場合、このフィールドにそのFragmentの型を追加する - if filed.IsFragmentSpread { - typ, ok := filed.ResponseFields.StructType().Underlying().(*types.Struct) - if !ok { - continue - } - for j := 0; j < typ.NumFields(); j++ { - vars = append(vars, typ.Field(j)) - structTags = append(structTags, typ.Tag(j)) - } - } else { - vars = append(vars, types.NewVar(0, nil, templates.ToGo(filed.Name), filed.Type)) - structTags = append(structTags, strings.Join(filed.Tags, " ")) - } - } - - return types.NewStruct(vars, structTags) -} - -func (rs ResponseFieldList) IsFragment() bool { - if len(rs) != 1 { - return false - } - - return rs[0].IsInlineFragment || rs[0].IsFragmentSpread -} - -func (rs ResponseFieldList) IsBasicType() bool { - return len(rs) == 0 -} - -func (rs ResponseFieldList) IsStructType() bool { - return len(rs) > 0 && !rs.IsFragment() -} - -type SourceGenerator struct { - cfg *config.Config - binder *config.Binder - client config.PackageConfig -} - -func NewSourceGenerator(cfg *config.Config, client config.PackageConfig) *SourceGenerator { - return &SourceGenerator{ - cfg: cfg, - binder: cfg.NewBinder(), - client: client, - } -} - -func (r *SourceGenerator) NewResponseFields(selectionSet ast.SelectionSet) ResponseFieldList { - responseFields := make(ResponseFieldList, 0, len(selectionSet)) - for _, selection := range selectionSet { - responseFields = append(responseFields, r.NewResponseField(selection)) - } - - return responseFields -} - -func (r *SourceGenerator) NewResponseFieldsByDefinition(definition *ast.Definition) (ResponseFieldList, error) { - fields := make(ResponseFieldList, 0, len(definition.Fields)) - for _, field := range definition.Fields { - if field.Type.Name() == "__Schema" || field.Type.Name() == "__Type" { - continue - } - - var typ types.Type - if field.Type.Name() == "Query" || field.Type.Name() == "Mutation" { - var baseType types.Type - baseType, err := r.binder.FindType(r.client.Pkg().Path(), field.Type.Name()) - if err != nil { - if !strings.Contains(err.Error(), "unable to find type") { - return nil, fmt.Errorf("not found type: %w", err) - } - - // create new type - baseType = types.NewPointer(types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(field.Type.Name()), nil), - nil, - nil, - )) - } - - // for recursive struct field in go - typ = types.NewPointer(baseType) - } else { - baseType, err := r.binder.FindTypeFromName(r.cfg.Models[field.Type.Name()].Model[0]) - if err != nil { - return nil, fmt.Errorf("not found type: %w", err) - } - - typ = r.binder.CopyModifiersFromAst(field.Type, baseType) - } - - tags := []string{ - fmt.Sprintf(`json:"%s"`, field.Name), - fmt.Sprintf(`graphql:"%s"`, field.Name), - } - - fields = append(fields, &ResponseField{ - Name: field.Name, - Type: typ, - Tags: tags, - }) - } - - return fields, nil -} - -func (r *SourceGenerator) NewResponseField(selection ast.Selection) *ResponseField { - switch selection := selection.(type) { - case *ast.Field: - fieldsResponseFields := r.NewResponseFields(selection.SelectionSet) - - var baseType types.Type - switch { - case fieldsResponseFields.IsBasicType(): - baseType = r.Type(selection.Definition.Type.Name()) - case fieldsResponseFields.IsFragment(): - // 子フィールドがFragmentの場合はこのFragmentがフィールドの型になる - // if a child field is fragment, this field type became fragment. - baseType = fieldsResponseFields[0].Type - case fieldsResponseFields.IsStructType(): - baseType = fieldsResponseFields.StructType() - default: - // ここにきたらバグ - // here is bug - panic("not match type") - } - - // GraphQLの定義がオプショナルのはtypeのポインタ型が返り、配列の定義場合はポインタのスライスの型になって返ってきます - // return pointer type then optional type or slice pointer then slice type of definition in GraphQL. - typ := r.binder.CopyModifiersFromAst(selection.Definition.Type, baseType) - - tags := []string{ - fmt.Sprintf(`json:"%s"`, selection.Alias), - fmt.Sprintf(`graphql:"%s"`, selection.Alias), - } - - return &ResponseField{ - Name: selection.Alias, - Type: typ, - Tags: tags, - ResponseFields: fieldsResponseFields, - } - - case *ast.FragmentSpread: - // この構造体はテンプレート側で使われることはなく、ast.FieldでFragment判定するために使用する - fieldsResponseFields := r.NewResponseFields(selection.Definition.SelectionSet) - typ := types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(selection.Name), nil), - fieldsResponseFields.StructType(), - nil, - ) - - return &ResponseField{ - Name: selection.Name, - Type: typ, - IsFragmentSpread: true, - ResponseFields: fieldsResponseFields, - } - - case *ast.InlineFragment: - // InlineFragmentは子要素をそのままstructとしてもつので、ここで、構造体の型を作成します - fieldsResponseFields := r.NewResponseFields(selection.SelectionSet) - - return &ResponseField{ - Name: selection.TypeCondition, - Type: fieldsResponseFields.StructType(), - IsInlineFragment: true, - Tags: []string{fmt.Sprintf(`graphql:"... on %s"`, selection.TypeCondition)}, - ResponseFields: fieldsResponseFields, - } - } - - panic("unexpected selection type") -} - -func (r *SourceGenerator) OperationArguments(variableDefinitions ast.VariableDefinitionList) []*Argument { - argumentTypes := make([]*Argument, 0, len(variableDefinitions)) - for _, v := range variableDefinitions { - argumentTypes = append(argumentTypes, &Argument{ - Variable: v.Variable, - Type: r.binder.CopyModifiersFromAst(v.Type, r.Type(v.Type.Name())), - }) - } - - return argumentTypes -} - -// Typeの引数に渡すtypeNameは解析した結果からselectionなどから求めた型の名前を渡さなければいけない -func (r *SourceGenerator) Type(typeName string) types.Type { - goType, err := r.binder.FindTypeFromName(r.cfg.Models[typeName].Model[0]) - if err != nil { - // 実装として正しいtypeNameを渡していれば必ず見つかるはずなのでpanic - panic(fmt.Sprintf("%+v", err)) - } - - return goType -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/template.go b/vendor/github.com/Yamashou/gqlgenc/clientgen/template.go deleted file mode 100644 index 8a8017e79e8..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/template.go +++ /dev/null @@ -1,31 +0,0 @@ -package clientgen - -import ( - "fmt" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - gqlgencConfig "github.com/Yamashou/gqlgenc/config" -) - -func RenderTemplate(cfg *config.Config, query *Query, mutation *Mutation, fragments []*Fragment, operations []*Operation, operationResponses []*OperationResponse, generateCfg *gqlgencConfig.GenerateConfig, client config.PackageConfig) error { - if err := templates.Render(templates.Options{ - PackageName: client.Package, - Filename: client.Filename, - Data: map[string]interface{}{ - "Query": query, - "Mutation": mutation, - "Fragment": fragments, - "Operation": operations, - "OperationResponse": operationResponses, - "GenerateClient": generateCfg.ShouldGenerateClient(), - "ClientInterfaceName": generateCfg.ClientInterfaceName, - }, - Packages: cfg.Packages, - PackageDoc: "// Code generated by github.com/Yamashou/gqlgenc, DO NOT EDIT.\n", - }); err != nil { - return fmt.Errorf("%s generating failed: %w", client.Filename, err) - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgen/template.gotpl b/vendor/github.com/Yamashou/gqlgenc/clientgen/template.gotpl deleted file mode 100644 index 30b2df26b04..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgen/template.gotpl +++ /dev/null @@ -1,75 +0,0 @@ -{{- if .GenerateClient }} - {{ reserveImport "bytes" }} - {{ reserveImport "context" }} - {{ reserveImport "encoding/json" }} - {{ reserveImport "fmt" }} - {{ reserveImport "io" }} - {{ reserveImport "io/ioutil" }} - {{ reserveImport "net/http" }} - {{ reserveImport "net/url" }} - {{ reserveImport "path" }} - {{ reserveImport "time" }} - - - {{ reserveImport "github.com/Yamashou/gqlgenc/graphqljson" }} - {{ reserveImport "github.com/Yamashou/gqlgenc/client" }} - - {{- if .ClientInterfaceName }} - type {{ .ClientInterfaceName }} interface { - {{- range $model := .Operation }} - {{ $model.Name | go }} (ctx context.Context{{- range $arg := .Args }}, {{ $arg.Variable | goPrivate }} {{ $arg.Type | ref }} {{- end }}, httpRequestOptions ...client.HTTPRequestOption) (*{{ $model.ResponseStructName | go }}, error) - {{- end }} - } - {{- end }} - - type Client struct { - Client *client.Client - } - - {{- if .ClientInterfaceName }} - func NewClient(cli *http.Client, baseURL string, options ...client.HTTPRequestOption) {{ .ClientInterfaceName }} { - return &Client{Client: client.NewClient(cli, baseURL, options...)} - } - {{- else }} - func NewClient(cli *http.Client, baseURL string, options ...client.HTTPRequestOption) *Client { - return &Client{Client: client.NewClient(cli, baseURL, options...)} - } - {{- end }} -{{- end }} - -type {{ .Query.Name | go }} {{ .Query.Type | ref }} - -{{- if .Mutation }} - type {{ .Mutation.Name | go }} {{ .Mutation.Type | ref }} -{{- end }} - -{{- range $name, $element := .Fragment }} - type {{ .Name | go }} {{ .Type | ref }} -{{- end }} - -{{- range $name, $element := .OperationResponse }} - type {{ .Name | go }} {{ .Type | ref }} -{{- end }} - - - -{{- range $model := .Operation}} - const {{ $model.Name|go }}Document = `{{ $model.Operation }}` - - {{- if $.GenerateClient }} - func (c *Client) {{ $model.Name | go }} (ctx context.Context{{- range $arg := .Args }}, {{ $arg.Variable | goPrivate }} {{ $arg.Type | ref }} {{- end }}, httpRequestOptions ...client.HTTPRequestOption) (*{{ $model.ResponseStructName | go }}, error) { - vars := map[string]interface{}{ - {{- range $args := .VariableDefinitions}} - "{{ $args.Variable }}": {{ $args.Variable | goPrivate }}, - {{- end }} - } - - var res {{ $model.ResponseStructName | go }} - if err := c.Client.Post(ctx, "{{ $model.Name }}", {{ $model.Name|go }}Document, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil - } - {{- end}} -{{- end}} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/client.go b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/client.go deleted file mode 100644 index 8d7ebfa1d13..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/client.go +++ /dev/null @@ -1,85 +0,0 @@ -package clientgenv2 - -import ( - "fmt" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/plugin" - gqlgencConfig "github.com/Yamashou/gqlgenc/config" -) - -var _ plugin.ConfigMutator = &Plugin{} - -type Plugin struct { - queryFilePaths []string - Client config.PackageConfig - GenerateConfig *gqlgencConfig.GenerateConfig -} - -func New(queryFilePaths []string, client config.PackageConfig, generateConfig *gqlgencConfig.GenerateConfig) *Plugin { - return &Plugin{ - queryFilePaths: queryFilePaths, - Client: client, - GenerateConfig: generateConfig, - } -} - -func (p *Plugin) Name() string { - return "clientgen" -} - -func (p *Plugin) MutateConfig(cfg *config.Config) error { - querySources, err := LoadQuerySources(p.queryFilePaths) - if err != nil { - return fmt.Errorf("load query sources failed: %w", err) - } - - // 1. 全体のqueryDocumentを1度にparse - // 1. Parse document from source of query - queryDocument, err := ParseQueryDocuments(cfg.Schema, querySources) - if err != nil { - return fmt.Errorf(": %w", err) - } - - // 2. OperationごとのqueryDocumentを作成 - // 2. Separate documents for each operation - queryDocuments, err := QueryDocumentsByOperations(cfg.Schema, queryDocument.Operations) - if err != nil { - return fmt.Errorf("parse query document failed: %w", err) - } - - // 3. テンプレートと情報ソースを元にコード生成 - // 3. Generate code from template and document source - sourceGenerator := NewSourceGenerator(cfg, p.Client) - source := NewSource(cfg.Schema, queryDocument, sourceGenerator, p.GenerateConfig) - query, err := source.Query() - if err != nil { - return fmt.Errorf("generating query object: %w", err) - } - - mutation, err := source.Mutation() - if err != nil { - return fmt.Errorf("generating mutation object: %w", err) - } - - fragments, err := source.Fragments() - if err != nil { - return fmt.Errorf("generating fragment failed: %w", err) - } - - operationResponses, err := source.OperationResponses() - if err != nil { - return fmt.Errorf("generating operation response failed: %w", err) - } - - operations, err := source.Operations(queryDocuments) - if err != nil { - return fmt.Errorf("generating operation failed: %w", err) - } - - if err := RenderTemplate(cfg, query, mutation, fragments, operations, operationResponses, source.ResponseSubTypes(), p.GenerateConfig, p.Client); err != nil { - return fmt.Errorf("template failed: %w", err) - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/query.go b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/query.go deleted file mode 100644 index 3d13562cd4b..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/query.go +++ /dev/null @@ -1,94 +0,0 @@ -package clientgenv2 - -import ( - "fmt" - - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/parser" - "github.com/vektah/gqlparser/v2/validator" -) - -func ParseQueryDocuments(schema *ast.Schema, querySources []*ast.Source) (*ast.QueryDocument, error) { - var queryDocument ast.QueryDocument - for _, querySource := range querySources { - query, gqlerr := parser.ParseQuery(querySource) - if gqlerr != nil { - return nil, fmt.Errorf(": %w", gqlerr) - } - - mergeQueryDocument(&queryDocument, query) - } - - if errs := validator.Validate(schema, &queryDocument); errs != nil { - return nil, fmt.Errorf(": %w", errs) - } - - return &queryDocument, nil -} - -func mergeQueryDocument(q, other *ast.QueryDocument) { - q.Operations = append(q.Operations, other.Operations...) - q.Fragments = append(q.Fragments, other.Fragments...) -} - -func QueryDocumentsByOperations(schema *ast.Schema, operations ast.OperationList) ([]*ast.QueryDocument, error) { - queryDocuments := make([]*ast.QueryDocument, 0, len(operations)) - for _, operation := range operations { - fragments := fragmentsInOperationDefinition(operation) - - queryDocument := &ast.QueryDocument{ - Operations: ast.OperationList{operation}, - Fragments: fragments, - Position: nil, - } - - if errs := validator.Validate(schema, queryDocument); errs != nil { - return nil, fmt.Errorf(": %w", errs) - } - - queryDocuments = append(queryDocuments, queryDocument) - } - - return queryDocuments, nil -} - -func fragmentsInOperationDefinition(operation *ast.OperationDefinition) ast.FragmentDefinitionList { - fragments := fragmentsInOperationWalker(operation.SelectionSet) - uniqueFragments := fragmentsUnique(fragments) - - return uniqueFragments -} - -func fragmentsUnique(fragments ast.FragmentDefinitionList) ast.FragmentDefinitionList { - uniqueMap := make(map[string]*ast.FragmentDefinition) - for _, fragment := range fragments { - uniqueMap[fragment.Name] = fragment - } - - uniqueFragments := make(ast.FragmentDefinitionList, 0, len(uniqueMap)) - for _, fragment := range uniqueMap { - uniqueFragments = append(uniqueFragments, fragment) - } - - return uniqueFragments -} - -func fragmentsInOperationWalker(selectionSet ast.SelectionSet) ast.FragmentDefinitionList { - var fragments ast.FragmentDefinitionList - for _, selection := range selectionSet { - var selectionSet ast.SelectionSet - switch selection := selection.(type) { - case *ast.Field: - selectionSet = selection.SelectionSet - case *ast.InlineFragment: - selectionSet = selection.SelectionSet - case *ast.FragmentSpread: - fragments = append(fragments, selection.Definition) - selectionSet = selection.Definition.SelectionSet - } - - fragments = append(fragments, fragmentsInOperationWalker(selectionSet)...) - } - - return fragments -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/query_source.go b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/query_source.go deleted file mode 100644 index d7eeb0ce247..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/query_source.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright (c) 2020 gqlgen authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package clientgenv2 - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/vektah/gqlparser/v2/ast" -) - -var path2regex = strings.NewReplacer( - `.`, `\.`, - `*`, `.+`, - `\`, `[\\/]`, - `/`, `[\\/]`, -) - -// LoadQuerySourceなどは、gqlgenがLoadConfigでSchemaを読み込む時の実装をコピーして一部修正している -// **/test/*.graphqlなどに対応している -func LoadQuerySources(queryFileNames []string) ([]*ast.Source, error) { - var noGlobQueryFileNames config.StringList - - var err error - preGlobbing := queryFileNames - for _, f := range preGlobbing { - var matches []string - - // for ** we want to override default globbing patterns and walk all - // subdirectories to match schema files. - if strings.Contains(f, "**") { - pathParts := strings.SplitN(f, "**", 2) - rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`) - // turn the rest of the glob into a regex, anchored only at the end because ** allows - // for any number of dirs in between and walk will let us match against the full path name - globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`) - - if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) { - matches = append(matches, path) - } - - return nil - }); err != nil { - return nil, fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) - } - } else { - matches, err = filepath.Glob(f) - if err != nil { - return nil, fmt.Errorf("failed to glob schema filename %v: %w", f, err) - } - } - - for _, m := range matches { - if noGlobQueryFileNames.Has(m) { - continue - } - - noGlobQueryFileNames = append(noGlobQueryFileNames, m) - } - } - - querySources := make([]*ast.Source, 0, len(noGlobQueryFileNames)) - for _, filename := range noGlobQueryFileNames { - filename = filepath.ToSlash(filename) - var err error - var schemaRaw []byte - schemaRaw, err = ioutil.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to open schema: %w", err) - } - - querySources = append(querySources, &ast.Source{Name: filename, Input: string(schemaRaw)}) - } - - return querySources, nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/source.go b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/source.go deleted file mode 100644 index 4d3fa78ab06..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/source.go +++ /dev/null @@ -1,255 +0,0 @@ -package clientgenv2 - -import ( - "bytes" - "fmt" - "go/types" - - "github.com/99designs/gqlgen/codegen/templates" - "github.com/Yamashou/gqlgenc/config" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/formatter" -) - -type Source struct { - schema *ast.Schema - queryDocument *ast.QueryDocument - sourceGenerator *SourceGenerator - generateConfig *config.GenerateConfig -} - -func NewSource(schema *ast.Schema, queryDocument *ast.QueryDocument, sourceGenerator *SourceGenerator, generateConfig *config.GenerateConfig) *Source { - return &Source{ - schema: schema, - queryDocument: queryDocument, - sourceGenerator: sourceGenerator, - generateConfig: generateConfig, - } -} - -type Fragment struct { - Name string - Type types.Type -} - -func (s *Source) Fragments() ([]*Fragment, error) { - fragments := make([]*Fragment, 0, len(s.queryDocument.Fragments)) - for _, fragment := range s.queryDocument.Fragments { - responseFields := s.sourceGenerator.NewResponseFields(fragment.SelectionSet, fragment.Name) - if s.sourceGenerator.cfg.Models.Exists(fragment.Name) { - return nil, fmt.Errorf("%s is duplicated", fragment.Name) - } - - fragment := &Fragment{ - Name: fragment.Name, - Type: responseFields.StructType(), - } - - fragments = append(fragments, fragment) - } - - for _, fragment := range fragments { - name := fragment.Name - s.sourceGenerator.cfg.Models.Add( - name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(name)), - ) - } - - return fragments, nil -} - -type Operation struct { - Name string - ResponseStructName string - Operation string - Args []*Argument - VariableDefinitions ast.VariableDefinitionList -} - -func NewOperation(operation *ast.OperationDefinition, queryDocument *ast.QueryDocument, args []*Argument, generateConfig *config.GenerateConfig) *Operation { - return &Operation{ - Name: operation.Name, - ResponseStructName: getResponseStructName(operation, generateConfig), - Operation: queryString(queryDocument), - Args: args, - VariableDefinitions: operation.VariableDefinitions, - } -} - -func ValidateOperationList(os ast.OperationList) error { - if err := IsUniqueName(os); err != nil { - return fmt.Errorf("is not unique operation name: %w", err) - } - - return nil -} - -func IsUniqueName(os ast.OperationList) error { - operationNames := make(map[string]struct{}) - for _, operation := range os { - _, exist := operationNames[templates.ToGo(operation.Name)] - if exist { - return fmt.Errorf("duplicate operation: %s", operation.Name) - } - } - - return nil -} - -func (s *Source) Operations(queryDocuments []*ast.QueryDocument) ([]*Operation, error) { - operations := make([]*Operation, 0, len(s.queryDocument.Operations)) - - queryDocumentsMap := queryDocumentMapByOperationName(queryDocuments) - operationArgsMap := s.operationArgsMapByOperationName() - - if err := ValidateOperationList(s.queryDocument.Operations); err != nil { - return nil, fmt.Errorf("validation error: %w", err) - } - - for _, operation := range s.queryDocument.Operations { - queryDocument := queryDocumentsMap[operation.Name] - - args := operationArgsMap[operation.Name] - operations = append(operations, NewOperation( - operation, - queryDocument, - args, - s.generateConfig, - )) - } - - return operations, nil -} - -func (s *Source) operationArgsMapByOperationName() map[string][]*Argument { - operationArgsMap := make(map[string][]*Argument) - for _, operation := range s.queryDocument.Operations { - operationArgsMap[operation.Name] = s.sourceGenerator.OperationArguments(operation.VariableDefinitions) - } - - return operationArgsMap -} - -func queryDocumentMapByOperationName(queryDocuments []*ast.QueryDocument) map[string]*ast.QueryDocument { - queryDocumentMap := make(map[string]*ast.QueryDocument) - for _, queryDocument := range queryDocuments { - operation := queryDocument.Operations[0] - queryDocumentMap[operation.Name] = queryDocument - } - - return queryDocumentMap -} - -func queryString(queryDocument *ast.QueryDocument) string { - var buf bytes.Buffer - astFormatter := formatter.NewFormatter(&buf) - astFormatter.FormatQueryDocument(queryDocument) - - return buf.String() -} - -type OperationResponse struct { - Name string - Type types.Type -} - -func (s *Source) OperationResponses() ([]*OperationResponse, error) { - operationResponse := make([]*OperationResponse, 0, len(s.queryDocument.Operations)) - for _, operation := range s.queryDocument.Operations { - responseFields := s.sourceGenerator.NewResponseFields(operation.SelectionSet, operation.Name) - name := getResponseStructName(operation, s.generateConfig) - if s.sourceGenerator.cfg.Models.Exists(name) { - return nil, fmt.Errorf("%s is duplicated", name) - } - operationResponse = append(operationResponse, &OperationResponse{ - Name: name, - Type: responseFields.StructType(), - }) - } - - for _, operationResponse := range operationResponse { - name := operationResponse.Name - s.sourceGenerator.cfg.Models.Add( - name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(name)), - ) - } - - return operationResponse, nil -} - -func (s *Source) ResponseSubTypes() []*StructSource { - return s.sourceGenerator.StructSources -} - -type Query struct { - Name string - Type types.Type -} - -func (s *Source) Query() (*Query, error) { - fields, err := s.sourceGenerator.NewResponseFieldsByDefinition(s.schema.Query) - if err != nil { - return nil, fmt.Errorf("generate failed for query struct type : %w", err) - } - - s.sourceGenerator.cfg.Models.Add( - s.schema.Query.Name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(s.schema.Query.Name)), - ) - - return &Query{ - Name: s.schema.Query.Name, - Type: fields.StructType(), - }, nil -} - -type Mutation struct { - Name string - Type types.Type -} - -func (s *Source) Mutation() (*Mutation, error) { - fields, err := s.sourceGenerator.NewResponseFieldsByDefinition(s.schema.Mutation) - if err != nil { - return nil, fmt.Errorf("generate failed for mutation struct type : %w", err) - } - - s.sourceGenerator.cfg.Models.Add( - s.schema.Mutation.Name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(s.schema.Mutation.Name)), - ) - - return &Mutation{ - Name: s.schema.Mutation.Name, - Type: fields.StructType(), - }, nil -} - -func getResponseStructName(operation *ast.OperationDefinition, generateConfig *config.GenerateConfig) string { - name := operation.Name - if generateConfig != nil { - if generateConfig.Prefix != nil { - if operation.Operation == ast.Mutation { - name = fmt.Sprintf("%s%s", generateConfig.Prefix.Mutation, name) - } - - if operation.Operation == ast.Query { - name = fmt.Sprintf("%s%s", generateConfig.Prefix.Query, name) - } - } - - if generateConfig.Suffix != nil { - if operation.Operation == ast.Mutation { - name = fmt.Sprintf("%s%s", name, generateConfig.Suffix.Mutation) - } - - if operation.Operation == ast.Query { - name = fmt.Sprintf("%s%s", name, generateConfig.Suffix.Query) - } - } - } - - return name -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/source_generator.go b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/source_generator.go deleted file mode 100644 index 4b8a80d06d0..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/source_generator.go +++ /dev/null @@ -1,289 +0,0 @@ -package clientgenv2 - -import ( - "fmt" - "go/types" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -type Argument struct { - Variable string - Type types.Type -} - -type ResponseField struct { - Name string - IsFragmentSpread bool - IsInlineFragment bool - Type types.Type - Tags []string - ResponseFields ResponseFieldList -} - -type ResponseFieldList []*ResponseField - -func (rs ResponseFieldList) IsFragmentSpread() bool { - if len(rs) != 1 { - return false - } - - return rs[0].IsFragmentSpread -} - -func (rs ResponseFieldList) StructType() *types.Struct { - vars := make([]*types.Var, 0) - structTags := make([]string, 0) - for _, filed := range rs { - // クエリーのフィールドの子階層がFragmentの場合、このフィールドにそのFragmentの型を追加する - if filed.IsFragmentSpread { - typ, ok := filed.ResponseFields.StructType().Underlying().(*types.Struct) - if !ok { - continue - } - for j := 0; j < typ.NumFields(); j++ { - vars = append(vars, typ.Field(j)) - structTags = append(structTags, typ.Tag(j)) - } - } else { - vars = append(vars, types.NewVar(0, nil, templates.ToGo(filed.Name), filed.Type)) - structTags = append(structTags, strings.Join(filed.Tags, " ")) - } - } - - return types.NewStruct(vars, structTags) -} - -func (rs ResponseFieldList) IsFragment() bool { - if len(rs) != 1 { - return false - } - - return rs[0].IsInlineFragment || rs[0].IsFragmentSpread -} - -func (rs ResponseFieldList) IsBasicType() bool { - return len(rs) == 0 -} - -func (rs ResponseFieldList) IsStructType() bool { - return len(rs) > 0 && !rs.IsFragment() -} - -type StructSource struct { - Name string - Type types.Type -} - -type SourceGenerator struct { - cfg *config.Config - binder *config.Binder - client config.PackageConfig - StructSources []*StructSource -} - -func NewSourceGenerator(cfg *config.Config, client config.PackageConfig) *SourceGenerator { - return &SourceGenerator{ - cfg: cfg, - binder: cfg.NewBinder(), - client: client, - StructSources: []*StructSource{}, - } -} - -func (r *SourceGenerator) NewResponseFields(selectionSet ast.SelectionSet, typeName string) ResponseFieldList { - responseFields := make(ResponseFieldList, 0, len(selectionSet)) - for _, selection := range selectionSet { - responseFields = append(responseFields, r.NewResponseField(selection, typeName)) - } - - return responseFields -} - -func (r *SourceGenerator) NewResponseFieldsByDefinition(definition *ast.Definition) (ResponseFieldList, error) { - fields := make(ResponseFieldList, 0, len(definition.Fields)) - for _, field := range definition.Fields { - if field.Type.Name() == "__Schema" || field.Type.Name() == "__Type" { - continue - } - - var typ types.Type - if field.Type.Name() == "Query" || field.Type.Name() == "Mutation" { - var baseType types.Type - baseType, err := r.binder.FindType(r.client.Pkg().Path(), field.Type.Name()) - if err != nil { - if !strings.Contains(err.Error(), "unable to find type") { - return nil, fmt.Errorf("not found type: %w", err) - } - - // create new type - baseType = types.NewPointer(types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(field.Type.Name()), nil), - nil, - nil, - )) - } - - // for recursive struct field in go - typ = types.NewPointer(baseType) - } else { - baseType, err := r.binder.FindTypeFromName(r.cfg.Models[field.Type.Name()].Model[0]) - if err != nil { - return nil, fmt.Errorf("not found type: %w", err) - } - - typ = r.binder.CopyModifiersFromAst(field.Type, baseType) - } - - var tags []string - if !field.Type.NonNull { - tags = append(tags, fmt.Sprintf(`json:"%s,omitempty"`, field.Name), fmt.Sprintf(`graphql:"%s"`, field.Name)) - } else { - tags = append(tags, fmt.Sprintf(`json:"%s"`, field.Name), fmt.Sprintf(`graphql:"%s"`, field.Name)) - } - - fields = append(fields, &ResponseField{ - Name: field.Name, - Type: typ, - Tags: tags, - }) - } - - return fields, nil -} - -func NewLayerTypeName(base, thisField string) string { - return fmt.Sprintf("%s_%s", base, thisField) -} - -func (r *SourceGenerator) NewResponseField(selection ast.Selection, typeName string) *ResponseField { - switch selection := selection.(type) { - case *ast.Field: - typeName = NewLayerTypeName(typeName, templates.ToGo(selection.Alias)) - fieldsResponseFields := r.NewResponseFields(selection.SelectionSet, typeName) - - var baseType types.Type - switch { - case fieldsResponseFields.IsBasicType(): - baseType = r.Type(selection.Definition.Type.Name()) - case fieldsResponseFields.IsFragment(): - // 子フィールドがFragmentの場合はこのFragmentがフィールドの型になる - // if a child field is fragment, this field type became fragment. - baseType = fieldsResponseFields[0].Type - case fieldsResponseFields.IsStructType(): - structType := fieldsResponseFields.StructType() - r.StructSources = append(r.StructSources, &StructSource{ - Name: typeName, - Type: structType, - }) - baseType = types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), typeName, nil), - structType, - nil, - ) - default: - // ここにきたらバグ - // here is bug - panic("not match type") - } - - // GraphQLの定義がオプショナルのはtypeのポインタ型が返り、配列の定義場合はポインタのスライスの型になって返ってきます - // return pointer type then optional type or slice pointer then slice type of definition in GraphQL. - typ := r.binder.CopyModifiersFromAst(selection.Definition.Type, baseType) - - tags := []string{ - fmt.Sprintf(`json:"%s"`, selection.Alias), - fmt.Sprintf(`graphql:"%s"`, selection.Alias), - } - - return &ResponseField{ - Name: selection.Alias, - Type: typ, - Tags: tags, - ResponseFields: fieldsResponseFields, - } - - case *ast.FragmentSpread: - // この構造体はテンプレート側で使われることはなく、ast.FieldでFragment判定するために使用する - fieldsResponseFields := r.NewResponseFields(selection.Definition.SelectionSet, NewLayerTypeName(typeName, templates.ToGo(selection.Name))) - baseType := types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(selection.Name), nil), - fieldsResponseFields.StructType(), - nil, - ) - - return &ResponseField{ - Name: selection.Name, - Type: types.NewPointer(baseType), - IsFragmentSpread: true, - ResponseFields: fieldsResponseFields, - } - - case *ast.InlineFragment: - // InlineFragmentは子要素をそのままstructとしてもつので、ここで、構造体の型を作成します - name := NewLayerTypeName(typeName, templates.ToGo(selection.TypeCondition)) - fieldsResponseFields := r.NewResponseFields(selection.SelectionSet, name) - - if fieldsResponseFields.IsFragmentSpread() { - typ := types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(fieldsResponseFields[0].Name), nil), - fieldsResponseFields.StructType(), - nil, - ) - - return &ResponseField{ - Name: selection.TypeCondition, - Type: typ, - Tags: []string{fmt.Sprintf(`graphql:"... on %s"`, selection.TypeCondition)}, - ResponseFields: fieldsResponseFields, - } - } - - structType := fieldsResponseFields.StructType() - r.StructSources = append(r.StructSources, &StructSource{ - Name: name, - Type: structType, - }) - typ := types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), name, nil), - structType, - nil, - ) - - return &ResponseField{ - Name: selection.TypeCondition, - Type: typ, - IsInlineFragment: true, - Tags: []string{fmt.Sprintf(`graphql:"... on %s"`, selection.TypeCondition)}, - ResponseFields: fieldsResponseFields, - } - } - - panic("unexpected selection type") -} - -func (r *SourceGenerator) OperationArguments(variableDefinitions ast.VariableDefinitionList) []*Argument { - argumentTypes := make([]*Argument, 0, len(variableDefinitions)) - for _, v := range variableDefinitions { - argumentTypes = append(argumentTypes, &Argument{ - Variable: v.Variable, - Type: r.binder.CopyModifiersFromAst(v.Type, r.Type(v.Type.Name())), - }) - } - - return argumentTypes -} - -// Typeの引数に渡すtypeNameは解析した結果からselectionなどから求めた型の名前を渡さなければいけない -func (r *SourceGenerator) Type(typeName string) types.Type { - goType, err := r.binder.FindTypeFromName(r.cfg.Models[typeName].Model[0]) - if err != nil { - // 実装として正しいtypeNameを渡していれば必ず見つかるはずなのでpanic - panic(fmt.Sprintf("%+v", err)) - } - - return goType -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/template.go b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/template.go deleted file mode 100644 index 156ea0de650..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/template.go +++ /dev/null @@ -1,39 +0,0 @@ -package clientgenv2 - -import ( - - // nolint:golint, nolintlint - _ "embed" - "fmt" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - gqlgencConfig "github.com/Yamashou/gqlgenc/config" -) - -//go:embed template.gotpl -var template string - -func RenderTemplate(cfg *config.Config, query *Query, mutation *Mutation, fragments []*Fragment, operations []*Operation, operationResponses []*OperationResponse, structSources []*StructSource, generateCfg *gqlgencConfig.GenerateConfig, client config.PackageConfig) error { - if err := templates.Render(templates.Options{ - PackageName: client.Package, - Filename: client.Filename, - Template: template, - Data: map[string]interface{}{ - "Query": query, - "Mutation": mutation, - "Fragment": fragments, - "Operation": operations, - "OperationResponse": operationResponses, - "GenerateClient": generateCfg.ShouldGenerateClient(), - "StructSources": structSources, - "ClientInterfaceName": generateCfg.GetClientInterfaceName(), - }, - Packages: cfg.Packages, - PackageDoc: "// Code generated by github.com/Yamashou/gqlgenc, DO NOT EDIT.\n", - }); err != nil { - return fmt.Errorf("%s generating failed: %w", client.Filename, err) - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/template.gotpl b/vendor/github.com/Yamashou/gqlgenc/clientgenv2/template.gotpl deleted file mode 100644 index fbb6167e78a..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/clientgenv2/template.gotpl +++ /dev/null @@ -1,73 +0,0 @@ -{{- if .GenerateClient }} - {{ reserveImport "bytes" }} - {{ reserveImport "context" }} - {{ reserveImport "encoding/json" }} - {{ reserveImport "fmt" }} - {{ reserveImport "io" }} - {{ reserveImport "io/ioutil" }} - {{ reserveImport "net/http" }} - {{ reserveImport "net/url" }} - {{ reserveImport "path" }} - {{ reserveImport "time" }} - - - {{ reserveImport "github.com/Yamashou/gqlgenc/graphqljson" }} - {{ reserveImport "github.com/Yamashou/gqlgenc/clientv2" }} - - - {{- if .ClientInterfaceName }} - type {{ .ClientInterfaceName }} interface { - {{- range $model := .Operation }} - {{ $model.Name | go }} (ctx context.Context{{- range $arg := .Args }}, {{ $arg.Variable | goPrivate }} {{ $arg.Type | ref }} {{- end }}, interceptors ...clientv2.RequestInterceptor) (*{{ $model.ResponseStructName | go }}, error) - {{- end }} - } - {{- end }} - - type Client struct { - Client *clientv2.Client - } - - func NewClient(cli *http.Client, baseURL string, interceptors ...clientv2.RequestInterceptor) {{- if .ClientInterfaceName }} {{ .ClientInterfaceName }} {{- else }} *Client {{- end }} { - return &Client{Client: clientv2.NewClient(cli, baseURL, interceptors...)} - } - -{{- end }} - -type {{ .Query.Name | go }} {{ .Query.Type | ref }} - -{{- if .Mutation }} - type {{ .Mutation.Name | go }} {{ .Mutation.Type | ref }} -{{- end }} - -{{- range $name, $element := .Fragment }} - type {{ .Name | go }} {{ .Type | ref }} -{{- end }} - -{{- range $name, $element := .StructSources }} - type {{ .Name }} {{ .Type | ref }} -{{- end}} - -{{- range $name, $element := .OperationResponse }} - type {{ .Name | go }} {{ .Type | ref }} -{{- end }} - -{{- range $model := .Operation}} - const {{ $model.Name|go }}Document = `{{ $model.Operation }}` - - {{- if $.GenerateClient }} - func (c *Client) {{ $model.Name|go }} (ctx context.Context{{- range $arg := .Args }}, {{ $arg.Variable | goPrivate }} {{ $arg.Type | ref }} {{- end }}, interceptors ...clientv2.RequestInterceptor) (*{{ $model.ResponseStructName | go }}, error) { - vars := map[string]interface{}{ - {{- range $args := .VariableDefinitions}} - "{{ $args.Variable }}": {{ $args.Variable | goPrivate }}, - {{- end }} - } - - var res {{ $model.ResponseStructName | go }} - if err := c.Client.Post(ctx, "{{ $model.Name }}", {{ $model.Name|go }}Document, &res, vars, interceptors...); err != nil { - return nil, err - } - - return &res, nil - } - {{- end}} -{{- end}} diff --git a/vendor/github.com/Yamashou/gqlgenc/config/config.go b/vendor/github.com/Yamashou/gqlgenc/config/config.go deleted file mode 100644 index 2ac49a2a1e2..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/config/config.go +++ /dev/null @@ -1,311 +0,0 @@ -package config - -import ( - "context" - "fmt" - "io/ioutil" - "net/http" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/Yamashou/gqlgenc/client" - "github.com/Yamashou/gqlgenc/introspection" - "github.com/vektah/gqlparser/v2" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/validator" - "gopkg.in/yaml.v2" -) - -// Config extends the gqlgen basic config -// and represents the config file -type Config struct { - SchemaFilename StringList `yaml:"schema,omitempty"` - Model config.PackageConfig `yaml:"model,omitempty"` - Client config.PackageConfig `yaml:"client,omitempty"` - Models config.TypeMap `yaml:"models,omitempty"` - Endpoint *EndPointConfig `yaml:"endpoint,omitempty"` - Generate *GenerateConfig `yaml:"generate,omitempty"` - - Query []string `yaml:"query"` - - // gqlgen config struct - GQLConfig *config.Config `yaml:"-"` -} - -var cfgFilenames = []string{".gqlgenc.yml", "gqlgenc.yml", "gqlgenc.yaml"} - -// StringList is a simple array of strings -type StringList []string - -// Has checks if the strings array has a give value -func (a StringList) Has(file string) bool { - for _, existing := range a { - if existing == file { - return true - } - } - - return false -} - -// LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories -// walking up the tree. The closest config file will be returned. -func LoadConfigFromDefaultLocations() (*Config, error) { - cfgFile, err := findCfg() - if err != nil { - return nil, err - } - - err = os.Chdir(filepath.Dir(cfgFile)) - if err != nil { - return nil, fmt.Errorf("unable to enter config dir: %w", err) - } - - return LoadConfig(cfgFile) -} - -// EndPointConfig are the allowed options for the 'endpoint' config -type EndPointConfig struct { - URL string `yaml:"url"` - Headers map[string]string `yaml:"headers,omitempty"` -} - -// findCfg searches for the config file in this directory and all parents up the tree -// looking for the closest match -func findCfg() (string, error) { - dir, err := os.Getwd() - if err != nil { - return "", fmt.Errorf("unable to get working dir to findCfg: %w", err) - } - - cfg := findCfgInDir(dir) - - for cfg == "" && dir != filepath.Dir(dir) { - dir = filepath.Dir(dir) - cfg = findCfgInDir(dir) - } - - if cfg == "" { - return "", os.ErrNotExist - } - - return cfg, nil -} - -func findCfgInDir(dir string) string { - for _, cfgName := range cfgFilenames { - path := filepath.Join(dir, cfgName) - if _, err := os.Stat(path); err == nil { - return path - } - } - - return "" -} - -var path2regex = strings.NewReplacer( - `.`, `\.`, - `*`, `.+`, - `\`, `[\\/]`, - `/`, `[\\/]`, -) - -// LoadConfig loads and parses the config gqlgenc config -func LoadConfig(filename string) (*Config, error) { - var cfg Config - b, err := ioutil.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to read config: %w", err) - } - - confContent := []byte(os.ExpandEnv(string(b))) - if err := yaml.UnmarshalStrict(confContent, &cfg); err != nil { - return nil, fmt.Errorf("unable to parse config: %w", err) - } - - if cfg.SchemaFilename != nil && cfg.Endpoint != nil { - return nil, fmt.Errorf("'schema' and 'endpoint' both specified. Use schema to load from a local file, use endpoint to load from a remote server (using introspection)") - } - - if cfg.SchemaFilename == nil && cfg.Endpoint == nil { - return nil, fmt.Errorf("neither 'schema' nor 'endpoint' specified. Use schema to load from a local file, use endpoint to load from a remote server (using introspection)") - } - - // https://github.com/99designs/gqlgen/blob/3a31a752df764738b1f6e99408df3b169d514784/codegen/config/config.go#L120 - for _, f := range cfg.SchemaFilename { - var matches []string - - // for ** we want to override default globbing patterns and walk all - // subdirectories to match schema files. - if strings.Contains(f, "**") { - pathParts := strings.SplitN(f, "**", 2) - rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`) - // turn the rest of the glob into a regex, anchored only at the end because ** allows - // for any number of dirs in between and walk will let us match against the full path name - globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`) - - if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) { - matches = append(matches, path) - } - - return nil - }); err != nil { - return nil, fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) - } - } else { - matches, err = filepath.Glob(f) - if err != nil { - return nil, fmt.Errorf("failed to glob schema filename %s: %w", f, err) - } - } - - files := StringList{} - for _, m := range matches { - if !files.Has(m) { - files = append(files, m) - } - } - - cfg.SchemaFilename = files - } - - models := make(config.TypeMap) - if cfg.Models != nil { - models = cfg.Models - } - - sources := []*ast.Source{} - - for _, filename := range cfg.SchemaFilename { - filename = filepath.ToSlash(filename) - var err error - var schemaRaw []byte - schemaRaw, err = ioutil.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to open schema: %w", err) - } - - sources = append(sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) - } - - cfg.GQLConfig = &config.Config{ - Model: cfg.Model, - Models: models, - // TODO: gqlgen must be set exec but client not used - Exec: config.ExecConfig{Filename: "generated.go"}, - Directives: map[string]config.DirectiveConfig{}, - Sources: sources, - } - - if err := cfg.Client.Check(); err != nil { - return nil, fmt.Errorf("config.exec: %w", err) - } - - return &cfg, nil -} - -// LoadSchema load and parses the schema from a local file or a remote server -func (c *Config) LoadSchema(ctx context.Context) error { - var schema *ast.Schema - - if c.SchemaFilename != nil { - s, err := c.loadLocalSchema() - if err != nil { - return fmt.Errorf("load local schema failed: %w", err) - } - - schema = s - } else { - s, err := c.loadRemoteSchema(ctx) - if err != nil { - return fmt.Errorf("load remote schema failed: %w", err) - } - - schema = s - } - - if schema.Query == nil { - schema.Query = &ast.Definition{ - Kind: ast.Object, - Name: "Query", - } - schema.Types["Query"] = schema.Query - } - - c.GQLConfig.Schema = schema - - return nil -} - -func (c *Config) loadRemoteSchema(ctx context.Context) (*ast.Schema, error) { - addHeader := func(req *http.Request) { - for key, value := range c.Endpoint.Headers { - req.Header.Set(key, value) - } - } - gqlclient := client.NewClient(http.DefaultClient, c.Endpoint.URL, addHeader) - - var res introspection.Query - if err := gqlclient.Post(ctx, "Query", introspection.Introspection, &res, nil); err != nil { - return nil, fmt.Errorf("introspection query failed: %w", err) - } - - schema, err := validator.ValidateSchemaDocument(introspection.ParseIntrospectionQuery(c.Endpoint.URL, res)) - if err != nil { - return nil, fmt.Errorf("validation error: %w", err) - } - - return schema, nil -} - -func (c *Config) loadLocalSchema() (*ast.Schema, error) { - schema, err := gqlparser.LoadSchema(c.GQLConfig.Sources...) - if err != nil { - return nil, err - } - - return schema, nil -} - -type GenerateConfig struct { - Prefix *NamingConfig `yaml:"prefix,omitempty"` - Suffix *NamingConfig `yaml:"suffix,omitempty"` - UnamedPattern string `yaml:"unamedPattern,omitempty"` - Client *bool `yaml:"client,omitempty"` - ClientInterfaceName *string `yaml:"clientInterfaceName,omitempty"` - // if true, used client v2 in generate code - ClientV2 bool `yaml:"clientV2,omitempty"` -} - -func (c *GenerateConfig) ShouldGenerateClient() bool { - if c == nil { - return true - } - - if c.Client != nil && !*c.Client { - return false - } - - return true -} - -func (c *GenerateConfig) GetClientInterfaceName() *string { - if c == nil { - return nil - } - - return c.ClientInterfaceName -} - -type NamingConfig struct { - Query string `yaml:"query,omitempty"` - Mutation string `yaml:"mutation,omitempty"` -} diff --git a/vendor/github.com/Yamashou/gqlgenc/generator/generater.go b/vendor/github.com/Yamashou/gqlgenc/generator/generater.go deleted file mode 100644 index 7c803ae54b2..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/generator/generater.go +++ /dev/null @@ -1,60 +0,0 @@ -package generator - -import ( - "context" - "fmt" - - "github.com/99designs/gqlgen/api" - codegenconfig "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/plugin" - "github.com/99designs/gqlgen/plugin/modelgen" - "github.com/Yamashou/gqlgenc/config" -) - -// mutateHook adds the "omitempty" option to nilable fields. -// For more info see https://github.com/99designs/gqlgen/blob/master/docs/content/recipes/modelgen-hook.md -func mutateHook(build *modelgen.ModelBuild) *modelgen.ModelBuild { - for _, model := range build.Models { - for _, field := range model.Fields { - field.Tag = `json:"` + field.Name - if codegenconfig.IsNilable(field.Type) { - field.Tag += ",omitempty" - } - field.Tag += `"` - } - } - - return build -} - -func Generate(ctx context.Context, cfg *config.Config, option ...api.Option) error { - var plugins []plugin.Plugin - if cfg.Model.IsDefined() { - p := modelgen.Plugin{ - MutateHook: mutateHook, - } - plugins = append(plugins, &p) - } - for _, o := range option { - o(cfg.GQLConfig, &plugins) - } - - if err := cfg.LoadSchema(ctx); err != nil { - return fmt.Errorf("failed to load schema: %w", err) - } - - if err := cfg.GQLConfig.Init(); err != nil { - return fmt.Errorf("generating core failed: %w", err) - } - - for _, p := range plugins { - if mut, ok := p.(plugin.ConfigMutator); ok { - err := mut.MutateConfig(cfg.GQLConfig) - if err != nil { - return fmt.Errorf("%s failed: %w", p.Name(), err) - } - } - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/graphqljson/graphql.go b/vendor/github.com/Yamashou/gqlgenc/graphqljson/graphql.go deleted file mode 100644 index d41e4c56578..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/graphqljson/graphql.go +++ /dev/null @@ -1,369 +0,0 @@ -/* -MIT License - -Copyright (c) 2017 Dmitri Shuralyov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -// Package graphqljson provides a function for decoding JSON -// into a GraphQL query data structure. -package graphqljson - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "reflect" - "strings" -) - -// Reference: https://blog.gopheracademy.com/advent-2017/custom-json-unmarshaler-for-graphql-client/ - -// UnmarshalData parses the JSON-encoded GraphQL response data and stores -// the result in the GraphQL query data structure pointed to by v. -// -// The implementation is created on top of the JSON tokenizer available -// in "encoding/json".Decoder. -func UnmarshalData(data json.RawMessage, v interface{}) error { - d := newDecoder(bytes.NewBuffer(data)) - if err := d.Decode(v); err != nil { - return fmt.Errorf(": %w", err) - } - - // TODO: この処理が本当に必要かは今後検討 - tok, err := d.jsonDecoder.Token() - switch err { - case io.EOF: - // Expect to get io.EOF. There shouldn't be any more - // tokens left after we've decoded v successfully. - return nil - case nil: - return fmt.Errorf("invalid token '%v' after top-level value", tok) - } - - return fmt.Errorf("invalid token '%v' after top-level value", tok) -} - -// Decoder is a JSON Decoder that performs custom unmarshaling behavior -// for GraphQL query data structures. It's implemented on top of a JSON tokenizer. -type Decoder struct { - jsonDecoder *json.Decoder - - // Stack of what part of input JSON we're in the middle of - objects, arrays. - parseState []json.Delim - - // Stacks of values where to unmarshal. - // The top of each stack is the reflect.Value where to unmarshal next JSON value. - // - // The reason there's more than one stack is because we might be unmarshaling - // a single JSON value into multiple GraphQL fragments or embedded structs, so - // we keep track of them all. - vs [][]reflect.Value -} - -func newDecoder(r io.Reader) *Decoder { - jsonDecoder := json.NewDecoder(r) - jsonDecoder.UseNumber() - - return &Decoder{ - jsonDecoder: jsonDecoder, - } -} - -// Decode decodes a single JSON value from d.tokenizer into v. -func (d *Decoder) Decode(v interface{}) error { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return fmt.Errorf("cannot decode into non-pointer %T", v) - } - - d.vs = [][]reflect.Value{{rv.Elem()}} - if err := d.decode(); err != nil { - return fmt.Errorf(": %w", err) - } - - return nil -} - -// decode decodes a single JSON value from d.tokenizer into d.vs. -func (d *Decoder) decode() error { - // The loop invariant is that the top of each d.vs stack - // is where we try to unmarshal the next JSON value we see. - for len(d.vs) > 0 { - tok, err := d.jsonDecoder.Token() - if err == io.EOF { - return errors.New("unexpected end of JSON input") - } else if err != nil { - return fmt.Errorf(": %w", err) - } - - switch { - // Are we inside an object and seeing next key (rather than end of object)? - case d.state() == '{' && tok != json.Delim('}'): - key, ok := tok.(string) - if !ok { - return errors.New("unexpected non-key in JSON input") - } - - // The last matching one is the one considered - var matchingFieldValue *reflect.Value - for i := range d.vs { - v := d.vs[i][len(d.vs[i])-1] - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - var f reflect.Value - if v.Kind() == reflect.Struct { - f = fieldByGraphQLName(v, key) - if f.IsValid() { - matchingFieldValue = &f - } - } - d.vs[i] = append(d.vs[i], f) - } - if matchingFieldValue == nil { - return fmt.Errorf("struct field for %q doesn't exist in any of %v places to unmarshal", key, len(d.vs)) - } - - // We've just consumed the current token, which was the key. - // Read the next token, which should be the value. - // If it's of json.RawMessage type, decode the value. - if matchingFieldValue.Type() == reflect.TypeOf(json.RawMessage{}) { - var data json.RawMessage - err = d.jsonDecoder.Decode(&data) - tok = data - } else { - tok, err = d.jsonDecoder.Token() - } - - if err == io.EOF { - return errors.New("unexpected end of JSON input") - } else if err != nil { - return fmt.Errorf(": %w", err) - } - - // Are we inside an array and seeing next value (rather than end of array)? - case d.state() == '[' && tok != json.Delim(']'): - someSliceExist := false - for i := range d.vs { - v := d.vs[i][len(d.vs[i])-1] - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - var f reflect.Value - if v.Kind() == reflect.Slice { - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) // v = append(v, T). - f = v.Index(v.Len() - 1) - someSliceExist = true - } - d.vs[i] = append(d.vs[i], f) - } - if !someSliceExist { - return fmt.Errorf("slice doesn't exist in any of %v places to unmarshal", len(d.vs)) - } - } - - switch tok := tok.(type) { - case string, json.Number, bool, nil, json.RawMessage: - // Value. - - for i := range d.vs { - v := d.vs[i][len(d.vs[i])-1] - if !v.IsValid() { - continue - } - err := unmarshalValue(tok, v) - if err != nil { - return fmt.Errorf(": %w", err) - } - } - d.popAllVs() - - case json.Delim: - switch tok { - case '{': - // Start of object. - - d.pushState(tok) - - frontier := make([]reflect.Value, len(d.vs)) // Places to look for GraphQL fragments/embedded structs. - for i := range d.vs { - v := d.vs[i][len(d.vs[i])-1] - frontier[i] = v - // TODO: Do this recursively or not? Add a test case if needed. - if v.Kind() == reflect.Ptr && v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) // v = new(T). - } - } - // Find GraphQL fragments/embedded structs recursively, adding to frontier - // as new ones are discovered and exploring them further. - for len(frontier) > 0 { - v := frontier[0] - frontier = frontier[1:] - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if v.Kind() != reflect.Struct { - continue - } - for i := 0; i < v.NumField(); i++ { - if isGraphQLFragment(v.Type().Field(i)) || v.Type().Field(i).Anonymous { - // Add GraphQL fragment or embedded struct. - d.vs = append(d.vs, []reflect.Value{v.Field(i)}) - frontier = append(frontier, v.Field(i)) - } - } - } - case '[': - // Start of array. - - d.pushState(tok) - - for i := range d.vs { - v := d.vs[i][len(d.vs[i])-1] - // TODO: Confirm this is needed, write a test case. - // if v.Kind() == reflect.Ptr && v.IsNil() { - // v.Set(reflect.New(v.Type().Elem())) // v = new(T). - //} - - // Reset slice to empty (in case it had non-zero initial value). - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if v.Kind() != reflect.Slice { - continue - } - v.Set(reflect.MakeSlice(v.Type(), 0, 0)) // v = make(T, 0, 0). - } - case '}', ']': - // End of object or array. - d.popAllVs() - d.popState() - default: - return errors.New("unexpected delimiter in JSON input") - } - default: - return errors.New("unexpected token in JSON input") - } - } - - return nil -} - -// pushState pushes a new parse state s onto the stack. -func (d *Decoder) pushState(s json.Delim) { - d.parseState = append(d.parseState, s) -} - -// popState pops a parse state (already obtained) off the stack. -// The stack must be non-empty. -func (d *Decoder) popState() { - d.parseState = d.parseState[:len(d.parseState)-1] -} - -// state reports the parse state on top of stack, or 0 if empty. -func (d *Decoder) state() json.Delim { - if len(d.parseState) == 0 { - return 0 - } - - return d.parseState[len(d.parseState)-1] -} - -// popAllVs pops from all d.vs stacks, keeping only non-empty ones. -func (d *Decoder) popAllVs() { - var nonEmpty [][]reflect.Value - for i := range d.vs { - d.vs[i] = d.vs[i][:len(d.vs[i])-1] - if len(d.vs[i]) > 0 { - nonEmpty = append(nonEmpty, d.vs[i]) - } - } - d.vs = nonEmpty -} - -// fieldByGraphQLName returns an exported struct field of struct v -// that matches GraphQL name, or invalid reflect.Value if none found. -func fieldByGraphQLName(v reflect.Value, name string) reflect.Value { - for i := 0; i < v.NumField(); i++ { - if v.Type().Field(i).PkgPath != "" { - // Skip unexported field. - continue - } - if hasGraphQLName(v.Type().Field(i), name) { - return v.Field(i) - } - } - - return reflect.Value{} -} - -// hasGraphQLName reports whether struct field f has GraphQL name. -func hasGraphQLName(f reflect.StructField, name string) bool { - value, ok := f.Tag.Lookup("graphql") - if !ok { - // TODO: caseconv package is relatively slow. Optimize it, then consider using it here. - // return caseconv.MixedCapsToLowerCamelCase(f.Name) == name - return strings.EqualFold(f.Name, name) - } - value = strings.TrimSpace(value) // TODO: Parse better. - if strings.HasPrefix(value, "...") { - // GraphQL fragment. It doesn't have a name. - return false - } - if i := strings.Index(value, "("); i != -1 { - value = value[:i] - } - if i := strings.Index(value, ":"); i != -1 { - value = value[:i] - } - - return strings.TrimSpace(value) == name -} - -// isGraphQLFragment reports whether struct field f is a GraphQL fragment. -func isGraphQLFragment(f reflect.StructField) bool { - value, ok := f.Tag.Lookup("graphql") - if !ok { - return false - } - value = strings.TrimSpace(value) // TODO: Parse better. - - return strings.HasPrefix(value, "...") -} - -// unmarshalValue unmarshals JSON value into v. -// v must be addressable and not obtained by the use of unexported -// struct fields, otherwise unmarshalValue will panic. -func unmarshalValue(value json.Token, v reflect.Value) error { - b, err := json.Marshal(value) // TODO: Short-circuit (if profiling says it's worth it). - if err != nil { - return fmt.Errorf(": %w", err) - } - - err = json.Unmarshal(b, v.Addr().Interface()) - if err != nil { - return fmt.Errorf(": %w", err) - } - - return nil -} diff --git a/vendor/github.com/Yamashou/gqlgenc/introspection/parse.go b/vendor/github.com/Yamashou/gqlgenc/introspection/parse.go deleted file mode 100644 index e878125bd2e..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/introspection/parse.go +++ /dev/null @@ -1,326 +0,0 @@ -package introspection - -import ( - "fmt" - - "github.com/vektah/gqlparser/v2/ast" -) - -func ParseIntrospectionQuery(url string, query Query) *ast.SchemaDocument { - parser := parser{ - sharedPosition: &ast.Position{Src: &ast.Source{ - Name: "remote", - BuiltIn: false, - }}, - } - - if url != "" { - parser.sharedPosition.Src.Name = url - } - - return parser.parseIntrospectionQuery(query) -} - -type parser struct { - sharedPosition *ast.Position -} - -func (p parser) parseIntrospectionQuery(query Query) *ast.SchemaDocument { - var doc ast.SchemaDocument - typeMap := query.Schema.Types.NameMap() - - doc.Schema = append(doc.Schema, p.parseSchemaDefinition(query, typeMap)) - doc.Position = p.sharedPosition - - for _, typeVale := range typeMap { - doc.Definitions = append(doc.Definitions, p.parseTypeSystemDefinition(typeVale)) - } - - for _, directiveValue := range query.Schema.Directives { - doc.Directives = append(doc.Directives, p.parseDirectiveDefinition(directiveValue)) - } - - return &doc -} - -func (p parser) parseSchemaDefinition(query Query, typeMap map[string]*FullType) *ast.SchemaDefinition { - def := ast.SchemaDefinition{} - def.Position = p.sharedPosition - - if query.Schema.QueryType.Name != nil { - def.OperationTypes = append(def.OperationTypes, - p.parseOperationTypeDefinitionForQuery(typeMap[*query.Schema.QueryType.Name]), - ) - } - - if query.Schema.MutationType != nil { - def.OperationTypes = append(def.OperationTypes, - p.parseOperationTypeDefinitionForMutation(typeMap[*query.Schema.MutationType.Name]), - ) - } - - return &def -} - -func (p parser) parseOperationTypeDefinitionForQuery(fullType *FullType) *ast.OperationTypeDefinition { - var op ast.OperationTypeDefinition - op.Operation = ast.Query - op.Type = *fullType.Name - op.Position = p.sharedPosition - - return &op -} - -func (p parser) parseOperationTypeDefinitionForMutation(fullType *FullType) *ast.OperationTypeDefinition { - var op ast.OperationTypeDefinition - op.Operation = ast.Mutation - op.Type = *fullType.Name - op.Position = p.sharedPosition - - return &op -} - -func (p parser) parseDirectiveDefinition(directiveValue *DirectiveType) *ast.DirectiveDefinition { - args := make(ast.ArgumentDefinitionList, 0, len(directiveValue.Args)) - for _, arg := range directiveValue.Args { - argumentDefinition := p.buildInputValue(arg) - args = append(args, argumentDefinition) - } - locations := make([]ast.DirectiveLocation, 0, len(directiveValue.Locations)) - for _, locationValue := range directiveValue.Locations { - locations = append(locations, ast.DirectiveLocation(locationValue)) - } - - return &ast.DirectiveDefinition{ - Description: pointerString(directiveValue.Description), - Name: directiveValue.Name, - Arguments: args, - Locations: locations, - Position: p.sharedPosition, - } -} - -func (p parser) parseObjectFields(typeVale *FullType) ast.FieldList { - fieldList := make(ast.FieldList, 0, len(typeVale.Fields)) - for _, field := range typeVale.Fields { - typ := p.getType(&field.Type) - args := make(ast.ArgumentDefinitionList, 0, len(field.Args)) - for _, arg := range field.Args { - argumentDefinition := p.buildInputValue(arg) - args = append(args, argumentDefinition) - } - - fieldDefinition := &ast.FieldDefinition{ - Description: pointerString(field.Description), - Name: field.Name, - Arguments: args, - Type: typ, - Position: p.sharedPosition, - } - fieldList = append(fieldList, fieldDefinition) - } - - return fieldList -} - -func (p parser) parseInputObjectFields(typeVale *FullType) ast.FieldList { - fieldList := make(ast.FieldList, 0, len(typeVale.InputFields)) - for _, field := range typeVale.InputFields { - typ := p.getType(&field.Type) - fieldDefinition := &ast.FieldDefinition{ - Description: pointerString(field.Description), - Name: field.Name, - Type: typ, - Position: p.sharedPosition, - } - fieldList = append(fieldList, fieldDefinition) - } - - return fieldList -} - -func (p parser) parseObjectTypeDefinition(typeVale *FullType) *ast.Definition { - fieldList := p.parseObjectFields(typeVale) - interfaces := make([]string, 0, len(typeVale.Interfaces)) - for _, intf := range typeVale.Interfaces { - interfaces = append(interfaces, pointerString(intf.Name)) - } - - enums := make(ast.EnumValueList, 0, len(typeVale.EnumValues)) - for _, enum := range typeVale.EnumValues { - enumValue := &ast.EnumValueDefinition{ - Description: pointerString(enum.Description), - Name: enum.Name, - Position: p.sharedPosition, - } - enums = append(enums, enumValue) - } - - return &ast.Definition{ - Kind: ast.Object, - Description: pointerString(typeVale.Description), - Name: pointerString(typeVale.Name), - Interfaces: interfaces, - Fields: fieldList, - EnumValues: enums, - Position: p.sharedPosition, - BuiltIn: true, - } -} - -func (p parser) parseInterfaceTypeDefinition(typeVale *FullType) *ast.Definition { - fieldList := p.parseObjectFields(typeVale) - interfaces := make([]string, 0, len(typeVale.Interfaces)) - for _, intf := range typeVale.Interfaces { - interfaces = append(interfaces, pointerString(intf.Name)) - } - - return &ast.Definition{ - Kind: ast.Interface, - Description: pointerString(typeVale.Description), - Name: pointerString(typeVale.Name), - Interfaces: interfaces, - Fields: fieldList, - Position: p.sharedPosition, - BuiltIn: true, - } -} - -func (p parser) parseInputObjectTypeDefinition(typeVale *FullType) *ast.Definition { - fieldList := p.parseInputObjectFields(typeVale) - interfaces := make([]string, 0, len(typeVale.Interfaces)) - for _, intf := range typeVale.Interfaces { - interfaces = append(interfaces, pointerString(intf.Name)) - } - - return &ast.Definition{ - Kind: ast.InputObject, - Description: pointerString(typeVale.Description), - Name: pointerString(typeVale.Name), - Interfaces: interfaces, - Fields: fieldList, - Position: p.sharedPosition, - BuiltIn: true, - } -} - -func (p parser) parseUnionTypeDefinition(typeVale *FullType) *ast.Definition { - unions := make([]string, 0, len(typeVale.PossibleTypes)) - for _, unionValue := range typeVale.PossibleTypes { - unions = append(unions, *unionValue.Name) - } - - return &ast.Definition{ - Kind: ast.Union, - Description: pointerString(typeVale.Description), - Name: pointerString(typeVale.Name), - Types: unions, - Position: p.sharedPosition, - BuiltIn: true, - } -} - -func (p parser) parseEnumTypeDefinition(typeVale *FullType) *ast.Definition { - enums := make(ast.EnumValueList, 0, len(typeVale.EnumValues)) - for _, enum := range typeVale.EnumValues { - enumValue := &ast.EnumValueDefinition{ - Description: pointerString(enum.Description), - Name: enum.Name, - Position: p.sharedPosition, - } - enums = append(enums, enumValue) - } - - return &ast.Definition{ - Kind: ast.Enum, - Description: pointerString(typeVale.Description), - Name: pointerString(typeVale.Name), - EnumValues: enums, - Position: p.sharedPosition, - BuiltIn: true, - } -} - -func (p parser) parseScalarTypeExtension(typeVale *FullType) *ast.Definition { - return &ast.Definition{ - Kind: ast.Scalar, - Description: pointerString(typeVale.Description), - Name: pointerString(typeVale.Name), - Position: p.sharedPosition, - BuiltIn: true, - } -} - -func (p parser) parseTypeSystemDefinition(typeVale *FullType) *ast.Definition { - switch typeVale.Kind { - case TypeKindScalar: - return p.parseScalarTypeExtension(typeVale) - case TypeKindInterface: - return p.parseInterfaceTypeDefinition(typeVale) - case TypeKindEnum: - return p.parseEnumTypeDefinition(typeVale) - case TypeKindUnion: - return p.parseUnionTypeDefinition(typeVale) - case TypeKindObject: - return p.parseObjectTypeDefinition(typeVale) - case TypeKindInputObject: - return p.parseInputObjectTypeDefinition(typeVale) - case TypeKindList, TypeKindNonNull: - panic(fmt.Sprintf("not match Kind: %s", typeVale.Kind)) - } - - panic(fmt.Sprintf("not match Kind: %s", typeVale.Kind)) -} - -func (p parser) buildInputValue(input *InputValue) *ast.ArgumentDefinition { - typ := p.getType(&input.Type) - - var defaultValue *ast.Value - if input.DefaultValue != nil { - defaultValue = &ast.Value{ - Raw: pointerString(input.DefaultValue), - Kind: ast.Variable, - Position: p.sharedPosition, - } - } - - return &ast.ArgumentDefinition{ - Description: pointerString(input.Description), - Name: input.Name, - DefaultValue: defaultValue, - Type: typ, - Position: p.sharedPosition, - } -} - -func (p parser) getType(typeRef *TypeRef) *ast.Type { - if typeRef.Kind == TypeKindList { - itemRef := typeRef.OfType - if itemRef == nil { - panic("Decorated type deeper than introspection query.") - } - - return ast.ListType(p.getType(itemRef), p.sharedPosition) - } - - if typeRef.Kind == TypeKindNonNull { - nullableRef := typeRef.OfType - if nullableRef == nil { - panic("Decorated type deeper than introspection query.") - } - nullableType := p.getType(nullableRef) - nullableType.NonNull = true - - return nullableType - } - - return ast.NamedType(pointerString(typeRef.Name), p.sharedPosition) -} - -func pointerString(s *string) string { - if s == nil { - return "" - } - - return *s -} diff --git a/vendor/github.com/Yamashou/gqlgenc/introspection/query.go b/vendor/github.com/Yamashou/gqlgenc/introspection/query.go deleted file mode 100644 index 7bd126ac247..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/introspection/query.go +++ /dev/null @@ -1,93 +0,0 @@ -package introspection - -const Introspection = `query Query { - __schema { - queryType { name } - mutationType { name } - subscriptionType { name } - types { - ...FullType - } - directives { - name - description - locations - args { - ...InputValue - } - } - } - } - - fragment FullType on __Type { - kind - name - description - fields(includeDeprecated: true) { - name - description - args { - ...InputValue - } - type { - ...TypeRef - } - isDeprecated - deprecationReason - } - inputFields { - ...InputValue - } - interfaces { - ...TypeRef - } - enumValues(includeDeprecated: true) { - name - description - isDeprecated - deprecationReason - } - possibleTypes { - ...TypeRef - } - } - - fragment InputValue on __InputValue { - name - description - type { ...TypeRef } - defaultValue - } - - fragment TypeRef on __Type { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - } - } - } - } - } - } - } - }` diff --git a/vendor/github.com/Yamashou/gqlgenc/introspection/type.go b/vendor/github.com/Yamashou/gqlgenc/introspection/type.go deleted file mode 100644 index 789f72bf758..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/introspection/type.go +++ /dev/null @@ -1,80 +0,0 @@ -package introspection - -type TypeKind string - -const ( - TypeKindScalar TypeKind = "SCALAR" - TypeKindObject TypeKind = "OBJECT" - TypeKindInterface TypeKind = "INTERFACE" - TypeKindUnion TypeKind = "UNION" - TypeKindEnum TypeKind = "ENUM" - TypeKindInputObject TypeKind = "INPUT_OBJECT" - TypeKindList TypeKind = "LIST" - TypeKindNonNull TypeKind = "NON_NULL" -) - -type FullTypes []*FullType - -func (fs FullTypes) NameMap() map[string]*FullType { - typeMap := make(map[string]*FullType) - for _, typ := range fs { - typeMap[*typ.Name] = typ - } - - return typeMap -} - -type FullType struct { - Kind TypeKind - Name *string - Description *string - Fields []*FieldValue - InputFields []*InputValue - Interfaces []*TypeRef - EnumValues []*struct { - Name string - Description *string - IsDeprecated bool - DeprecationReason *string - } - PossibleTypes []*TypeRef -} - -type FieldValue struct { - Name string - Description *string - Args []*InputValue - Type TypeRef - IsDeprecated bool - DeprecationReason *string -} - -type InputValue struct { - Name string - Description *string - Type TypeRef - DefaultValue *string -} - -type TypeRef struct { - Kind TypeKind - Name *string - OfType *TypeRef -} - -type Query struct { - Schema struct { - QueryType struct{ Name *string } - MutationType *struct{ Name *string } - SubscriptionType *struct{ Name *string } - Types FullTypes - Directives []*DirectiveType - } `graphql:"__schema"` -} - -type DirectiveType struct { - Name string - Description *string - Locations []string - Args []*InputValue -} diff --git a/vendor/github.com/Yamashou/gqlgenc/main.go b/vendor/github.com/Yamashou/gqlgenc/main.go deleted file mode 100644 index 2f3d5a8471e..00000000000 --- a/vendor/github.com/Yamashou/gqlgenc/main.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "context" - "fmt" - "os" - - "github.com/99designs/gqlgen/api" - "github.com/Yamashou/gqlgenc/clientgen" - "github.com/Yamashou/gqlgenc/clientgenv2" - "github.com/Yamashou/gqlgenc/config" - "github.com/Yamashou/gqlgenc/generator" -) - -func main() { - ctx := context.Background() - cfg, err := config.LoadConfigFromDefaultLocations() - if err != nil { - fmt.Fprintf(os.Stderr, "%+v", err.Error()) - os.Exit(2) - } - - clientGen := api.AddPlugin(clientgen.New(cfg.Query, cfg.Client, cfg.Generate)) - if cfg.Generate != nil { - if cfg.Generate.ClientV2 { - clientGen = api.AddPlugin(clientgenv2.New(cfg.Query, cfg.Client, cfg.Generate)) - } - } - - if err := generator.Generate(ctx, cfg, clientGen); err != nil { - fmt.Fprintf(os.Stderr, "%+v", err.Error()) - os.Exit(4) - } -} diff --git a/vendor/github.com/agnivade/levenshtein/.gitignore b/vendor/github.com/agnivade/levenshtein/.gitignore deleted file mode 100644 index 345780a4444..00000000000 --- a/vendor/github.com/agnivade/levenshtein/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -coverage.txt -fuzz/fuzz-fuzz.zip -fuzz/corpus/corpus/* -fuzz/corpus/suppressions/* -fuzz/corpus/crashes/* diff --git a/vendor/github.com/agnivade/levenshtein/.travis.yml b/vendor/github.com/agnivade/levenshtein/.travis.yml deleted file mode 100644 index 0873fa983fb..00000000000 --- a/vendor/github.com/agnivade/levenshtein/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: go - -# See https://travis-ci.community/t/goos-js-goarch-wasm-go-run-fails-panic-newosproc-not-implemented/1651 -#addons: -# chrome: stable - -before_install: -- export GO111MODULE=on - -#install: -#- go get github.com/agnivade/wasmbrowsertest -#- mv $GOPATH/bin/wasmbrowsertest $GOPATH/bin/go_js_wasm_exec -#- export PATH=$GOPATH/bin:$PATH - -go: -- 1.13.x -- 1.14.x -- 1.15.x -- tip - -script: -#- GOOS=js GOARCH=wasm go test -v -- go test -v diff --git a/vendor/github.com/agnivade/levenshtein/License.txt b/vendor/github.com/agnivade/levenshtein/License.txt deleted file mode 100644 index 54b51f49938..00000000000 --- a/vendor/github.com/agnivade/levenshtein/License.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Agniva De Sarker - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/agnivade/levenshtein/Makefile b/vendor/github.com/agnivade/levenshtein/Makefile deleted file mode 100644 index 5f6890d6132..00000000000 --- a/vendor/github.com/agnivade/levenshtein/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -all: test install - -install: - go install - -lint: - gofmt -l -s -w . && go vet . && golint -set_exit_status=1 . - -test: # The first 2 go gets are to support older Go versions - go get github.com/arbovm/levenshtein - go get github.com/dgryski/trifles/leven - GO111MODULE=on go test -race -v -coverprofile=coverage.txt -covermode=atomic - -bench: - go test -run=XXX -bench=. -benchmem -count=5 diff --git a/vendor/github.com/agnivade/levenshtein/README.md b/vendor/github.com/agnivade/levenshtein/README.md deleted file mode 100644 index 13c52a2101a..00000000000 --- a/vendor/github.com/agnivade/levenshtein/README.md +++ /dev/null @@ -1,80 +0,0 @@ -levenshtein [![Build Status](https://travis-ci.org/agnivade/levenshtein.svg?branch=master)](https://travis-ci.org/agnivade/levenshtein) [![Go Report Card](https://goreportcard.com/badge/github.com/agnivade/levenshtein)](https://goreportcard.com/report/github.com/agnivade/levenshtein) [![PkgGoDev](https://pkg.go.dev/badge/github.com/agnivade/levenshtein)](https://pkg.go.dev/github.com/agnivade/levenshtein) -=========== - -[Go](http://golang.org) package to calculate the [Levenshtein Distance](http://en.wikipedia.org/wiki/Levenshtein_distance) - -The library is fully capable of working with non-ascii strings. But the strings are not normalized. That is left as a user-dependant use case. Please normalize the strings before passing it to the library if you have such a requirement. -- https://blog.golang.org/normalization - -#### Limitation - -As a performance optimization, the library can handle strings only up to 65536 characters (runes). If you need to handle strings larger than that, please pin to version 1.0.3. - -Install -------- - - go get github.com/agnivade/levenshtein - -Example -------- - -```go -package main - -import ( - "fmt" - "github.com/agnivade/levenshtein" -) - -func main() { - s1 := "kitten" - s2 := "sitting" - distance := levenshtein.ComputeDistance(s1, s2) - fmt.Printf("The distance between %s and %s is %d.\n", s1, s2, distance) - // Output: - // The distance between kitten and sitting is 3. -} - -``` - -Benchmarks ----------- - -``` -name time/op -Simple/ASCII-4 330ns ± 2% -Simple/French-4 617ns ± 2% -Simple/Nordic-4 1.16µs ± 4% -Simple/Tibetan-4 1.05µs ± 1% - -name alloc/op -Simple/ASCII-4 96.0B ± 0% -Simple/French-4 128B ± 0% -Simple/Nordic-4 192B ± 0% -Simple/Tibetan-4 144B ± 0% - -name allocs/op -Simple/ASCII-4 1.00 ± 0% -Simple/French-4 1.00 ± 0% -Simple/Nordic-4 1.00 ± 0% -Simple/Tibetan-4 1.00 ± 0% -``` - -Comparisons with other libraries --------------------------------- - -``` -name time/op -Leven/ASCII/agniva-4 353ns ± 1% -Leven/ASCII/arbovm-4 485ns ± 1% -Leven/ASCII/dgryski-4 395ns ± 0% -Leven/French/agniva-4 648ns ± 1% -Leven/French/arbovm-4 791ns ± 0% -Leven/French/dgryski-4 682ns ± 0% -Leven/Nordic/agniva-4 1.28µs ± 1% -Leven/Nordic/arbovm-4 1.52µs ± 1% -Leven/Nordic/dgryski-4 1.32µs ± 1% -Leven/Tibetan/agniva-4 1.12µs ± 1% -Leven/Tibetan/arbovm-4 1.31µs ± 0% -Leven/Tibetan/dgryski-4 1.16µs ± 0% -``` diff --git a/vendor/github.com/agnivade/levenshtein/levenshtein.go b/vendor/github.com/agnivade/levenshtein/levenshtein.go deleted file mode 100644 index f727a66fe71..00000000000 --- a/vendor/github.com/agnivade/levenshtein/levenshtein.go +++ /dev/null @@ -1,89 +0,0 @@ -// Package levenshtein is a Go implementation to calculate Levenshtein Distance. -// -// Implementation taken from -// https://gist.github.com/andrei-m/982927#gistcomment-1931258 -package levenshtein - -import "unicode/utf8" - -// minLengthThreshold is the length of the string beyond which -// an allocation will be made. Strings smaller than this will be -// zero alloc. -const minLengthThreshold = 32 - -// ComputeDistance computes the levenshtein distance between the two -// strings passed as an argument. The return value is the levenshtein distance -// -// Works on runes (Unicode code points) but does not normalize -// the input strings. See https://blog.golang.org/normalization -// and the golang.org/x/text/unicode/norm package. -func ComputeDistance(a, b string) int { - if len(a) == 0 { - return utf8.RuneCountInString(b) - } - - if len(b) == 0 { - return utf8.RuneCountInString(a) - } - - if a == b { - return 0 - } - - // We need to convert to []rune if the strings are non-ASCII. - // This could be avoided by using utf8.RuneCountInString - // and then doing some juggling with rune indices, - // but leads to far more bounds checks. It is a reasonable trade-off. - s1 := []rune(a) - s2 := []rune(b) - - // swap to save some memory O(min(a,b)) instead of O(a) - if len(s1) > len(s2) { - s1, s2 = s2, s1 - } - lenS1 := len(s1) - lenS2 := len(s2) - - // Init the row. - var x []uint16 - if lenS1+1 > minLengthThreshold { - x = make([]uint16, lenS1+1) - } else { - // We make a small optimization here for small strings. - // Because a slice of constant length is effectively an array, - // it does not allocate. So we can re-slice it to the right length - // as long as it is below a desired threshold. - x = make([]uint16, minLengthThreshold) - x = x[:lenS1+1] - } - - // we start from 1 because index 0 is already 0. - for i := 1; i < len(x); i++ { - x[i] = uint16(i) - } - - // make a dummy bounds check to prevent the 2 bounds check down below. - // The one inside the loop is particularly costly. - _ = x[lenS1] - // fill in the rest - for i := 1; i <= lenS2; i++ { - prev := uint16(i) - for j := 1; j <= lenS1; j++ { - current := x[j-1] // match - if s2[i-1] != s1[j-1] { - current = min(min(x[j-1]+1, prev+1), x[j]+1) - } - x[j-1] = prev - prev = current - } - x[lenS1] = prev - } - return int(x[lenS1]) -} - -func min(a, b uint16) uint16 { - if a < b { - return a - } - return b -} diff --git a/vendor/github.com/anacrolix/dms/LICENSE b/vendor/github.com/anacrolix/dms/LICENSE deleted file mode 100644 index 3b827a441d5..00000000000 --- a/vendor/github.com/anacrolix/dms/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2012, Matt Joiner . -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 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 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. \ No newline at end of file diff --git a/vendor/github.com/anacrolix/dms/dlna/dlna.go b/vendor/github.com/anacrolix/dms/dlna/dlna.go deleted file mode 100644 index 07f5880f272..00000000000 --- a/vendor/github.com/anacrolix/dms/dlna/dlna.go +++ /dev/null @@ -1,102 +0,0 @@ -package dlna - -import ( - "fmt" - "strings" - "time" -) - -const ( - TimeSeekRangeDomain = "TimeSeekRange.dlna.org" - ContentFeaturesDomain = "contentFeatures.dlna.org" - TransferModeDomain = "transferMode.dlna.org" -) - -type ContentFeatures struct { - ProfileName string - SupportTimeSeek bool - SupportRange bool - // Play speeds, DLNA.ORG_PS would go here if supported. - Transcoded bool -} - -func BinaryInt(b bool) uint { - if b { - return 1 - } else { - return 0 - } -} - -// flags are in hex. trailing 24 zeroes, 26 are after the space -// "DLNA.ORG_OP=" time-seek-range-supp bytes-range-header-supp -func (cf ContentFeatures) String() (ret string) { - //DLNA.ORG_PN=[a-zA-Z0-9_]* - params := make([]string, 0, 2) - if cf.ProfileName != "" { - params = append(params, "DLNA.ORG_PN="+cf.ProfileName) - } - params = append(params, fmt.Sprintf( - "DLNA.ORG_OP=%b%b;DLNA.ORG_CI=%b", - BinaryInt(cf.SupportTimeSeek), - BinaryInt(cf.SupportRange), - BinaryInt(cf.Transcoded))) - return strings.Join(params, ";") -} - -func ParseNPTTime(s string) (time.Duration, error) { - var h, m, sec, ms time.Duration - n, err := fmt.Sscanf(s, "%d:%2d:%2d.%3d", &h, &m, &sec, &ms) - if err != nil { - return -1, err - } - if n < 3 { - return -1, fmt.Errorf("invalid npt time: %s", s) - } - ret := time.Duration(h) * time.Hour - ret += time.Duration(m) * time.Minute - ret += sec * time.Second - ret += ms * time.Millisecond - return ret, nil -} - -func FormatNPTTime(npt time.Duration) string { - npt /= time.Millisecond - ms := npt % 1000 - npt /= 1000 - s := npt % 60 - npt /= 60 - m := npt % 60 - npt /= 60 - h := npt - return fmt.Sprintf("%02d:%02d:%02d.%03d", h, m, s, ms) -} - -type NPTRange struct { - Start, End time.Duration -} - -func ParseNPTRange(s string) (ret NPTRange, err error) { - ss := strings.SplitN(s, "-", 2) - if ss[0] != "" { - ret.Start, err = ParseNPTTime(ss[0]) - if err != nil { - return - } - } - if ss[1] != "" { - ret.End, err = ParseNPTTime(ss[1]) - if err != nil { - return - } - } - return -} - -func (me NPTRange) String() (ret string) { - ret = me.Start.String() + "-" - if me.End >= 0 { - ret += me.End.String() - } - return -} diff --git a/vendor/github.com/anacrolix/dms/soap/soap.go b/vendor/github.com/anacrolix/dms/soap/soap.go deleted file mode 100644 index 5424bc855e9..00000000000 --- a/vendor/github.com/anacrolix/dms/soap/soap.go +++ /dev/null @@ -1,68 +0,0 @@ -package soap - -import ( - "encoding/xml" -) - -const ( - EncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" - EnvelopeNS = "http://schemas.xmlsoap.org/soap/envelope/" -) - -type Arg struct { - XMLName xml.Name - Value string `xml:",chardata"` -} - -type Action struct { - XMLName xml.Name - Args []Arg -} - -type Body struct { - Action []byte `xml:",innerxml"` -} - -type UPnPError struct { - XMLName xml.Name `xml:"urn:schemas-upnp-org:control-1-0 UPnPError"` - Code uint `xml:"errorCode"` - Desc string `xml:"errorDescription"` -} - -type FaultDetail struct { - XMLName xml.Name `xml:"detail"` - Data interface{} -} - -type Fault struct { - XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"` - FaultCode string `xml:"faultcode"` - FaultString string `xml:"faultstring"` - Detail FaultDetail `xml:"detail"` -} - -func NewFault(s string, detail interface{}) *Fault { - return &Fault{ - FaultCode: EnvelopeNS + ":Client", - FaultString: s, - Detail: FaultDetail{ - Data: detail, - }, - } -} - -type Envelope struct { - XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` - EncodingStyle string `xml:"encodingStyle,attr"` - Body Body `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` -} - -/* XML marshalling of nested namespaces is broken. - -func NewEnvelope(action []byte) Envelope { - return Envelope{ - EncodingStyle: EncodingStyle, - Body: Body{action}, - } -} -*/ diff --git a/vendor/github.com/anacrolix/dms/ssdp/ssdp.go b/vendor/github.com/anacrolix/dms/ssdp/ssdp.go deleted file mode 100644 index 5b03c709f0b..00000000000 --- a/vendor/github.com/anacrolix/dms/ssdp/ssdp.go +++ /dev/null @@ -1,330 +0,0 @@ -package ssdp - -import ( - "bufio" - "bytes" - "fmt" - "io" - "log" - "math/rand" - "net" - "net/http" - "net/textproto" - "strconv" - "strings" - "time" - - "golang.org/x/net/ipv4" -) - -const ( - AddrString = "239.255.255.250:1900" - rootDevice = "upnp:rootdevice" - aliveNTS = "ssdp:alive" - byebyeNTS = "ssdp:byebye" -) - -var ( - NetAddr *net.UDPAddr -) - -func init() { - var err error - NetAddr, err = net.ResolveUDPAddr("udp4", AddrString) - if err != nil { - log.Panicf("Could not resolve %s: %s", AddrString, err) - } -} - -type badStringError struct { - what string - str string -} - -func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) } - -func ReadRequest(b *bufio.Reader) (req *http.Request, err error) { - tp := textproto.NewReader(b) - var s string - if s, err = tp.ReadLine(); err != nil { - return nil, err - } - defer func() { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - }() - - var f []string - // TODO a split that only allows N values? - if f = strings.SplitN(s, " ", 3); len(f) < 3 { - return nil, &badStringError{"malformed request line", s} - } - if f[1] != "*" { - return nil, &badStringError{"bad URL request", f[1]} - } - req = &http.Request{ - Method: f[0], - } - var ok bool - if req.ProtoMajor, req.ProtoMinor, ok = http.ParseHTTPVersion(strings.TrimSpace(f[2])); !ok { - return nil, &badStringError{"malformed HTTP version", f[2]} - } - - mimeHeader, err := tp.ReadMIMEHeader() - if err != nil { - return nil, err - } - req.Header = http.Header(mimeHeader) - return -} - -type Server struct { - conn *net.UDPConn - Interface net.Interface - Server string - Services []string - Devices []string - Location func(net.IP) string - UUID string - NotifyInterval time.Duration - closed chan struct{} -} - -func makeConn(ifi net.Interface) (ret *net.UDPConn, err error) { - ret, err = net.ListenMulticastUDP("udp", &ifi, NetAddr) - if err != nil { - return - } - p := ipv4.NewPacketConn(ret) - if err := p.SetMulticastTTL(2); err != nil { - log.Println(err) - } - if err := p.SetMulticastLoopback(true); err != nil { - log.Println(err) - } - return -} - -func (me *Server) serve() { - for { - b := make([]byte, me.Interface.MTU) - n, addr, err := me.conn.ReadFromUDP(b) - select { - case <-me.closed: - return - default: - } - if err != nil { - log.Printf("error reading from UDP socket: %s", err) - break - } - go me.handle(b[:n], addr) - } -} - -func (me *Server) Init() (err error) { - me.closed = make(chan struct{}) - me.conn, err = makeConn(me.Interface) - return -} - -func (me *Server) Close() { - close(me.closed) - me.sendByeBye() - me.conn.Close() -} - -func (me *Server) Serve() (err error) { - go me.serve() - for { - addrs, err := me.Interface.Addrs() - if err != nil { - return err - } - for _, addr := range addrs { - ip := func() net.IP { - switch val := addr.(type) { - case *net.IPNet: - return val.IP - case *net.IPAddr: - return val.IP - } - panic(fmt.Sprint("unexpected addr type:", addr)) - }() - extraHdrs := [][2]string{ - {"CACHE-CONTROL", fmt.Sprintf("max-age=%d", 5*me.NotifyInterval/2/time.Second)}, - {"LOCATION", me.Location(ip)}, - } - me.notifyAll(aliveNTS, extraHdrs) - } - time.Sleep(me.NotifyInterval) - } -} - -func (me *Server) usnFromTarget(target string) string { - if target == me.UUID { - return target - } - return me.UUID + "::" + target -} - -func (me *Server) makeNotifyMessage(target, nts string, extraHdrs [][2]string) []byte { - lines := [...][2]string{ - {"HOST", AddrString}, - {"NT", target}, - {"NTS", nts}, - {"SERVER", me.Server}, - {"USN", me.usnFromTarget(target)}, - } - buf := &bytes.Buffer{} - fmt.Fprint(buf, "NOTIFY * HTTP/1.1\r\n") - writeHdr := func(keyValue [2]string) { - fmt.Fprintf(buf, "%s: %s\r\n", keyValue[0], keyValue[1]) - } - for _, pair := range lines { - writeHdr(pair) - } - for _, pair := range extraHdrs { - writeHdr(pair) - } - fmt.Fprint(buf, "\r\n") - return buf.Bytes() -} - -func (me *Server) send(buf []byte, addr *net.UDPAddr) { - if n, err := me.conn.WriteToUDP(buf, addr); err != nil { - log.Printf("error writing to UDP socket: %s", err) - } else if n != len(buf) { - log.Printf("short write: %d/%d bytes", n, len(buf)) - } -} - -func (me *Server) delayedSend(delay time.Duration, buf []byte, addr *net.UDPAddr) { - go func() { - select { - case <-time.After(delay): - me.send(buf, addr) - case <-me.closed: - } - }() -} - -func (me *Server) log(args ...interface{}) { - args = append([]interface{}{me.Interface.Name + ":"}, args...) - log.Print(args...) -} - -func (me *Server) sendByeBye() { - for _, type_ := range me.allTypes() { - buf := me.makeNotifyMessage(type_, byebyeNTS, nil) - me.send(buf, NetAddr) - } -} - -func (me *Server) notifyAll(nts string, extraHdrs [][2]string) { - for _, type_ := range me.allTypes() { - buf := me.makeNotifyMessage(type_, nts, extraHdrs) - delay := time.Duration(rand.Int63n(int64(100 * time.Millisecond))) - me.delayedSend(delay, buf, NetAddr) - } -} - -func (me *Server) allTypes() (ret []string) { - for _, a := range [][]string{ - {rootDevice, me.UUID}, - me.Devices, - me.Services, - } { - ret = append(ret, a...) - } - return -} - -func (me *Server) handle(buf []byte, sender *net.UDPAddr) { - req, err := ReadRequest(bufio.NewReader(bytes.NewReader(buf))) - if err != nil { - log.Println(err) - return - } - if req.Method != "M-SEARCH" || req.Header.Get("man") != `"ssdp:discover"` { - return - } - var mx uint - if req.Header.Get("Host") == AddrString { - mxHeader := req.Header.Get("mx") - i, err := strconv.ParseUint(mxHeader, 0, 0) - if err != nil { - log.Printf("Invalid mx header %q: %s", mxHeader, err) - return - } - mx = uint(i) - } else { - mx = 1 - } - types := func(st string) []string { - if st == "ssdp:all" { - return me.allTypes() - } - for _, t := range me.allTypes() { - if t == st { - return []string{t} - } - } - return nil - }(req.Header.Get("st")) - for _, ip := range func() (ret []net.IP) { - addrs, err := me.Interface.Addrs() - if err != nil { - panic(err) - } - for _, addr := range addrs { - if ip, ok := func() (net.IP, bool) { - switch data := addr.(type) { - case *net.IPNet: - if data.Contains(sender.IP) { - return data.IP, true - } - return nil, false - case *net.IPAddr: - return data.IP, true - } - panic(addr) - }(); ok { - ret = append(ret, ip) - } - } - return - }() { - for _, type_ := range types { - resp := me.makeResponse(ip, type_, req) - delay := time.Duration(rand.Int63n(int64(time.Second) * int64(mx))) - me.delayedSend(delay, resp, sender) - } - } -} - -func (me *Server) makeResponse(ip net.IP, targ string, req *http.Request) (ret []byte) { - resp := &http.Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(http.Header), - Request: req, - } - for _, pair := range [...][2]string{ - {"CACHE-CONTROL", fmt.Sprintf("max-age=%d", 5*me.NotifyInterval/2/time.Second)}, - {"EXT", ""}, - {"LOCATION", me.Location(ip)}, - {"SERVER", me.Server}, - {"ST", targ}, - {"USN", me.usnFromTarget(targ)}, - } { - resp.Header.Set(pair[0], pair[1]) - } - buf := &bytes.Buffer{} - if err := resp.Write(buf); err != nil { - panic(err) - } - return buf.Bytes() -} diff --git a/vendor/github.com/anacrolix/dms/upnp/eventing.go b/vendor/github.com/anacrolix/dms/upnp/eventing.go deleted file mode 100644 index 11cd88df54b..00000000000 --- a/vendor/github.com/anacrolix/dms/upnp/eventing.go +++ /dev/null @@ -1,91 +0,0 @@ -package upnp - -import ( - "crypto/rand" - "encoding/xml" - "fmt" - "io" - "log" - "net/url" - "regexp" - "time" -) - -// TODO: Why use namespace prefixes in PropertySet et al? Because the spec -// uses them, and I believe the Golang standard library XML spec implementers -// incorrectly assume that you can get away with just xmlns="". - -// propertyset is the root element sent in an event callback. -type PropertySet struct { - XMLName struct{} `xml:"e:propertyset"` - Properties []Property - // This should be set to `"urn:schemas-upnp-org:event-1-0"`. - Space string `xml:"xmlns:e,attr"` -} - -// propertys provide namespacing to the contained variables. -type Property struct { - XMLName struct{} `xml:"e:property"` - Variable Variable -} - -// Represents an evented state variable that has sendEvents="yes" in its -// service spec. -type Variable struct { - XMLName xml.Name - Value string `xml:",chardata"` -} - -type subscriber struct { - sid string - nextSeq uint32 // 0 for initial event, wraps from Uint32Max to 1. - urls []*url.URL - expiry time.Time -} - -// Intended to eventually be an embeddable implementation for managing -// eventing for a service. Not complete. -type Eventing struct { - subscribers map[string]*subscriber -} - -func (me *Eventing) Subscribe(callback []*url.URL, timeoutSeconds int) (sid string, actualTimeout int, err error) { - var uuid [16]byte - io.ReadFull(rand.Reader, uuid[:]) - sid = FormatUUID(uuid[:]) - if _, ok := me.subscribers[sid]; ok { - err = fmt.Errorf("already subscribed: %s", sid) - return - } - ssr := &subscriber{ - sid: sid, - urls: callback, - expiry: time.Now().Add(time.Duration(timeoutSeconds) * time.Second), - } - if me.subscribers == nil { - me.subscribers = make(map[string]*subscriber) - } - me.subscribers[sid] = ssr - actualTimeout = int(ssr.expiry.Sub(time.Now()) / time.Second) - return -} - -func (me *Eventing) Unsubscribe(sid string) error { - return nil -} - -var callbackURLRegexp = regexp.MustCompile("<(.*?)>") - -// Parse the CALLBACK HTTP header in an event subscription request. See UPnP -// Device Architecture 4.1.2. -func ParseCallbackURLs(callback string) (ret []*url.URL) { - for _, match := range callbackURLRegexp.FindAllStringSubmatch(callback, -1) { - _url, err := url.Parse(match[1]) - if err != nil { - log.Printf("bad callback url: %q", match[1]) - continue - } - ret = append(ret, _url) - } - return -} diff --git a/vendor/github.com/anacrolix/dms/upnp/upnp.go b/vendor/github.com/anacrolix/dms/upnp/upnp.go deleted file mode 100644 index eef9295f9f2..00000000000 --- a/vendor/github.com/anacrolix/dms/upnp/upnp.go +++ /dev/null @@ -1,162 +0,0 @@ -package upnp - -import ( - "encoding/xml" - "errors" - "fmt" - "log" - "regexp" - "strconv" - "strings" -) - -var serviceURNRegexp *regexp.Regexp = regexp.MustCompile(`^urn:schemas-upnp-org:service:(\w+):(\d+)$`) - -type ServiceURN struct { - Type string - Version uint64 -} - -func (me ServiceURN) String() string { - return fmt.Sprintf("urn:schemas-upnp-org:service:%s:%d", me.Type, me.Version) -} - -func ParseServiceType(s string) (ret ServiceURN, err error) { - matches := serviceURNRegexp.FindStringSubmatch(s) - if matches == nil { - err = errors.New(s) - return - } - if len(matches) != 3 { - log.Panicf("Invalid serviceURNRegexp ?") - } - ret.Type = matches[1] - ret.Version, err = strconv.ParseUint(matches[2], 0, 0) - return -} - -type SoapAction struct { - ServiceURN - Action string -} - -func ParseActionHTTPHeader(s string) (ret SoapAction, err error) { - if len(s) < 3 { - return - } - if s[0] != '"' || s[len(s)-1] != '"' { - return - } - s = s[1 : len(s)-1] - hashIndex := strings.LastIndex(s, "#") - if hashIndex == -1 { - return - } - ret.Action = s[hashIndex+1:] - ret.ServiceURN, err = ParseServiceType(s[:hashIndex]) - return -} - -type SpecVersion struct { - Major int `xml:"major"` - Minor int `xml:"minor"` -} - -type Icon struct { - Mimetype string `xml:"mimetype"` - Width int `xml:"width"` - Height int `xml:"height"` - Depth int `xml:"depth"` - URL string `xml:"url"` -} - -type Service struct { - XMLName xml.Name `xml:"service"` - ServiceType string `xml:"serviceType"` - ServiceId string `xml:"serviceId"` - SCPDURL string - ControlURL string `xml:"controlURL"` - EventSubURL string `xml:"eventSubURL"` -} - -type Device struct { - DeviceType string `xml:"deviceType"` - FriendlyName string `xml:"friendlyName"` - Manufacturer string `xml:"manufacturer"` - ModelName string `xml:"modelName"` - UDN string - IconList []Icon `xml:"iconList>icon"` - ServiceList []Service `xml:"serviceList>service"` -} - -type DeviceDesc struct { - XMLName xml.Name `xml:"urn:schemas-upnp-org:device-1-0 root"` - SpecVersion SpecVersion `xml:"specVersion"` - Device Device `xml:"device"` -} - -type Error struct { - XMLName xml.Name `xml:"urn:schemas-upnp-org:control-1-0 UPnPError"` - Code uint `xml:"errorCode"` - Desc string `xml:"errorDescription"` -} - -func (e *Error) Error() string { - return fmt.Sprintf("%d %s", e.Code, e.Desc) -} - -const ( - InvalidActionErrorCode = 401 - ActionFailedErrorCode = 501 - ArgumentValueInvalidErrorCode = 600 -) - -var ( - InvalidActionError = Errorf(401, "Invalid Action") - ArgumentValueInvalidError = Errorf(600, "The argument value is invalid") -) - -// Errorf creates an UPNP error from the given code and description -func Errorf(code uint, tpl string, args ...interface{}) *Error { - return &Error{Code: code, Desc: fmt.Sprintf(tpl, args...)} -} - -// ConvertError converts any error to an UPNP error -func ConvertError(err error) *Error { - if err == nil { - return nil - } - if e, ok := err.(*Error); ok { - return e - } - return Errorf(ActionFailedErrorCode, err.Error()) -} - -type Action struct { - Name string - Arguments []Argument -} - -type Argument struct { - Name string - Direction string - RelatedStateVar string -} - -type SCPD struct { - XMLName xml.Name `xml:"urn:schemas-upnp-org:service-1-0 scpd"` - SpecVersion SpecVersion `xml:"specVersion"` - ActionList []Action `xml:"actionList>action"` - ServiceStateTable []StateVariable `xml:"serviceStateTable>stateVariable"` -} - -type StateVariable struct { - SendEvents string `xml:"sendEvents,attr"` - Name string `xml:"name"` - DataType string `xml:"dataType"` - AllowedValues *[]string `xml:"allowedValueList>allowedValue,omitempty"` -} - -func FormatUUID(buf []byte) string { - return fmt.Sprintf("uuid:%x-%x-%x-%x-%x", buf[:4], buf[4:6], buf[6:8], buf[8:10], buf[10:16]) -} diff --git a/vendor/github.com/anacrolix/dms/upnpav/upnpav.go b/vendor/github.com/anacrolix/dms/upnpav/upnpav.go deleted file mode 100644 index 2ba7f8adec6..00000000000 --- a/vendor/github.com/anacrolix/dms/upnpav/upnpav.go +++ /dev/null @@ -1,45 +0,0 @@ -package upnpav - -import ( - "encoding/xml" -) - -const ( - NoSuchObjectErrorCode = 701 -) - -type Resource struct { - XMLName xml.Name `xml:"res"` - ProtocolInfo string `xml:"protocolInfo,attr"` - URL string `xml:",chardata"` - Size uint64 `xml:"size,attr,omitempty"` - Bitrate uint `xml:"bitrate,attr,omitempty"` - Duration string `xml:"duration,attr,omitempty"` - Resolution string `xml:"resolution,attr,omitempty"` -} - -type Container struct { - Object - XMLName xml.Name `xml:"container"` - ChildCount int `xml:"childCount,attr"` -} - -type Item struct { - Object - XMLName xml.Name `xml:"item"` - Res []Resource -} - -type Object struct { - ID string `xml:"id,attr"` - ParentID string `xml:"parentID,attr"` - Restricted int `xml:"restricted,attr"` // indicates whether the object is modifiable - Class string `xml:"upnp:class"` - Icon string `xml:"upnp:icon,omitempty"` - Title string `xml:"dc:title"` - Artist string `xml:"upnp:artist,omitempty"` - Album string `xml:"upnp:album,omitempty"` - Genre string `xml:"upnp:genre,omitempty"` - AlbumArtURI string `xml:"upnp:albumArtURI,omitempty"` - Searchable int `xml:"searchable,attr"` -} diff --git a/vendor/github.com/antchfx/htmlquery/.gitignore b/vendor/github.com/antchfx/htmlquery/.gitignore deleted file mode 100644 index 4d5d27b1d3a..00000000000 --- a/vendor/github.com/antchfx/htmlquery/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# vscode -.vscode -debug -*.test - -./build - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof \ No newline at end of file diff --git a/vendor/github.com/antchfx/htmlquery/.travis.yml b/vendor/github.com/antchfx/htmlquery/.travis.yml deleted file mode 100644 index 86da84abe6c..00000000000 --- a/vendor/github.com/antchfx/htmlquery/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: go - -go: - - 1.9.x - - 1.12.x - - 1.13.x - -install: - - go get golang.org/x/net/html/charset - - go get golang.org/x/net/html - - go get github.com/antchfx/xpath - - go get github.com/mattn/goveralls - - go get github.com/golang/groupcache - -script: - - $HOME/gopath/bin/goveralls -service=travis-ci \ No newline at end of file diff --git a/vendor/github.com/antchfx/htmlquery/LICENSE b/vendor/github.com/antchfx/htmlquery/LICENSE deleted file mode 100644 index e14c37141c5..00000000000 --- a/vendor/github.com/antchfx/htmlquery/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/antchfx/htmlquery/README.md b/vendor/github.com/antchfx/htmlquery/README.md deleted file mode 100644 index 5eb290d0cdc..00000000000 --- a/vendor/github.com/antchfx/htmlquery/README.md +++ /dev/null @@ -1,163 +0,0 @@ -htmlquery -==== -[![Build Status](https://travis-ci.org/antchfx/htmlquery.svg?branch=master)](https://travis-ci.org/antchfx/htmlquery) -[![Coverage Status](https://coveralls.io/repos/github/antchfx/htmlquery/badge.svg?branch=master)](https://coveralls.io/github/antchfx/htmlquery?branch=master) -[![GoDoc](https://godoc.org/github.com/antchfx/htmlquery?status.svg)](https://godoc.org/github.com/antchfx/htmlquery) -[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/htmlquery)](https://goreportcard.com/report/github.com/antchfx/htmlquery) - -Overview -==== - -`htmlquery` is an XPath query package for HTML, lets you extract data or evaluate from HTML documents by an XPath expression. - -`htmlquery` built-in the query object caching feature based on [LRU](https://godoc.org/github.com/golang/groupcache/lru), this feature will caching the recently used XPATH query string. Enable query caching can avoid re-compile XPath expression each query. - -You can visit this page to learn about the supported XPath(1.0/2.0) syntax. https://github.com/antchfx/xpath - -XPath query packages for Go -=== -| Name | Description | -| ------------------------------------------------- | ----------------------------------------- | -| [htmlquery](https://github.com/antchfx/htmlquery) | XPath query package for the HTML document | -| [xmlquery](https://github.com/antchfx/xmlquery) | XPath query package for the XML document | -| [jsonquery](https://github.com/antchfx/jsonquery) | XPath query package for the JSON document | - -Installation -==== - -``` -go get github.com/antchfx/htmlquery -``` - -Getting Started -==== - -#### Query, returns matched elements or error. - -```go -nodes, err := htmlquery.QueryAll(doc, "//a") -if err != nil { - panic(`not a valid XPath expression.`) -} -``` - -#### Load HTML document from URL. - -```go -doc, err := htmlquery.LoadURL("http://example.com/") -``` - -#### Load HTML from document. - -```go -filePath := "/home/user/sample.html" -doc, err := htmlquery.LoadDoc(filePath) -``` - -#### Load HTML document from string. - -```go -s := `....` -doc, err := htmlquery.Parse(strings.NewReader(s)) -``` - -#### Find all A elements. - -```go -list := htmlquery.Find(doc, "//a") -``` - -#### Find all A elements that have `href` attribute. - -```go -list := htmlquery.Find(doc, "//a[@href]") -``` - -#### Find all A elements with `href` attribute and only return `href` value. - -```go -list := htmlquery.Find(doc, "//a/@href") -for _ , n := range list{ - fmt.Println(htmlquery.SelectAttr(n, "href")) // output @href value -} -``` - -### Find the third A element. - -```go -a := htmlquery.FindOne(doc, "//a[3]") -``` - -### Find children element (img) under A `href` and print the source -```go -a := htmlquery.FindOne(doc, "//a") -img := htmlquery.FindOne(a, "//img") -fmt.Prinln(htmlquery.SelectAttr(img, "src")) // output @src value -``` - -#### Evaluate the number of all IMG element. - -```go -expr, _ := xpath.Compile("count(//img)") -v := expr.Evaluate(htmlquery.CreateXPathNavigator(doc)).(float64) -fmt.Printf("total count is %f", v) -``` - - -Quick Starts -=== - -```go -func main() { - doc, err := htmlquery.LoadURL("https://www.bing.com/search?q=golang") - if err != nil { - panic(err) - } - // Find all news item. - list, err := htmlquery.QueryAll(doc, "//ol/li") - if err != nil { - panic(err) - } - for i, n := range list { - a := htmlquery.FindOne(n, "//a") - if a != nil { - fmt.Printf("%d %s(%s)\n", i, htmlquery.InnerText(a), htmlquery.SelectAttr(a, "href")) - } - } -} -``` - - -FAQ -==== - -#### `Find()` vs `QueryAll()`, which is better? - -`Find` and `QueryAll` both do the same things, searches all of matched html nodes. -The `Find` will panics if you give an error XPath query, but `QueryAll` will return an error for you. - -#### Can I save my query expression object for the next query? - -Yes, you can. We offer the `QuerySelector` and `QuerySelectorAll` methods, It will accept your query expression object. - -Cache a query expression object(or reused) will avoid re-compile XPath query expression, improve your query performance. - -#### XPath query object cache performance - -``` -goos: windows -goarch: amd64 -pkg: github.com/antchfx/htmlquery -BenchmarkSelectorCache-4 20000000 55.2 ns/op -BenchmarkDisableSelectorCache-4 500000 3162 ns/op -``` - -#### How to disable caching? - -``` -htmlquery.DisableSelectorCache = true -``` - -Questions -=== -Please let me know if you have any questions. diff --git a/vendor/github.com/antchfx/htmlquery/cache.go b/vendor/github.com/antchfx/htmlquery/cache.go deleted file mode 100644 index e27cd289741..00000000000 --- a/vendor/github.com/antchfx/htmlquery/cache.go +++ /dev/null @@ -1,42 +0,0 @@ -package htmlquery - -import ( - "sync" - - "github.com/antchfx/xpath" - "github.com/golang/groupcache/lru" -) - -// DisableSelectorCache will disable caching for the query selector if value is true. -var DisableSelectorCache = false - -// SelectorCacheMaxEntries allows how many selector object can be caching. Default is 50. -// Will disable caching if SelectorCacheMaxEntries <= 0. -var SelectorCacheMaxEntries = 50 - -var ( - cacheOnce sync.Once - cache *lru.Cache - cacheMutex sync.Mutex -) - -func getQuery(expr string) (*xpath.Expr, error) { - if DisableSelectorCache || SelectorCacheMaxEntries <= 0 { - return xpath.Compile(expr) - } - cacheOnce.Do(func() { - cache = lru.New(SelectorCacheMaxEntries) - }) - cacheMutex.Lock() - defer cacheMutex.Unlock() - if v, ok := cache.Get(expr); ok { - return v.(*xpath.Expr), nil - } - v, err := xpath.Compile(expr) - if err != nil { - return nil, err - } - cache.Add(expr, v) - return v, nil - -} diff --git a/vendor/github.com/antchfx/htmlquery/query.go b/vendor/github.com/antchfx/htmlquery/query.go deleted file mode 100644 index f6742f5486c..00000000000 --- a/vendor/github.com/antchfx/htmlquery/query.go +++ /dev/null @@ -1,346 +0,0 @@ -/* -Package htmlquery provides extract data from HTML documents using XPath expression. -*/ -package htmlquery - -import ( - "bufio" - "bytes" - "fmt" - "io" - "net/http" - "os" - - "github.com/antchfx/xpath" - "golang.org/x/net/html" - "golang.org/x/net/html/charset" -) - -var _ xpath.NodeNavigator = &NodeNavigator{} - -// CreateXPathNavigator creates a new xpath.NodeNavigator for the specified html.Node. -func CreateXPathNavigator(top *html.Node) *NodeNavigator { - return &NodeNavigator{curr: top, root: top, attr: -1} -} - -// Find is like QueryAll but Will panics if the expression `expr` cannot be parsed. -// -// See `QueryAll()` function. -func Find(top *html.Node, expr string) []*html.Node { - nodes, err := QueryAll(top, expr) - if err != nil { - panic(err) - } - return nodes -} - -// FindOne is like Query but will panics if the expression `expr` cannot be parsed. -// See `Query()` function. -func FindOne(top *html.Node, expr string) *html.Node { - node, err := Query(top, expr) - if err != nil { - panic(err) - } - return node -} - -// QueryAll searches the html.Node that matches by the specified XPath expr. -// Return an error if the expression `expr` cannot be parsed. -func QueryAll(top *html.Node, expr string) ([]*html.Node, error) { - exp, err := getQuery(expr) - if err != nil { - return nil, err - } - nodes := QuerySelectorAll(top, exp) - return nodes, nil -} - -// Query runs the given XPath expression against the given html.Node and -// returns the first matching html.Node, or nil if no matches are found. -// -// Returns an error if the expression `expr` cannot be parsed. -func Query(top *html.Node, expr string) (*html.Node, error) { - exp, err := getQuery(expr) - if err != nil { - return nil, err - } - return QuerySelector(top, exp), nil -} - -// QuerySelector returns the first matched html.Node by the specified XPath selector. -func QuerySelector(top *html.Node, selector *xpath.Expr) *html.Node { - t := selector.Select(CreateXPathNavigator(top)) - if t.MoveNext() { - return getCurrentNode(t.Current().(*NodeNavigator)) - } - return nil -} - -// QuerySelectorAll searches all of the html.Node that matches the specified XPath selectors. -func QuerySelectorAll(top *html.Node, selector *xpath.Expr) []*html.Node { - var elems []*html.Node - t := selector.Select(CreateXPathNavigator(top)) - for t.MoveNext() { - nav := t.Current().(*NodeNavigator) - n := getCurrentNode(nav) - elems = append(elems, n) - } - return elems -} - -// LoadURL loads the HTML document from the specified URL. -func LoadURL(url string) (*html.Node, error) { - resp, err := http.Get(url) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - r, err := charset.NewReader(resp.Body, resp.Header.Get("Content-Type")) - if err != nil { - return nil, err - } - return html.Parse(r) -} - -// LoadDoc loads the HTML document from the specified file path. -func LoadDoc(path string) (*html.Node, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - - return html.Parse(bufio.NewReader(f)) -} - -func getCurrentNode(n *NodeNavigator) *html.Node { - if n.NodeType() == xpath.AttributeNode { - childNode := &html.Node{ - Type: html.TextNode, - Data: n.Value(), - } - return &html.Node{ - Type: html.ElementNode, - Data: n.LocalName(), - FirstChild: childNode, - LastChild: childNode, - } - - } - return n.curr -} - -// Parse returns the parse tree for the HTML from the given Reader. -func Parse(r io.Reader) (*html.Node, error) { - return html.Parse(r) -} - -// InnerText returns the text between the start and end tags of the object. -func InnerText(n *html.Node) string { - var output func(*bytes.Buffer, *html.Node) - output = func(buf *bytes.Buffer, n *html.Node) { - switch n.Type { - case html.TextNode: - buf.WriteString(n.Data) - return - case html.CommentNode: - return - } - for child := n.FirstChild; child != nil; child = child.NextSibling { - output(buf, child) - } - } - - var buf bytes.Buffer - output(&buf, n) - return buf.String() -} - -// SelectAttr returns the attribute value with the specified name. -func SelectAttr(n *html.Node, name string) (val string) { - if n == nil { - return - } - if n.Type == html.ElementNode && n.Parent == nil && name == n.Data { - return InnerText(n) - } - for _, attr := range n.Attr { - if attr.Key == name { - val = attr.Val - break - } - } - return -} - -// ExistsAttr returns whether attribute with specified name exists. -func ExistsAttr(n *html.Node, name string) bool { - if n == nil { - return false - } - for _, attr := range n.Attr { - if attr.Key == name { - return true - } - } - return false -} - -// OutputHTML returns the text including tags name. -func OutputHTML(n *html.Node, self bool) string { - var buf bytes.Buffer - if self { - html.Render(&buf, n) - } else { - for n := n.FirstChild; n != nil; n = n.NextSibling { - html.Render(&buf, n) - } - } - return buf.String() -} - -type NodeNavigator struct { - root, curr *html.Node - attr int -} - -func (h *NodeNavigator) Current() *html.Node { - return h.curr -} - -func (h *NodeNavigator) NodeType() xpath.NodeType { - switch h.curr.Type { - case html.CommentNode: - return xpath.CommentNode - case html.TextNode: - return xpath.TextNode - case html.DocumentNode: - return xpath.RootNode - case html.ElementNode: - if h.attr != -1 { - return xpath.AttributeNode - } - return xpath.ElementNode - case html.DoctypeNode: - // ignored declare and as Root-Node type. - return xpath.RootNode - } - panic(fmt.Sprintf("unknown HTML node type: %v", h.curr.Type)) -} - -func (h *NodeNavigator) LocalName() string { - if h.attr != -1 { - return h.curr.Attr[h.attr].Key - } - return h.curr.Data -} - -func (*NodeNavigator) Prefix() string { - return "" -} - -func (h *NodeNavigator) Value() string { - switch h.curr.Type { - case html.CommentNode: - return h.curr.Data - case html.ElementNode: - if h.attr != -1 { - return h.curr.Attr[h.attr].Val - } - return InnerText(h.curr) - case html.TextNode: - return h.curr.Data - } - return "" -} - -func (h *NodeNavigator) Copy() xpath.NodeNavigator { - n := *h - return &n -} - -func (h *NodeNavigator) MoveToRoot() { - h.curr = h.root -} - -func (h *NodeNavigator) MoveToParent() bool { - if h.attr != -1 { - h.attr = -1 - return true - } else if node := h.curr.Parent; node != nil { - h.curr = node - return true - } - return false -} - -func (h *NodeNavigator) MoveToNextAttribute() bool { - if h.attr >= len(h.curr.Attr)-1 { - return false - } - h.attr++ - return true -} - -func (h *NodeNavigator) MoveToChild() bool { - if h.attr != -1 { - return false - } - if node := h.curr.FirstChild; node != nil { - h.curr = node - return true - } - return false -} - -func (h *NodeNavigator) MoveToFirst() bool { - if h.attr != -1 || h.curr.PrevSibling == nil { - return false - } - for { - node := h.curr.PrevSibling - if node == nil { - break - } - h.curr = node - } - return true -} - -func (h *NodeNavigator) String() string { - return h.Value() -} - -func (h *NodeNavigator) MoveToNext() bool { - if h.attr != -1 { - return false - } - if node := h.curr.NextSibling; node != nil { - h.curr = node - return true - } - return false -} - -func (h *NodeNavigator) MoveToPrevious() bool { - if h.attr != -1 { - return false - } - if node := h.curr.PrevSibling; node != nil { - h.curr = node - return true - } - return false -} - -func (h *NodeNavigator) MoveTo(other xpath.NodeNavigator) bool { - node, ok := other.(*NodeNavigator) - if !ok || node.root != h.root { - return false - } - - h.curr = node.curr - h.attr = node.attr - return true -} diff --git a/vendor/github.com/antchfx/xpath/.gitignore b/vendor/github.com/antchfx/xpath/.gitignore deleted file mode 100644 index 4d5d27b1d3a..00000000000 --- a/vendor/github.com/antchfx/xpath/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# vscode -.vscode -debug -*.test - -./build - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof \ No newline at end of file diff --git a/vendor/github.com/antchfx/xpath/.travis.yml b/vendor/github.com/antchfx/xpath/.travis.yml deleted file mode 100644 index 6b63957a8c1..00000000000 --- a/vendor/github.com/antchfx/xpath/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go - -go: - - 1.6 - - 1.9 - - '1.10' - -install: - - go get github.com/mattn/goveralls - -script: - - $HOME/gopath/bin/goveralls -service=travis-ci \ No newline at end of file diff --git a/vendor/github.com/antchfx/xpath/LICENSE b/vendor/github.com/antchfx/xpath/LICENSE deleted file mode 100644 index e14c37141c5..00000000000 --- a/vendor/github.com/antchfx/xpath/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/antchfx/xpath/README.md b/vendor/github.com/antchfx/xpath/README.md deleted file mode 100644 index 9a58a9fc38e..00000000000 --- a/vendor/github.com/antchfx/xpath/README.md +++ /dev/null @@ -1,173 +0,0 @@ -XPath -==== -[![GoDoc](https://godoc.org/github.com/antchfx/xpath?status.svg)](https://godoc.org/github.com/antchfx/xpath) -[![Coverage Status](https://coveralls.io/repos/github/antchfx/xpath/badge.svg?branch=master)](https://coveralls.io/github/antchfx/xpath?branch=master) -[![Build Status](https://travis-ci.org/antchfx/xpath.svg?branch=master)](https://travis-ci.org/antchfx/xpath) -[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/xpath)](https://goreportcard.com/report/github.com/antchfx/xpath) - -XPath is Go package provides selecting nodes from XML, HTML or other documents using XPath expression. - -Implementation -=== - -- [htmlquery](https://github.com/antchfx/htmlquery) - an XPath query package for HTML document - -- [xmlquery](https://github.com/antchfx/xmlquery) - an XPath query package for XML document. - -- [jsonquery](https://github.com/antchfx/jsonquery) - an XPath query package for JSON document - -Supported Features -=== - -#### The basic XPath patterns. - -> The basic XPath patterns cover 90% of the cases that most stylesheets will need. - -- `node` : Selects all child elements with nodeName of node. - -- `*` : Selects all child elements. - -- `@attr` : Selects the attribute attr. - -- `@*` : Selects all attributes. - -- `node()` : Matches an org.w3c.dom.Node. - -- `text()` : Matches a org.w3c.dom.Text node. - -- `comment()` : Matches a comment. - -- `.` : Selects the current node. - -- `..` : Selects the parent of current node. - -- `/` : Selects the document node. - -- `a[expr]` : Select only those nodes matching a which also satisfy the expression expr. - -- `a[n]` : Selects the nth matching node matching a When a filter's expression is a number, XPath selects based on position. - -- `a/b` : For each node matching a, add the nodes matching b to the result. - -- `a//b` : For each node matching a, add the descendant nodes matching b to the result. - -- `//b` : Returns elements in the entire document matching b. - -- `a|b` : All nodes matching a or b, union operation(not boolean or). - -- `(a, b, c)` : Evaluates each of its operands and concatenates the resulting sequences, in order, into a single result sequence - - -#### Node Axes - -- `child::*` : The child axis selects children of the current node. - -- `descendant::*` : The descendant axis selects descendants of the current node. It is equivalent to '//'. - -- `descendant-or-self::*` : Selects descendants including the current node. - -- `attribute::*` : Selects attributes of the current element. It is equivalent to @* - -- `following-sibling::*` : Selects nodes after the current node. - -- `preceding-sibling::*` : Selects nodes before the current node. - -- `following::*` : Selects the first matching node following in document order, excluding descendants. - -- `preceding::*` : Selects the first matching node preceding in document order, excluding ancestors. - -- `parent::*` : Selects the parent if it matches. The '..' pattern from the core is equivalent to 'parent::node()'. - -- `ancestor::*` : Selects matching ancestors. - -- `ancestor-or-self::*` : Selects ancestors including the current node. - -- `self::*` : Selects the current node. '.' is equivalent to 'self::node()'. - -#### Expressions - - The gxpath supported three types: number, boolean, string. - -- `path` : Selects nodes based on the path. - -- `a = b` : Standard comparisons. - - * a = b True if a equals b. - * a != b True if a is not equal to b. - * a < b True if a is less than b. - * a <= b True if a is less than or equal to b. - * a > b True if a is greater than b. - * a >= b True if a is greater than or equal to b. - -- `a + b` : Arithmetic expressions. - - * `- a` Unary minus - * a + b Add - * a - b Substract - * a * b Multiply - * a div b Divide - * a mod b Floating point mod, like Java. - -- `a or b` : Boolean `or` operation. - -- `a and b` : Boolean `and` operation. - -- `(expr)` : Parenthesized expressions. - -- `fun(arg1, ..., argn)` : Function calls: - -| Function | Supported | -| --- | --- | -`boolean()`| ✓ | -`ceiling()`| ✓ | -`choose()`| ✗ | -`concat()`| ✓ | -`contains()`| ✓ | -`count()`| ✓ | -`current()`| ✗ | -`document()`| ✗ | -`element-available()`| ✗ | -`ends-with()`| ✓ | -`false()`| ✓ | -`floor()`| ✓ | -`format-number()`| ✗ | -`function-available()`| ✗ | -`generate-id()`| ✗ | -`id()`| ✗ | -`key()`| ✗ | -`lang()`| ✗ | -`last()`| ✓ | -`local-name()`| ✓ | -`matches()`| ✓ | -`name()`| ✓ | -`namespace-uri()`| ✓ | -`normalize-space()`| ✓ | -`not()`| ✓ | -`number()`| ✓ | -`position()`| ✓ | -`replace()`| ✓ | -`reverse()`| ✓ | -`round()`| ✓ | -`starts-with()`| ✓ | -`string()`| ✓ | -`string-length()`| ✓ | -`substring()`| ✓ | -`substring-after()`| ✓ | -`substring-before()`| ✓ | -`sum()`| ✓ | -`system-property()`| ✗ | -`translate()`| ✓ | -`true()`| ✓ | -`unparsed-entity-url()` | ✗ | - -Changelogs -=== - -2019-03-19 -- optimize XPath `|` operation performance. [#33](https://github.com/antchfx/xpath/issues/33). Tips: suggest split into multiple subquery if you have a lot of `|` operations. - -2019-01-29 -- improvement `normalize-space` function. [#32](https://github.com/antchfx/xpath/issues/32) - -2018-12-07 -- supports XPath 2.0 Sequence expressions. [#30](https://github.com/antchfx/xpath/pull/30) by [@minherz](https://github.com/minherz). \ No newline at end of file diff --git a/vendor/github.com/antchfx/xpath/build.go b/vendor/github.com/antchfx/xpath/build.go deleted file mode 100644 index 58d8f316e48..00000000000 --- a/vendor/github.com/antchfx/xpath/build.go +++ /dev/null @@ -1,545 +0,0 @@ -package xpath - -import ( - "errors" - "fmt" -) - -type flag int - -const ( - noneFlag flag = iota - filterFlag -) - -// builder provides building an XPath expressions. -type builder struct { - depth int - flag flag - firstInput query -} - -// axisPredicate creates a predicate to predicating for this axis node. -func axisPredicate(root *axisNode) func(NodeNavigator) bool { - // get current axix node type. - typ := ElementNode - switch root.AxeType { - case "attribute": - typ = AttributeNode - case "self", "parent": - typ = allNode - default: - switch root.Prop { - case "comment": - typ = CommentNode - case "text": - typ = TextNode - // case "processing-instruction": - // typ = ProcessingInstructionNode - case "node": - typ = allNode - } - } - nametest := root.LocalName != "" || root.Prefix != "" - predicate := func(n NodeNavigator) bool { - if typ == n.NodeType() || typ == allNode || typ == TextNode { - if nametest { - if root.LocalName == n.LocalName() && root.Prefix == n.Prefix() { - return true - } - } else { - return true - } - } - return false - } - - return predicate -} - -// processAxisNode processes a query for the XPath axis node. -func (b *builder) processAxisNode(root *axisNode) (query, error) { - var ( - err error - qyInput query - qyOutput query - predicate = axisPredicate(root) - ) - - if root.Input == nil { - qyInput = &contextQuery{} - } else { - if root.AxeType == "child" && (root.Input.Type() == nodeAxis) { - if input := root.Input.(*axisNode); input.AxeType == "descendant-or-self" { - var qyGrandInput query - if input.Input != nil { - qyGrandInput, _ = b.processNode(input.Input) - } else { - qyGrandInput = &contextQuery{} - } - // fix #20: https://github.com/antchfx/htmlquery/issues/20 - filter := func(n NodeNavigator) bool { - v := predicate(n) - switch root.Prop { - case "text": - v = v && n.NodeType() == TextNode - case "comment": - v = v && n.NodeType() == CommentNode - } - return v - } - qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: true} - return qyOutput, nil - } - } - qyInput, err = b.processNode(root.Input) - if err != nil { - return nil, err - } - } - - switch root.AxeType { - case "ancestor": - qyOutput = &ancestorQuery{Input: qyInput, Predicate: predicate} - case "ancestor-or-self": - qyOutput = &ancestorQuery{Input: qyInput, Predicate: predicate, Self: true} - case "attribute": - qyOutput = &attributeQuery{Input: qyInput, Predicate: predicate} - case "child": - filter := func(n NodeNavigator) bool { - v := predicate(n) - switch root.Prop { - case "text": - v = v && n.NodeType() == TextNode - case "node": - v = v && (n.NodeType() == ElementNode || n.NodeType() == TextNode) - case "comment": - v = v && n.NodeType() == CommentNode - } - return v - } - qyOutput = &childQuery{Input: qyInput, Predicate: filter} - case "descendant": - qyOutput = &descendantQuery{Input: qyInput, Predicate: predicate} - case "descendant-or-self": - qyOutput = &descendantQuery{Input: qyInput, Predicate: predicate, Self: true} - case "following": - qyOutput = &followingQuery{Input: qyInput, Predicate: predicate} - case "following-sibling": - qyOutput = &followingQuery{Input: qyInput, Predicate: predicate, Sibling: true} - case "parent": - qyOutput = &parentQuery{Input: qyInput, Predicate: predicate} - case "preceding": - qyOutput = &precedingQuery{Input: qyInput, Predicate: predicate} - case "preceding-sibling": - qyOutput = &precedingQuery{Input: qyInput, Predicate: predicate, Sibling: true} - case "self": - qyOutput = &selfQuery{Input: qyInput, Predicate: predicate} - case "namespace": - // haha,what will you do someting?? - default: - err = fmt.Errorf("unknown axe type: %s", root.AxeType) - return nil, err - } - return qyOutput, nil -} - -// processFilterNode builds query for the XPath filter predicate. -func (b *builder) processFilterNode(root *filterNode) (query, error) { - b.flag |= filterFlag - - qyInput, err := b.processNode(root.Input) - if err != nil { - return nil, err - } - qyCond, err := b.processNode(root.Condition) - if err != nil { - return nil, err - } - qyOutput := &filterQuery{Input: qyInput, Predicate: qyCond} - return qyOutput, nil -} - -// processFunctionNode processes query for the XPath function node. -func (b *builder) processFunctionNode(root *functionNode) (query, error) { - var qyOutput query - switch root.FuncName { - case "starts-with": - arg1, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - arg2, err := b.processNode(root.Args[1]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: startwithFunc(arg1, arg2)} - case "ends-with": - arg1, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - arg2, err := b.processNode(root.Args[1]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: endwithFunc(arg1, arg2)} - case "contains": - arg1, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - arg2, err := b.processNode(root.Args[1]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: containsFunc(arg1, arg2)} - case "matches": - //matches(string , pattern) - if len(root.Args) != 2 { - return nil, errors.New("xpath: matches function must have two parameters") - } - var ( - arg1, arg2 query - err error - ) - if arg1, err = b.processNode(root.Args[0]); err != nil { - return nil, err - } - if arg2, err = b.processNode(root.Args[1]); err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: matchesFunc(arg1, arg2)} - case "substring": - //substring( string , start [, length] ) - if len(root.Args) < 2 { - return nil, errors.New("xpath: substring function must have at least two parameter") - } - var ( - arg1, arg2, arg3 query - err error - ) - if arg1, err = b.processNode(root.Args[0]); err != nil { - return nil, err - } - if arg2, err = b.processNode(root.Args[1]); err != nil { - return nil, err - } - if len(root.Args) == 3 { - if arg3, err = b.processNode(root.Args[2]); err != nil { - return nil, err - } - } - qyOutput = &functionQuery{Input: b.firstInput, Func: substringFunc(arg1, arg2, arg3)} - case "substring-before", "substring-after": - //substring-xxxx( haystack, needle ) - if len(root.Args) != 2 { - return nil, errors.New("xpath: substring-before function must have two parameters") - } - var ( - arg1, arg2 query - err error - ) - if arg1, err = b.processNode(root.Args[0]); err != nil { - return nil, err - } - if arg2, err = b.processNode(root.Args[1]); err != nil { - return nil, err - } - qyOutput = &functionQuery{ - Input: b.firstInput, - Func: substringIndFunc(arg1, arg2, root.FuncName == "substring-after"), - } - case "string-length": - // string-length( [string] ) - if len(root.Args) < 1 { - return nil, errors.New("xpath: string-length function must have at least one parameter") - } - arg1, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: stringLengthFunc(arg1)} - case "normalize-space": - if len(root.Args) == 0 { - return nil, errors.New("xpath: normalize-space function must have at least one parameter") - } - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: argQuery, Func: normalizespaceFunc} - case "replace": - //replace( string , string, string ) - if len(root.Args) != 3 { - return nil, errors.New("xpath: replace function must have three parameters") - } - var ( - arg1, arg2, arg3 query - err error - ) - if arg1, err = b.processNode(root.Args[0]); err != nil { - return nil, err - } - if arg2, err = b.processNode(root.Args[1]); err != nil { - return nil, err - } - if arg3, err = b.processNode(root.Args[2]); err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: replaceFunc(arg1, arg2, arg3)} - case "translate": - //translate( string , string, string ) - if len(root.Args) != 3 { - return nil, errors.New("xpath: translate function must have three parameters") - } - var ( - arg1, arg2, arg3 query - err error - ) - if arg1, err = b.processNode(root.Args[0]); err != nil { - return nil, err - } - if arg2, err = b.processNode(root.Args[1]); err != nil { - return nil, err - } - if arg3, err = b.processNode(root.Args[2]); err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: b.firstInput, Func: translateFunc(arg1, arg2, arg3)} - case "not": - if len(root.Args) == 0 { - return nil, errors.New("xpath: not function must have at least one parameter") - } - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: argQuery, Func: notFunc} - case "name", "local-name", "namespace-uri": - if len(root.Args) > 1 { - return nil, fmt.Errorf("xpath: %s function must have at most one parameter", root.FuncName) - } - var ( - arg query - err error - ) - if len(root.Args) == 1 { - arg, err = b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - } - switch root.FuncName { - case "name": - qyOutput = &functionQuery{Input: b.firstInput, Func: nameFunc(arg)} - case "local-name": - qyOutput = &functionQuery{Input: b.firstInput, Func: localNameFunc(arg)} - case "namespace-uri": - qyOutput = &functionQuery{Input: b.firstInput, Func: namespaceFunc(arg)} - } - case "true", "false": - val := root.FuncName == "true" - qyOutput = &functionQuery{ - Input: b.firstInput, - Func: func(_ query, _ iterator) interface{} { - return val - }, - } - case "last": - qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc} - case "position": - qyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc} - case "boolean", "number", "string": - inp := b.firstInput - if len(root.Args) > 1 { - return nil, fmt.Errorf("xpath: %s function must have at most one parameter", root.FuncName) - } - if len(root.Args) == 1 { - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - inp = argQuery - } - f := &functionQuery{Input: inp} - switch root.FuncName { - case "boolean": - f.Func = booleanFunc - case "string": - f.Func = stringFunc - case "number": - f.Func = numberFunc - } - qyOutput = f - case "count": - //if b.firstInput == nil { - // return nil, errors.New("xpath: expression must evaluate to node-set") - //} - if len(root.Args) == 0 { - return nil, fmt.Errorf("xpath: count(node-sets) function must with have parameters node-sets") - } - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: argQuery, Func: countFunc} - case "sum": - if len(root.Args) == 0 { - return nil, fmt.Errorf("xpath: sum(node-sets) function must with have parameters node-sets") - } - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - qyOutput = &functionQuery{Input: argQuery, Func: sumFunc} - case "ceiling", "floor", "round": - if len(root.Args) == 0 { - return nil, fmt.Errorf("xpath: ceiling(node-sets) function must with have parameters node-sets") - } - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - f := &functionQuery{Input: argQuery} - switch root.FuncName { - case "ceiling": - f.Func = ceilingFunc - case "floor": - f.Func = floorFunc - case "round": - f.Func = roundFunc - } - qyOutput = f - case "concat": - if len(root.Args) < 2 { - return nil, fmt.Errorf("xpath: concat() must have at least two arguments") - } - var args []query - for _, v := range root.Args { - q, err := b.processNode(v) - if err != nil { - return nil, err - } - args = append(args, q) - } - qyOutput = &functionQuery{Input: b.firstInput, Func: concatFunc(args...)} - case "reverse": - if len(root.Args) == 0 { - return nil, fmt.Errorf("xpath: reverse(node-sets) function must with have parameters node-sets") - } - argQuery, err := b.processNode(root.Args[0]) - if err != nil { - return nil, err - } - qyOutput = &transformFunctionQuery{Input: argQuery, Func: reverseFunc} - default: - return nil, fmt.Errorf("not yet support this function %s()", root.FuncName) - } - return qyOutput, nil -} - -func (b *builder) processOperatorNode(root *operatorNode) (query, error) { - left, err := b.processNode(root.Left) - if err != nil { - return nil, err - } - right, err := b.processNode(root.Right) - if err != nil { - return nil, err - } - var qyOutput query - switch root.Op { - case "+", "-", "*", "div", "mod": // Numeric operator - var exprFunc func(interface{}, interface{}) interface{} - switch root.Op { - case "+": - exprFunc = plusFunc - case "-": - exprFunc = minusFunc - case "*": - exprFunc = mulFunc - case "div": - exprFunc = divFunc - case "mod": - exprFunc = modFunc - } - qyOutput = &numericQuery{Left: left, Right: right, Do: exprFunc} - case "=", ">", ">=", "<", "<=", "!=": - var exprFunc func(iterator, interface{}, interface{}) interface{} - switch root.Op { - case "=": - exprFunc = eqFunc - case ">": - exprFunc = gtFunc - case ">=": - exprFunc = geFunc - case "<": - exprFunc = ltFunc - case "<=": - exprFunc = leFunc - case "!=": - exprFunc = neFunc - } - qyOutput = &logicalQuery{Left: left, Right: right, Do: exprFunc} - case "or", "and": - isOr := false - if root.Op == "or" { - isOr = true - } - qyOutput = &booleanQuery{Left: left, Right: right, IsOr: isOr} - case "|": - qyOutput = &unionQuery{Left: left, Right: right} - } - return qyOutput, nil -} - -func (b *builder) processNode(root node) (q query, err error) { - if b.depth = b.depth + 1; b.depth > 1024 { - err = errors.New("the xpath expressions is too complex") - return - } - - switch root.Type() { - case nodeConstantOperand: - n := root.(*operandNode) - q = &constantQuery{Val: n.Val} - case nodeRoot: - q = &contextQuery{Root: true} - case nodeAxis: - q, err = b.processAxisNode(root.(*axisNode)) - b.firstInput = q - case nodeFilter: - q, err = b.processFilterNode(root.(*filterNode)) - case nodeFunction: - q, err = b.processFunctionNode(root.(*functionNode)) - case nodeOperator: - q, err = b.processOperatorNode(root.(*operatorNode)) - case nodeGroup: - q, err = b.processNode(root.(*groupNode).Input) - if err != nil { - return - } - q = &groupQuery{Input: q} - } - return -} - -// build builds a specified XPath expressions expr. -func build(expr string) (q query, err error) { - defer func() { - if e := recover(); e != nil { - switch x := e.(type) { - case string: - err = errors.New(x) - case error: - err = x - default: - err = errors.New("unknown panic") - } - } - }() - root := parse(expr) - b := &builder{} - return b.processNode(root) -} diff --git a/vendor/github.com/antchfx/xpath/cache.go b/vendor/github.com/antchfx/xpath/cache.go deleted file mode 100644 index 31a2b335656..00000000000 --- a/vendor/github.com/antchfx/xpath/cache.go +++ /dev/null @@ -1,80 +0,0 @@ -package xpath - -import ( - "regexp" - "sync" -) - -type loadFunc func(key interface{}) (interface{}, error) - -const ( - defaultCap = 65536 -) - -// The reason we're building a simple capacity-resetting loading cache (when capacity reached) instead of using -// something like github.com/hashicorp/golang-lru is primarily due to (not wanting to create) external dependency. -// Currently this library has 0 external dep (other than go sdk), and supports go 1.6, 1.9, and 1.10 (and later). -// Creating external lib dependencies (plus their transitive dependencies) would make things hard if not impossible. -// We expect under most circumstances, the defaultCap is big enough for any long running services that use this -// library if their xpath regexp cardinality is low. However, in extreme cases when the capacity is reached, we -// simply reset the cache, taking a small subsequent perf hit (next to nothing considering amortization) in trade -// of more complex and less performant LRU type of construct. -type loadingCache struct { - sync.RWMutex - cap int - load loadFunc - m map[interface{}]interface{} - reset int -} - -// NewLoadingCache creates a new instance of a loading cache with capacity. Capacity must be >= 0, or -// it will panic. Capacity == 0 means the cache growth is unbounded. -func NewLoadingCache(load loadFunc, capacity int) *loadingCache { - if capacity < 0 { - panic("capacity must be >= 0") - } - return &loadingCache{cap: capacity, load: load, m: make(map[interface{}]interface{})} -} - -func (c *loadingCache) get(key interface{}) (interface{}, error) { - c.RLock() - v, found := c.m[key] - c.RUnlock() - if found { - return v, nil - } - v, err := c.load(key) - if err != nil { - return nil, err - } - c.Lock() - if c.cap > 0 && len(c.m) >= c.cap { - c.m = map[interface{}]interface{}{key: v} - c.reset++ - } else { - c.m[key] = v - } - c.Unlock() - return v, nil -} - -var ( - // RegexpCache is a loading cache for string -> *regexp.Regexp mapping. It is exported so that in rare cases - // client can customize load func and/or capacity. - RegexpCache = defaultRegexpCache() -) - -func defaultRegexpCache() *loadingCache { - return NewLoadingCache( - func(key interface{}) (interface{}, error) { - return regexp.Compile(key.(string)) - }, defaultCap) -} - -func getRegexp(pattern string) (*regexp.Regexp, error) { - exp, err := RegexpCache.get(pattern) - if err != nil { - return nil, err - } - return exp.(*regexp.Regexp), nil -} diff --git a/vendor/github.com/antchfx/xpath/func.go b/vendor/github.com/antchfx/xpath/func.go deleted file mode 100644 index fd4187ba5a6..00000000000 --- a/vendor/github.com/antchfx/xpath/func.go +++ /dev/null @@ -1,614 +0,0 @@ -package xpath - -import ( - "errors" - "fmt" - "math" - "strconv" - "strings" - "sync" - "unicode" -) - -// Defined an interface of stringBuilder that compatible with -// strings.Builder(go 1.10) and bytes.Buffer(< go 1.10) -type stringBuilder interface { - WriteRune(r rune) (n int, err error) - WriteString(s string) (int, error) - Reset() - Grow(n int) - String() string -} - -var builderPool = sync.Pool{New: func() interface{} { - return newStringBuilder() -}} - -// The XPath function list. - -func predicate(q query) func(NodeNavigator) bool { - type Predicater interface { - Test(NodeNavigator) bool - } - if p, ok := q.(Predicater); ok { - return p.Test - } - return func(NodeNavigator) bool { return true } -} - -// positionFunc is a XPath Node Set functions position(). -func positionFunc(q query, t iterator) interface{} { - var ( - count = 1 - node = t.Current().Copy() - ) - test := predicate(q) - for node.MoveToPrevious() { - if test(node) { - count++ - } - } - return float64(count) -} - -// lastFunc is a XPath Node Set functions last(). -func lastFunc(q query, t iterator) interface{} { - var ( - count = 0 - node = t.Current().Copy() - ) - node.MoveToFirst() - test := predicate(q) - for { - if test(node) { - count++ - } - if !node.MoveToNext() { - break - } - } - return float64(count) -} - -// countFunc is a XPath Node Set functions count(node-set). -func countFunc(q query, t iterator) interface{} { - var count = 0 - q = functionArgs(q) - test := predicate(q) - switch typ := q.Evaluate(t).(type) { - case query: - for node := typ.Select(t); node != nil; node = typ.Select(t) { - if test(node) { - count++ - } - } - } - return float64(count) -} - -// sumFunc is a XPath Node Set functions sum(node-set). -func sumFunc(q query, t iterator) interface{} { - var sum float64 - switch typ := functionArgs(q).Evaluate(t).(type) { - case query: - for node := typ.Select(t); node != nil; node = typ.Select(t) { - if v, err := strconv.ParseFloat(node.Value(), 64); err == nil { - sum += v - } - } - case float64: - sum = typ - case string: - v, err := strconv.ParseFloat(typ, 64) - if err != nil { - panic(errors.New("sum() function argument type must be a node-set or number")) - } - sum = v - } - return sum -} - -func asNumber(t iterator, o interface{}) float64 { - switch typ := o.(type) { - case query: - node := typ.Select(t) - if node == nil { - return float64(0) - } - if v, err := strconv.ParseFloat(node.Value(), 64); err == nil { - return v - } - case float64: - return typ - case string: - v, err := strconv.ParseFloat(typ, 64) - if err != nil { - panic(errors.New("ceiling() function argument type must be a node-set or number")) - } - return v - } - return 0 -} - -// ceilingFunc is a XPath Node Set functions ceiling(node-set). -func ceilingFunc(q query, t iterator) interface{} { - val := asNumber(t, functionArgs(q).Evaluate(t)) - return math.Ceil(val) -} - -// floorFunc is a XPath Node Set functions floor(node-set). -func floorFunc(q query, t iterator) interface{} { - val := asNumber(t, functionArgs(q).Evaluate(t)) - return math.Floor(val) -} - -// roundFunc is a XPath Node Set functions round(node-set). -func roundFunc(q query, t iterator) interface{} { - val := asNumber(t, functionArgs(q).Evaluate(t)) - //return math.Round(val) - return round(val) -} - -// nameFunc is a XPath functions name([node-set]). -func nameFunc(arg query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var v NodeNavigator - if arg == nil { - v = t.Current() - } else { - v = arg.Clone().Select(t) - if v == nil { - return "" - } - } - ns := v.Prefix() - if ns == "" { - return v.LocalName() - } - return ns + ":" + v.LocalName() - } -} - -// localNameFunc is a XPath functions local-name([node-set]). -func localNameFunc(arg query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var v NodeNavigator - if arg == nil { - v = t.Current() - } else { - v = arg.Clone().Select(t) - if v == nil { - return "" - } - } - return v.LocalName() - } -} - -// namespaceFunc is a XPath functions namespace-uri([node-set]). -func namespaceFunc(arg query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var v NodeNavigator - if arg == nil { - v = t.Current() - } else { - // Get the first node in the node-set if specified. - v = arg.Clone().Select(t) - if v == nil { - return "" - } - } - // fix about namespace-uri() bug: https://github.com/antchfx/xmlquery/issues/22 - // TODO: In the next version, add NamespaceURL() to the NodeNavigator interface. - type namespaceURL interface { - NamespaceURL() string - } - if f, ok := v.(namespaceURL); ok { - return f.NamespaceURL() - } - return v.Prefix() - } -} - -func asBool(t iterator, v interface{}) bool { - switch v := v.(type) { - case nil: - return false - case *NodeIterator: - return v.MoveNext() - case bool: - return v - case float64: - return v != 0 - case string: - return v != "" - case query: - return v.Select(t) != nil - default: - panic(fmt.Errorf("unexpected type: %T", v)) - } -} - -func asString(t iterator, v interface{}) string { - switch v := v.(type) { - case nil: - return "" - case bool: - if v { - return "true" - } - return "false" - case float64: - return strconv.FormatFloat(v, 'g', -1, 64) - case string: - return v - case query: - node := v.Select(t) - if node == nil { - return "" - } - return node.Value() - default: - panic(fmt.Errorf("unexpected type: %T", v)) - } -} - -// booleanFunc is a XPath functions boolean([node-set]). -func booleanFunc(q query, t iterator) interface{} { - v := functionArgs(q).Evaluate(t) - return asBool(t, v) -} - -// numberFunc is a XPath functions number([node-set]). -func numberFunc(q query, t iterator) interface{} { - v := functionArgs(q).Evaluate(t) - return asNumber(t, v) -} - -// stringFunc is a XPath functions string([node-set]). -func stringFunc(q query, t iterator) interface{} { - v := functionArgs(q).Evaluate(t) - return asString(t, v) -} - -// startwithFunc is a XPath functions starts-with(string, string). -func startwithFunc(arg1, arg2 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var ( - m, n string - ok bool - ) - switch typ := functionArgs(arg1).Evaluate(t).(type) { - case string: - m = typ - case query: - node := typ.Select(t) - if node == nil { - return false - } - m = node.Value() - default: - panic(errors.New("starts-with() function argument type must be string")) - } - n, ok = functionArgs(arg2).Evaluate(t).(string) - if !ok { - panic(errors.New("starts-with() function argument type must be string")) - } - return strings.HasPrefix(m, n) - } -} - -// endwithFunc is a XPath functions ends-with(string, string). -func endwithFunc(arg1, arg2 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var ( - m, n string - ok bool - ) - switch typ := functionArgs(arg1).Evaluate(t).(type) { - case string: - m = typ - case query: - node := typ.Select(t) - if node == nil { - return false - } - m = node.Value() - default: - panic(errors.New("ends-with() function argument type must be string")) - } - n, ok = functionArgs(arg2).Evaluate(t).(string) - if !ok { - panic(errors.New("ends-with() function argument type must be string")) - } - return strings.HasSuffix(m, n) - } -} - -// containsFunc is a XPath functions contains(string or @attr, string). -func containsFunc(arg1, arg2 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var ( - m, n string - ok bool - ) - switch typ := functionArgs(arg1).Evaluate(t).(type) { - case string: - m = typ - case query: - node := typ.Select(t) - if node == nil { - return false - } - m = node.Value() - default: - panic(errors.New("contains() function argument type must be string")) - } - - n, ok = functionArgs(arg2).Evaluate(t).(string) - if !ok { - panic(errors.New("contains() function argument type must be string")) - } - - return strings.Contains(m, n) - } -} - -// matchesFunc is an XPath function that tests a given string against a regexp pattern. -// Note: does not support https://www.w3.org/TR/xpath-functions-31/#func-matches 3rd optional `flags` argument; if -// needed, directly put flags in the regexp pattern, such as `(?i)^pattern$` for `i` flag. -func matchesFunc(arg1, arg2 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var s string - switch typ := functionArgs(arg1).Evaluate(t).(type) { - case string: - s = typ - case query: - node := typ.Select(t) - if node == nil { - return "" - } - s = node.Value() - } - var pattern string - var ok bool - if pattern, ok = functionArgs(arg2).Evaluate(t).(string); !ok { - panic(errors.New("matches() function second argument type must be string")) - } - re, err := getRegexp(pattern) - if err != nil { - panic(fmt.Errorf("matches() function second argument is not a valid regexp pattern, err: %s", err.Error())) - } - return re.MatchString(s) - } -} - -// normalizespaceFunc is XPath functions normalize-space(string?) -func normalizespaceFunc(q query, t iterator) interface{} { - var m string - switch typ := functionArgs(q).Evaluate(t).(type) { - case string: - m = typ - case query: - node := typ.Select(t) - if node == nil { - return "" - } - m = node.Value() - } - var b = builderPool.Get().(stringBuilder) - b.Grow(len(m)) - - runeStr := []rune(strings.TrimSpace(m)) - l := len(runeStr) - for i := range runeStr { - r := runeStr[i] - isSpace := unicode.IsSpace(r) - if !(isSpace && (i+1 < l && unicode.IsSpace(runeStr[i+1]))) { - if isSpace { - r = ' ' - } - b.WriteRune(r) - } - } - result := b.String() - b.Reset() - builderPool.Put(b) - - return result -} - -// substringFunc is XPath functions substring function returns a part of a given string. -func substringFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var m string - switch typ := functionArgs(arg1).Evaluate(t).(type) { - case string: - m = typ - case query: - node := typ.Select(t) - if node == nil { - return "" - } - m = node.Value() - } - - var start, length float64 - var ok bool - - if start, ok = functionArgs(arg2).Evaluate(t).(float64); !ok { - panic(errors.New("substring() function first argument type must be int")) - } else if start < 1 { - panic(errors.New("substring() function first argument type must be >= 1")) - } - start-- - if arg3 != nil { - if length, ok = functionArgs(arg3).Evaluate(t).(float64); !ok { - panic(errors.New("substring() function second argument type must be int")) - } - } - if (len(m) - int(start)) < int(length) { - panic(errors.New("substring() function start and length argument out of range")) - } - if length > 0 { - return m[int(start):int(length+start)] - } - return m[int(start):] - } -} - -// substringIndFunc is XPath functions substring-before/substring-after function returns a part of a given string. -func substringIndFunc(arg1, arg2 query, after bool) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - var str string - switch v := functionArgs(arg1).Evaluate(t).(type) { - case string: - str = v - case query: - node := v.Select(t) - if node == nil { - return "" - } - str = node.Value() - } - var word string - switch v := functionArgs(arg2).Evaluate(t).(type) { - case string: - word = v - case query: - node := v.Select(t) - if node == nil { - return "" - } - word = node.Value() - } - if word == "" { - return "" - } - - i := strings.Index(str, word) - if i < 0 { - return "" - } - if after { - return str[i+len(word):] - } - return str[:i] - } -} - -// stringLengthFunc is XPATH string-length( [string] ) function that returns a number -// equal to the number of characters in a given string. -func stringLengthFunc(arg1 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - switch v := functionArgs(arg1).Evaluate(t).(type) { - case string: - return float64(len(v)) - case query: - node := v.Select(t) - if node == nil { - break - } - return float64(len(node.Value())) - } - return float64(0) - } -} - -// translateFunc is XPath functions translate() function returns a replaced string. -func translateFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - str := asString(t, functionArgs(arg1).Evaluate(t)) - src := asString(t, functionArgs(arg2).Evaluate(t)) - dst := asString(t, functionArgs(arg3).Evaluate(t)) - - replace := make([]string, 0, len(src)) - for i, s := range src { - d := "" - if i < len(dst) { - d = string(dst[i]) - } - replace = append(replace, string(s), d) - } - return strings.NewReplacer(replace...).Replace(str) - } -} - -// replaceFunc is XPath functions replace() function returns a replaced string. -func replaceFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - str := asString(t, functionArgs(arg1).Evaluate(t)) - src := asString(t, functionArgs(arg2).Evaluate(t)) - dst := asString(t, functionArgs(arg3).Evaluate(t)) - - return strings.Replace(str, src, dst, -1) - } -} - -// notFunc is XPATH functions not(expression) function operation. -func notFunc(q query, t iterator) interface{} { - switch v := functionArgs(q).Evaluate(t).(type) { - case bool: - return !v - case query: - node := v.Select(t) - return node == nil - default: - return false - } -} - -// concatFunc is the concat function concatenates two or more -// strings and returns the resulting string. -// concat( string1 , string2 [, stringn]* ) -func concatFunc(args ...query) func(query, iterator) interface{} { - return func(q query, t iterator) interface{} { - b := builderPool.Get().(stringBuilder) - for _, v := range args { - v = functionArgs(v) - - switch v := v.Evaluate(t).(type) { - case string: - b.WriteString(v) - case query: - node := v.Select(t) - if node != nil { - b.WriteString(node.Value()) - } - } - } - result := b.String() - b.Reset() - builderPool.Put(b) - - return result - } -} - -// https://github.com/antchfx/xpath/issues/43 -func functionArgs(q query) query { - if _, ok := q.(*functionQuery); ok { - return q - } - return q.Clone() -} - -func reverseFunc(q query, t iterator) func() NodeNavigator { - var list []NodeNavigator - for { - node := q.Select(t) - if node == nil { - break - } - list = append(list, node.Copy()) - } - i := len(list) - return func() NodeNavigator { - if i <= 0 { - return nil - } - i-- - node := list[i] - return node - } -} diff --git a/vendor/github.com/antchfx/xpath/func_go110.go b/vendor/github.com/antchfx/xpath/func_go110.go deleted file mode 100644 index 6df30d3d7c2..00000000000 --- a/vendor/github.com/antchfx/xpath/func_go110.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build go1.10 - -package xpath - -import ( - "math" - "strings" -) - -func round(f float64) int { - return int(math.Round(f)) -} - -func newStringBuilder() stringBuilder{ - return &strings.Builder{} -} diff --git a/vendor/github.com/antchfx/xpath/func_pre_go110.go b/vendor/github.com/antchfx/xpath/func_pre_go110.go deleted file mode 100644 index 335141f79f5..00000000000 --- a/vendor/github.com/antchfx/xpath/func_pre_go110.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build !go1.10 - -package xpath - -import ( - "bytes" - "math" -) - -// math.Round() is supported by Go 1.10+, -// This method just compatible for version <1.10. -// https://github.com/golang/go/issues/20100 -func round(f float64) int { - if math.Abs(f) < 0.5 { - return 0 - } - return int(f + math.Copysign(0.5, f)) -} - -func newStringBuilder() stringBuilder { - return &bytes.Buffer{} -} diff --git a/vendor/github.com/antchfx/xpath/operator.go b/vendor/github.com/antchfx/xpath/operator.go deleted file mode 100644 index 8c2f31f86c8..00000000000 --- a/vendor/github.com/antchfx/xpath/operator.go +++ /dev/null @@ -1,305 +0,0 @@ -package xpath - -import ( - "fmt" - "reflect" - "strconv" -) - -// The XPath number operator function list. - -// valueType is a return value type. -type valueType int - -const ( - booleanType valueType = iota - numberType - stringType - nodeSetType -) - -func getValueType(i interface{}) valueType { - v := reflect.ValueOf(i) - switch v.Kind() { - case reflect.Float64: - return numberType - case reflect.String: - return stringType - case reflect.Bool: - return booleanType - default: - if _, ok := i.(query); ok { - return nodeSetType - } - } - panic(fmt.Errorf("xpath unknown value type: %v", v.Kind())) -} - -type logical func(iterator, string, interface{}, interface{}) bool - -var logicalFuncs = [][]logical{ - {cmpBooleanBoolean, nil, nil, nil}, - {nil, cmpNumericNumeric, cmpNumericString, cmpNumericNodeSet}, - {nil, cmpStringNumeric, cmpStringString, cmpStringNodeSet}, - {nil, cmpNodeSetNumeric, cmpNodeSetString, cmpNodeSetNodeSet}, -} - -// number vs number -func cmpNumberNumberF(op string, a, b float64) bool { - switch op { - case "=": - return a == b - case ">": - return a > b - case "<": - return a < b - case ">=": - return a >= b - case "<=": - return a <= b - case "!=": - return a != b - } - return false -} - -// string vs string -func cmpStringStringF(op string, a, b string) bool { - switch op { - case "=": - return a == b - case ">": - return a > b - case "<": - return a < b - case ">=": - return a >= b - case "<=": - return a <= b - case "!=": - return a != b - } - return false -} - -func cmpBooleanBooleanF(op string, a, b bool) bool { - switch op { - case "or": - return a || b - case "and": - return a && b - } - return false -} - -func cmpNumericNumeric(t iterator, op string, m, n interface{}) bool { - a := m.(float64) - b := n.(float64) - return cmpNumberNumberF(op, a, b) -} - -func cmpNumericString(t iterator, op string, m, n interface{}) bool { - a := m.(float64) - b := n.(string) - num, err := strconv.ParseFloat(b, 64) - if err != nil { - panic(err) - } - return cmpNumberNumberF(op, a, num) -} - -func cmpNumericNodeSet(t iterator, op string, m, n interface{}) bool { - a := m.(float64) - b := n.(query) - - for { - node := b.Select(t) - if node == nil { - break - } - num, err := strconv.ParseFloat(node.Value(), 64) - if err != nil { - panic(err) - } - if cmpNumberNumberF(op, a, num) { - return true - } - } - return false -} - -func cmpNodeSetNumeric(t iterator, op string, m, n interface{}) bool { - a := m.(query) - b := n.(float64) - for { - node := a.Select(t) - if node == nil { - break - } - num, err := strconv.ParseFloat(node.Value(), 64) - if err != nil { - panic(err) - } - if cmpNumberNumberF(op, num, b) { - return true - } - } - return false -} - -func cmpNodeSetString(t iterator, op string, m, n interface{}) bool { - a := m.(query) - b := n.(string) - for { - node := a.Select(t) - if node == nil { - break - } - if cmpStringStringF(op, b, node.Value()) { - return true - } - } - return false -} - -func cmpNodeSetNodeSet(t iterator, op string, m, n interface{}) bool { - a := m.(query) - b := n.(query) - x := a.Select(t) - if x == nil { - return false - } - y := b.Select(t) - if y == nil { - return false - } - return cmpStringStringF(op, x.Value(), y.Value()) -} - -func cmpStringNumeric(t iterator, op string, m, n interface{}) bool { - a := m.(string) - b := n.(float64) - num, err := strconv.ParseFloat(a, 64) - if err != nil { - panic(err) - } - return cmpNumberNumberF(op, b, num) -} - -func cmpStringString(t iterator, op string, m, n interface{}) bool { - a := m.(string) - b := n.(string) - return cmpStringStringF(op, a, b) -} - -func cmpStringNodeSet(t iterator, op string, m, n interface{}) bool { - a := m.(string) - b := n.(query) - for { - node := b.Select(t) - if node == nil { - break - } - if cmpStringStringF(op, a, node.Value()) { - return true - } - } - return false -} - -func cmpBooleanBoolean(t iterator, op string, m, n interface{}) bool { - a := m.(bool) - b := n.(bool) - return cmpBooleanBooleanF(op, a, b) -} - -// eqFunc is an `=` operator. -func eqFunc(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, "=", m, n) -} - -// gtFunc is an `>` operator. -func gtFunc(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, ">", m, n) -} - -// geFunc is an `>=` operator. -func geFunc(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, ">=", m, n) -} - -// ltFunc is an `<` operator. -func ltFunc(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, "<", m, n) -} - -// leFunc is an `<=` operator. -func leFunc(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, "<=", m, n) -} - -// neFunc is an `!=` operator. -func neFunc(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, "!=", m, n) -} - -// orFunc is an `or` operator. -var orFunc = func(t iterator, m, n interface{}) interface{} { - t1 := getValueType(m) - t2 := getValueType(n) - return logicalFuncs[t1][t2](t, "or", m, n) -} - -func numericExpr(m, n interface{}, cb func(float64, float64) float64) float64 { - typ := reflect.TypeOf(float64(0)) - a := reflect.ValueOf(m).Convert(typ) - b := reflect.ValueOf(n).Convert(typ) - return cb(a.Float(), b.Float()) -} - -// plusFunc is an `+` operator. -var plusFunc = func(m, n interface{}) interface{} { - return numericExpr(m, n, func(a, b float64) float64 { - return a + b - }) -} - -// minusFunc is an `-` operator. -var minusFunc = func(m, n interface{}) interface{} { - return numericExpr(m, n, func(a, b float64) float64 { - return a - b - }) -} - -// mulFunc is an `*` operator. -var mulFunc = func(m, n interface{}) interface{} { - return numericExpr(m, n, func(a, b float64) float64 { - return a * b - }) -} - -// divFunc is an `DIV` operator. -var divFunc = func(m, n interface{}) interface{} { - return numericExpr(m, n, func(a, b float64) float64 { - return a / b - }) -} - -// modFunc is an 'MOD' operator. -var modFunc = func(m, n interface{}) interface{} { - return numericExpr(m, n, func(a, b float64) float64 { - return float64(int(a) % int(b)) - }) -} diff --git a/vendor/github.com/antchfx/xpath/parse.go b/vendor/github.com/antchfx/xpath/parse.go deleted file mode 100644 index acb0db9a7f7..00000000000 --- a/vendor/github.com/antchfx/xpath/parse.go +++ /dev/null @@ -1,1204 +0,0 @@ -package xpath - -import ( - "bytes" - "errors" - "fmt" - "strconv" - "unicode" -) - -// A XPath expression token type. -type itemType int - -const ( - itemComma itemType = iota // ',' - itemSlash // '/' - itemAt // '@' - itemDot // '.' - itemLParens // '(' - itemRParens // ')' - itemLBracket // '[' - itemRBracket // ']' - itemStar // '*' - itemPlus // '+' - itemMinus // '-' - itemEq // '=' - itemLt // '<' - itemGt // '>' - itemBang // '!' - itemDollar // '$' - itemApos // '\'' - itemQuote // '"' - itemUnion // '|' - itemNe // '!=' - itemLe // '<=' - itemGe // '>=' - itemAnd // '&&' - itemOr // '||' - itemDotDot // '..' - itemSlashSlash // '//' - itemName // XML Name - itemString // Quoted string constant - itemNumber // Number constant - itemAxe // Axe (like child::) - itemEOF // END -) - -// A node is an XPath node in the parse tree. -type node interface { - Type() nodeType -} - -// nodeType identifies the type of a parse tree node. -type nodeType int - -func (t nodeType) Type() nodeType { - return t -} - -const ( - nodeRoot nodeType = iota - nodeAxis - nodeFilter - nodeFunction - nodeOperator - nodeVariable - nodeConstantOperand - nodeGroup -) - -type parser struct { - r *scanner - d int -} - -// newOperatorNode returns new operator node OperatorNode. -func newOperatorNode(op string, left, right node) node { - return &operatorNode{nodeType: nodeOperator, Op: op, Left: left, Right: right} -} - -// newOperand returns new constant operand node OperandNode. -func newOperandNode(v interface{}) node { - return &operandNode{nodeType: nodeConstantOperand, Val: v} -} - -// newAxisNode returns new axis node AxisNode. -func newAxisNode(axeTyp, localName, prefix, prop string, n node) node { - return &axisNode{ - nodeType: nodeAxis, - LocalName: localName, - Prefix: prefix, - AxeType: axeTyp, - Prop: prop, - Input: n, - } -} - -// newVariableNode returns new variable node VariableNode. -func newVariableNode(prefix, name string) node { - return &variableNode{nodeType: nodeVariable, Name: name, Prefix: prefix} -} - -// newFilterNode returns a new filter node FilterNode. -func newFilterNode(n, m node) node { - return &filterNode{nodeType: nodeFilter, Input: n, Condition: m} -} - -func newGroupNode(n node) node { - return &groupNode{nodeType: nodeGroup, Input: n} -} - -// newRootNode returns a root node. -func newRootNode(s string) node { - return &rootNode{nodeType: nodeRoot, slash: s} -} - -// newFunctionNode returns function call node. -func newFunctionNode(name, prefix string, args []node) node { - return &functionNode{nodeType: nodeFunction, Prefix: prefix, FuncName: name, Args: args} -} - -// testOp reports whether current item name is an operand op. -func testOp(r *scanner, op string) bool { - return r.typ == itemName && r.prefix == "" && r.name == op -} - -func isPrimaryExpr(r *scanner) bool { - switch r.typ { - case itemString, itemNumber, itemDollar, itemLParens: - return true - case itemName: - return r.canBeFunc && !isNodeType(r) - } - return false -} - -func isNodeType(r *scanner) bool { - switch r.name { - case "node", "text", "processing-instruction", "comment": - return r.prefix == "" - } - return false -} - -func isStep(item itemType) bool { - switch item { - case itemDot, itemDotDot, itemAt, itemAxe, itemStar, itemName: - return true - } - return false -} - -func checkItem(r *scanner, typ itemType) { - if r.typ != typ { - panic(fmt.Sprintf("%s has an invalid token", r.text)) - } -} - -// parseExpression parsing the expression with input node n. -func (p *parser) parseExpression(n node) node { - if p.d = p.d + 1; p.d > 200 { - panic("the xpath query is too complex(depth > 200)") - } - n = p.parseOrExpr(n) - p.d-- - return n -} - -// next scanning next item on forward. -func (p *parser) next() bool { - return p.r.nextItem() -} - -func (p *parser) skipItem(typ itemType) { - checkItem(p.r, typ) - p.next() -} - -// OrExpr ::= AndExpr | OrExpr 'or' AndExpr -func (p *parser) parseOrExpr(n node) node { - opnd := p.parseAndExpr(n) - for { - if !testOp(p.r, "or") { - break - } - p.next() - opnd = newOperatorNode("or", opnd, p.parseAndExpr(n)) - } - return opnd -} - -// AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr -func (p *parser) parseAndExpr(n node) node { - opnd := p.parseEqualityExpr(n) - for { - if !testOp(p.r, "and") { - break - } - p.next() - opnd = newOperatorNode("and", opnd, p.parseEqualityExpr(n)) - } - return opnd -} - -// EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr | EqualityExpr '!=' RelationalExpr -func (p *parser) parseEqualityExpr(n node) node { - opnd := p.parseRelationalExpr(n) -Loop: - for { - var op string - switch p.r.typ { - case itemEq: - op = "=" - case itemNe: - op = "!=" - default: - break Loop - } - p.next() - opnd = newOperatorNode(op, opnd, p.parseRelationalExpr(n)) - } - return opnd -} - -// RelationalExpr ::= AdditiveExpr | RelationalExpr '<' AdditiveExpr | RelationalExpr '>' AdditiveExpr -// | RelationalExpr '<=' AdditiveExpr -// | RelationalExpr '>=' AdditiveExpr -func (p *parser) parseRelationalExpr(n node) node { - opnd := p.parseAdditiveExpr(n) -Loop: - for { - var op string - switch p.r.typ { - case itemLt: - op = "<" - case itemGt: - op = ">" - case itemLe: - op = "<=" - case itemGe: - op = ">=" - default: - break Loop - } - p.next() - opnd = newOperatorNode(op, opnd, p.parseAdditiveExpr(n)) - } - return opnd -} - -// AdditiveExpr ::= MultiplicativeExpr | AdditiveExpr '+' MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr -func (p *parser) parseAdditiveExpr(n node) node { - opnd := p.parseMultiplicativeExpr(n) -Loop: - for { - var op string - switch p.r.typ { - case itemPlus: - op = "+" - case itemMinus: - op = "-" - default: - break Loop - } - p.next() - opnd = newOperatorNode(op, opnd, p.parseMultiplicativeExpr(n)) - } - return opnd -} - -// MultiplicativeExpr ::= UnaryExpr | MultiplicativeExpr MultiplyOperator(*) UnaryExpr -// | MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr -func (p *parser) parseMultiplicativeExpr(n node) node { - opnd := p.parseUnaryExpr(n) -Loop: - for { - var op string - if p.r.typ == itemStar { - op = "*" - } else if testOp(p.r, "div") || testOp(p.r, "mod") { - op = p.r.name - } else { - break Loop - } - p.next() - opnd = newOperatorNode(op, opnd, p.parseUnaryExpr(n)) - } - return opnd -} - -// UnaryExpr ::= UnionExpr | '-' UnaryExpr -func (p *parser) parseUnaryExpr(n node) node { - minus := false - // ignore '-' sequence - for p.r.typ == itemMinus { - p.next() - minus = !minus - } - opnd := p.parseUnionExpr(n) - if minus { - opnd = newOperatorNode("*", opnd, newOperandNode(float64(-1))) - } - return opnd -} - -// UnionExpr ::= PathExpr | UnionExpr '|' PathExpr -func (p *parser) parseUnionExpr(n node) node { - opnd := p.parsePathExpr(n) -Loop: - for { - if p.r.typ != itemUnion { - break Loop - } - p.next() - opnd2 := p.parsePathExpr(n) - // Checking the node type that must be is node set type? - opnd = newOperatorNode("|", opnd, opnd2) - } - return opnd -} - -// PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath -func (p *parser) parsePathExpr(n node) node { - var opnd node - if isPrimaryExpr(p.r) { - opnd = p.parseFilterExpr(n) - switch p.r.typ { - case itemSlash: - p.next() - opnd = p.parseRelativeLocationPath(opnd) - case itemSlashSlash: - p.next() - opnd = p.parseRelativeLocationPath(newAxisNode("descendant-or-self", "", "", "", opnd)) - } - } else { - opnd = p.parseLocationPath(nil) - } - return opnd -} - -// FilterExpr ::= PrimaryExpr | FilterExpr Predicate -func (p *parser) parseFilterExpr(n node) node { - opnd := p.parsePrimaryExpr(n) - if p.r.typ == itemLBracket { - opnd = newFilterNode(opnd, p.parsePredicate(opnd)) - } - return opnd -} - -// Predicate ::= '[' PredicateExpr ']' -func (p *parser) parsePredicate(n node) node { - p.skipItem(itemLBracket) - opnd := p.parseExpression(n) - p.skipItem(itemRBracket) - return opnd -} - -// LocationPath ::= RelativeLocationPath | AbsoluteLocationPath -func (p *parser) parseLocationPath(n node) (opnd node) { - switch p.r.typ { - case itemSlash: - p.next() - opnd = newRootNode("/") - if isStep(p.r.typ) { - opnd = p.parseRelativeLocationPath(opnd) // ?? child:: or self ?? - } - case itemSlashSlash: - p.next() - opnd = newRootNode("//") - opnd = p.parseRelativeLocationPath(newAxisNode("descendant-or-self", "", "", "", opnd)) - default: - opnd = p.parseRelativeLocationPath(n) - } - return opnd -} - -// RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath -func (p *parser) parseRelativeLocationPath(n node) node { - opnd := n -Loop: - for { - opnd = p.parseStep(opnd) - switch p.r.typ { - case itemSlashSlash: - p.next() - opnd = newAxisNode("descendant-or-self", "", "", "", opnd) - case itemSlash: - p.next() - default: - break Loop - } - } - return opnd -} - -// Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep -func (p *parser) parseStep(n node) (opnd node) { - axeTyp := "child" // default axes value. - if p.r.typ == itemDot || p.r.typ == itemDotDot { - if p.r.typ == itemDot { - axeTyp = "self" - } else { - axeTyp = "parent" - } - p.next() - opnd = newAxisNode(axeTyp, "", "", "", n) - if p.r.typ != itemLBracket { - return opnd - } - } else { - switch p.r.typ { - case itemAt: - p.next() - axeTyp = "attribute" - case itemAxe: - axeTyp = p.r.name - p.next() - case itemLParens: - return p.parseSequence(n) - } - opnd = p.parseNodeTest(n, axeTyp) - } - for p.r.typ == itemLBracket { - opnd = newFilterNode(opnd, p.parsePredicate(opnd)) - } - return opnd -} - -// Expr ::= '(' Step ("," Step)* ')' -func (p *parser) parseSequence(n node) (opnd node) { - p.skipItem(itemLParens) - opnd = p.parseStep(n) - for { - if p.r.typ != itemComma { - break - } - p.next() - opnd2 := p.parseStep(n) - opnd = newOperatorNode("|", opnd, opnd2) - } - p.skipItem(itemRParens) - return opnd -} - -// NodeTest ::= NameTest | nodeType '(' ')' | 'processing-instruction' '(' Literal ')' -func (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) { - switch p.r.typ { - case itemName: - if p.r.canBeFunc && isNodeType(p.r) { - var prop string - switch p.r.name { - case "comment", "text", "processing-instruction", "node": - prop = p.r.name - } - var name string - p.next() - p.skipItem(itemLParens) - if prop == "processing-instruction" && p.r.typ != itemRParens { - checkItem(p.r, itemString) - name = p.r.strval - p.next() - } - p.skipItem(itemRParens) - opnd = newAxisNode(axeTyp, name, "", prop, n) - } else { - prefix := p.r.prefix - name := p.r.name - p.next() - if p.r.name == "*" { - name = "" - } - opnd = newAxisNode(axeTyp, name, prefix, "", n) - } - case itemStar: - opnd = newAxisNode(axeTyp, "", "", "", n) - p.next() - default: - panic("expression must evaluate to a node-set") - } - return opnd -} - -// PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall -func (p *parser) parsePrimaryExpr(n node) (opnd node) { - switch p.r.typ { - case itemString: - opnd = newOperandNode(p.r.strval) - p.next() - case itemNumber: - opnd = newOperandNode(p.r.numval) - p.next() - case itemDollar: - p.next() - checkItem(p.r, itemName) - opnd = newVariableNode(p.r.prefix, p.r.name) - p.next() - case itemLParens: - p.next() - opnd = p.parseExpression(n) - if opnd.Type() != nodeConstantOperand { - opnd = newGroupNode(opnd) - } - p.skipItem(itemRParens) - case itemName: - if p.r.canBeFunc && !isNodeType(p.r) { - opnd = p.parseMethod(nil) - } - } - return opnd -} - -// FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument )* )? ')' -func (p *parser) parseMethod(n node) node { - var args []node - name := p.r.name - prefix := p.r.prefix - - p.skipItem(itemName) - p.skipItem(itemLParens) - if p.r.typ != itemRParens { - for { - args = append(args, p.parseExpression(n)) - if p.r.typ == itemRParens { - break - } - p.skipItem(itemComma) - } - } - p.skipItem(itemRParens) - return newFunctionNode(name, prefix, args) -} - -// Parse parsing the XPath express string expr and returns a tree node. -func parse(expr string) node { - r := &scanner{text: expr} - r.nextChar() - r.nextItem() - p := &parser{r: r} - return p.parseExpression(nil) -} - -// rootNode holds a top-level node of tree. -type rootNode struct { - nodeType - slash string -} - -func (r *rootNode) String() string { - return r.slash -} - -// operatorNode holds two Nodes operator. -type operatorNode struct { - nodeType - Op string - Left, Right node -} - -func (o *operatorNode) String() string { - return fmt.Sprintf("%v%s%v", o.Left, o.Op, o.Right) -} - -// axisNode holds a location step. -type axisNode struct { - nodeType - Input node - Prop string // node-test name.[comment|text|processing-instruction|node] - AxeType string // name of the axes.[attribute|ancestor|child|....] - LocalName string // local part name of node. - Prefix string // prefix name of node. -} - -func (a *axisNode) String() string { - var b bytes.Buffer - if a.AxeType != "" { - b.Write([]byte(a.AxeType + "::")) - } - if a.Prefix != "" { - b.Write([]byte(a.Prefix + ":")) - } - b.Write([]byte(a.LocalName)) - if a.Prop != "" { - b.Write([]byte("/" + a.Prop + "()")) - } - return b.String() -} - -// operandNode holds a constant operand. -type operandNode struct { - nodeType - Val interface{} -} - -func (o *operandNode) String() string { - return fmt.Sprintf("%v", o.Val) -} - -// groupNode holds a set of node expression -type groupNode struct { - nodeType - Input node -} - -func (g *groupNode) String() string { - return fmt.Sprintf("%s", g.Input) -} - -// filterNode holds a condition filter. -type filterNode struct { - nodeType - Input, Condition node -} - -func (f *filterNode) String() string { - return fmt.Sprintf("%s[%s]", f.Input, f.Condition) -} - -// variableNode holds a variable. -type variableNode struct { - nodeType - Name, Prefix string -} - -func (v *variableNode) String() string { - if v.Prefix == "" { - return v.Name - } - return fmt.Sprintf("%s:%s", v.Prefix, v.Name) -} - -// functionNode holds a function call. -type functionNode struct { - nodeType - Args []node - Prefix string - FuncName string // function name -} - -func (f *functionNode) String() string { - var b bytes.Buffer - // fun(arg1, ..., argn) - b.Write([]byte(f.FuncName)) - b.Write([]byte("(")) - for i, arg := range f.Args { - if i > 0 { - b.Write([]byte(",")) - } - b.Write([]byte(fmt.Sprintf("%s", arg))) - } - b.Write([]byte(")")) - return b.String() -} - -type scanner struct { - text, name, prefix string - - pos int - curr rune - typ itemType - strval string // text value at current pos - numval float64 // number value at current pos - canBeFunc bool -} - -func (s *scanner) nextChar() bool { - if s.pos >= len(s.text) { - s.curr = rune(0) - return false - } - s.curr = rune(s.text[s.pos]) - s.pos++ - return true -} - -func (s *scanner) nextItem() bool { - s.skipSpace() - switch s.curr { - case 0: - s.typ = itemEOF - return false - case ',', '@', '(', ')', '|', '*', '[', ']', '+', '-', '=', '#', '$': - s.typ = asItemType(s.curr) - s.nextChar() - case '<': - s.typ = itemLt - s.nextChar() - if s.curr == '=' { - s.typ = itemLe - s.nextChar() - } - case '>': - s.typ = itemGt - s.nextChar() - if s.curr == '=' { - s.typ = itemGe - s.nextChar() - } - case '!': - s.typ = itemBang - s.nextChar() - if s.curr == '=' { - s.typ = itemNe - s.nextChar() - } - case '.': - s.typ = itemDot - s.nextChar() - if s.curr == '.' { - s.typ = itemDotDot - s.nextChar() - } else if isDigit(s.curr) { - s.typ = itemNumber - s.numval = s.scanFraction() - } - case '/': - s.typ = itemSlash - s.nextChar() - if s.curr == '/' { - s.typ = itemSlashSlash - s.nextChar() - } - case '"', '\'': - s.typ = itemString - s.strval = s.scanString() - default: - if isDigit(s.curr) { - s.typ = itemNumber - s.numval = s.scanNumber() - } else if isName(s.curr) { - s.typ = itemName - s.name = s.scanName() - s.prefix = "" - // "foo:bar" is one itemem not three because it doesn't allow spaces in between - // We should distinct it from "foo::" and need process "foo ::" as well - if s.curr == ':' { - s.nextChar() - // can be "foo:bar" or "foo::" - if s.curr == ':' { - // "foo::" - s.nextChar() - s.typ = itemAxe - } else { // "foo:*", "foo:bar" or "foo: " - s.prefix = s.name - if s.curr == '*' { - s.nextChar() - s.name = "*" - } else if isName(s.curr) { - s.name = s.scanName() - } else { - panic(fmt.Sprintf("%s has an invalid qualified name.", s.text)) - } - } - } else { - s.skipSpace() - if s.curr == ':' { - s.nextChar() - // it can be "foo ::" or just "foo :" - if s.curr == ':' { - s.nextChar() - s.typ = itemAxe - } else { - panic(fmt.Sprintf("%s has an invalid qualified name.", s.text)) - } - } - } - s.skipSpace() - s.canBeFunc = s.curr == '(' - } else { - panic(fmt.Sprintf("%s has an invalid token.", s.text)) - } - } - return true -} - -func (s *scanner) skipSpace() { -Loop: - for { - if !unicode.IsSpace(s.curr) || !s.nextChar() { - break Loop - } - } -} - -func (s *scanner) scanFraction() float64 { - var ( - i = s.pos - 2 - c = 1 // '.' - ) - for isDigit(s.curr) { - s.nextChar() - c++ - } - v, err := strconv.ParseFloat(s.text[i:i+c], 64) - if err != nil { - panic(fmt.Errorf("xpath: scanFraction parse float got error: %v", err)) - } - return v -} - -func (s *scanner) scanNumber() float64 { - var ( - c int - i = s.pos - 1 - ) - for isDigit(s.curr) { - s.nextChar() - c++ - } - if s.curr == '.' { - s.nextChar() - c++ - for isDigit(s.curr) { - s.nextChar() - c++ - } - } - v, err := strconv.ParseFloat(s.text[i:i+c], 64) - if err != nil { - panic(fmt.Errorf("xpath: scanNumber parse float got error: %v", err)) - } - return v -} - -func (s *scanner) scanString() string { - var ( - c = 0 - end = s.curr - ) - s.nextChar() - i := s.pos - 1 - for s.curr != end { - if !s.nextChar() { - panic(errors.New("xpath: scanString got unclosed string")) - } - c++ - } - s.nextChar() - return s.text[i : i+c] -} - -func (s *scanner) scanName() string { - var ( - c int - i = s.pos - 1 - ) - for isName(s.curr) { - c++ - if !s.nextChar() { - break - } - } - return s.text[i : i+c] -} - -func isName(r rune) bool { - return string(r) != ":" && string(r) != "/" && - (unicode.Is(first, r) || unicode.Is(second, r) || string(r) == "*") -} - -func isDigit(r rune) bool { - return unicode.IsDigit(r) -} - -func asItemType(r rune) itemType { - switch r { - case ',': - return itemComma - case '@': - return itemAt - case '(': - return itemLParens - case ')': - return itemRParens - case '|': - return itemUnion - case '*': - return itemStar - case '[': - return itemLBracket - case ']': - return itemRBracket - case '+': - return itemPlus - case '-': - return itemMinus - case '=': - return itemEq - case '$': - return itemDollar - } - panic(fmt.Errorf("unknown item: %v", r)) -} - -var first = &unicode.RangeTable{ - R16: []unicode.Range16{ - {0x003A, 0x003A, 1}, - {0x0041, 0x005A, 1}, - {0x005F, 0x005F, 1}, - {0x0061, 0x007A, 1}, - {0x00C0, 0x00D6, 1}, - {0x00D8, 0x00F6, 1}, - {0x00F8, 0x00FF, 1}, - {0x0100, 0x0131, 1}, - {0x0134, 0x013E, 1}, - {0x0141, 0x0148, 1}, - {0x014A, 0x017E, 1}, - {0x0180, 0x01C3, 1}, - {0x01CD, 0x01F0, 1}, - {0x01F4, 0x01F5, 1}, - {0x01FA, 0x0217, 1}, - {0x0250, 0x02A8, 1}, - {0x02BB, 0x02C1, 1}, - {0x0386, 0x0386, 1}, - {0x0388, 0x038A, 1}, - {0x038C, 0x038C, 1}, - {0x038E, 0x03A1, 1}, - {0x03A3, 0x03CE, 1}, - {0x03D0, 0x03D6, 1}, - {0x03DA, 0x03E0, 2}, - {0x03E2, 0x03F3, 1}, - {0x0401, 0x040C, 1}, - {0x040E, 0x044F, 1}, - {0x0451, 0x045C, 1}, - {0x045E, 0x0481, 1}, - {0x0490, 0x04C4, 1}, - {0x04C7, 0x04C8, 1}, - {0x04CB, 0x04CC, 1}, - {0x04D0, 0x04EB, 1}, - {0x04EE, 0x04F5, 1}, - {0x04F8, 0x04F9, 1}, - {0x0531, 0x0556, 1}, - {0x0559, 0x0559, 1}, - {0x0561, 0x0586, 1}, - {0x05D0, 0x05EA, 1}, - {0x05F0, 0x05F2, 1}, - {0x0621, 0x063A, 1}, - {0x0641, 0x064A, 1}, - {0x0671, 0x06B7, 1}, - {0x06BA, 0x06BE, 1}, - {0x06C0, 0x06CE, 1}, - {0x06D0, 0x06D3, 1}, - {0x06D5, 0x06D5, 1}, - {0x06E5, 0x06E6, 1}, - {0x0905, 0x0939, 1}, - {0x093D, 0x093D, 1}, - {0x0958, 0x0961, 1}, - {0x0985, 0x098C, 1}, - {0x098F, 0x0990, 1}, - {0x0993, 0x09A8, 1}, - {0x09AA, 0x09B0, 1}, - {0x09B2, 0x09B2, 1}, - {0x09B6, 0x09B9, 1}, - {0x09DC, 0x09DD, 1}, - {0x09DF, 0x09E1, 1}, - {0x09F0, 0x09F1, 1}, - {0x0A05, 0x0A0A, 1}, - {0x0A0F, 0x0A10, 1}, - {0x0A13, 0x0A28, 1}, - {0x0A2A, 0x0A30, 1}, - {0x0A32, 0x0A33, 1}, - {0x0A35, 0x0A36, 1}, - {0x0A38, 0x0A39, 1}, - {0x0A59, 0x0A5C, 1}, - {0x0A5E, 0x0A5E, 1}, - {0x0A72, 0x0A74, 1}, - {0x0A85, 0x0A8B, 1}, - {0x0A8D, 0x0A8D, 1}, - {0x0A8F, 0x0A91, 1}, - {0x0A93, 0x0AA8, 1}, - {0x0AAA, 0x0AB0, 1}, - {0x0AB2, 0x0AB3, 1}, - {0x0AB5, 0x0AB9, 1}, - {0x0ABD, 0x0AE0, 0x23}, - {0x0B05, 0x0B0C, 1}, - {0x0B0F, 0x0B10, 1}, - {0x0B13, 0x0B28, 1}, - {0x0B2A, 0x0B30, 1}, - {0x0B32, 0x0B33, 1}, - {0x0B36, 0x0B39, 1}, - {0x0B3D, 0x0B3D, 1}, - {0x0B5C, 0x0B5D, 1}, - {0x0B5F, 0x0B61, 1}, - {0x0B85, 0x0B8A, 1}, - {0x0B8E, 0x0B90, 1}, - {0x0B92, 0x0B95, 1}, - {0x0B99, 0x0B9A, 1}, - {0x0B9C, 0x0B9C, 1}, - {0x0B9E, 0x0B9F, 1}, - {0x0BA3, 0x0BA4, 1}, - {0x0BA8, 0x0BAA, 1}, - {0x0BAE, 0x0BB5, 1}, - {0x0BB7, 0x0BB9, 1}, - {0x0C05, 0x0C0C, 1}, - {0x0C0E, 0x0C10, 1}, - {0x0C12, 0x0C28, 1}, - {0x0C2A, 0x0C33, 1}, - {0x0C35, 0x0C39, 1}, - {0x0C60, 0x0C61, 1}, - {0x0C85, 0x0C8C, 1}, - {0x0C8E, 0x0C90, 1}, - {0x0C92, 0x0CA8, 1}, - {0x0CAA, 0x0CB3, 1}, - {0x0CB5, 0x0CB9, 1}, - {0x0CDE, 0x0CDE, 1}, - {0x0CE0, 0x0CE1, 1}, - {0x0D05, 0x0D0C, 1}, - {0x0D0E, 0x0D10, 1}, - {0x0D12, 0x0D28, 1}, - {0x0D2A, 0x0D39, 1}, - {0x0D60, 0x0D61, 1}, - {0x0E01, 0x0E2E, 1}, - {0x0E30, 0x0E30, 1}, - {0x0E32, 0x0E33, 1}, - {0x0E40, 0x0E45, 1}, - {0x0E81, 0x0E82, 1}, - {0x0E84, 0x0E84, 1}, - {0x0E87, 0x0E88, 1}, - {0x0E8A, 0x0E8D, 3}, - {0x0E94, 0x0E97, 1}, - {0x0E99, 0x0E9F, 1}, - {0x0EA1, 0x0EA3, 1}, - {0x0EA5, 0x0EA7, 2}, - {0x0EAA, 0x0EAB, 1}, - {0x0EAD, 0x0EAE, 1}, - {0x0EB0, 0x0EB0, 1}, - {0x0EB2, 0x0EB3, 1}, - {0x0EBD, 0x0EBD, 1}, - {0x0EC0, 0x0EC4, 1}, - {0x0F40, 0x0F47, 1}, - {0x0F49, 0x0F69, 1}, - {0x10A0, 0x10C5, 1}, - {0x10D0, 0x10F6, 1}, - {0x1100, 0x1100, 1}, - {0x1102, 0x1103, 1}, - {0x1105, 0x1107, 1}, - {0x1109, 0x1109, 1}, - {0x110B, 0x110C, 1}, - {0x110E, 0x1112, 1}, - {0x113C, 0x1140, 2}, - {0x114C, 0x1150, 2}, - {0x1154, 0x1155, 1}, - {0x1159, 0x1159, 1}, - {0x115F, 0x1161, 1}, - {0x1163, 0x1169, 2}, - {0x116D, 0x116E, 1}, - {0x1172, 0x1173, 1}, - {0x1175, 0x119E, 0x119E - 0x1175}, - {0x11A8, 0x11AB, 0x11AB - 0x11A8}, - {0x11AE, 0x11AF, 1}, - {0x11B7, 0x11B8, 1}, - {0x11BA, 0x11BA, 1}, - {0x11BC, 0x11C2, 1}, - {0x11EB, 0x11F0, 0x11F0 - 0x11EB}, - {0x11F9, 0x11F9, 1}, - {0x1E00, 0x1E9B, 1}, - {0x1EA0, 0x1EF9, 1}, - {0x1F00, 0x1F15, 1}, - {0x1F18, 0x1F1D, 1}, - {0x1F20, 0x1F45, 1}, - {0x1F48, 0x1F4D, 1}, - {0x1F50, 0x1F57, 1}, - {0x1F59, 0x1F5B, 0x1F5B - 0x1F59}, - {0x1F5D, 0x1F5D, 1}, - {0x1F5F, 0x1F7D, 1}, - {0x1F80, 0x1FB4, 1}, - {0x1FB6, 0x1FBC, 1}, - {0x1FBE, 0x1FBE, 1}, - {0x1FC2, 0x1FC4, 1}, - {0x1FC6, 0x1FCC, 1}, - {0x1FD0, 0x1FD3, 1}, - {0x1FD6, 0x1FDB, 1}, - {0x1FE0, 0x1FEC, 1}, - {0x1FF2, 0x1FF4, 1}, - {0x1FF6, 0x1FFC, 1}, - {0x2126, 0x2126, 1}, - {0x212A, 0x212B, 1}, - {0x212E, 0x212E, 1}, - {0x2180, 0x2182, 1}, - {0x3007, 0x3007, 1}, - {0x3021, 0x3029, 1}, - {0x3041, 0x3094, 1}, - {0x30A1, 0x30FA, 1}, - {0x3105, 0x312C, 1}, - {0x4E00, 0x9FA5, 1}, - {0xAC00, 0xD7A3, 1}, - }, -} - -var second = &unicode.RangeTable{ - R16: []unicode.Range16{ - {0x002D, 0x002E, 1}, - {0x0030, 0x0039, 1}, - {0x00B7, 0x00B7, 1}, - {0x02D0, 0x02D1, 1}, - {0x0300, 0x0345, 1}, - {0x0360, 0x0361, 1}, - {0x0387, 0x0387, 1}, - {0x0483, 0x0486, 1}, - {0x0591, 0x05A1, 1}, - {0x05A3, 0x05B9, 1}, - {0x05BB, 0x05BD, 1}, - {0x05BF, 0x05BF, 1}, - {0x05C1, 0x05C2, 1}, - {0x05C4, 0x0640, 0x0640 - 0x05C4}, - {0x064B, 0x0652, 1}, - {0x0660, 0x0669, 1}, - {0x0670, 0x0670, 1}, - {0x06D6, 0x06DC, 1}, - {0x06DD, 0x06DF, 1}, - {0x06E0, 0x06E4, 1}, - {0x06E7, 0x06E8, 1}, - {0x06EA, 0x06ED, 1}, - {0x06F0, 0x06F9, 1}, - {0x0901, 0x0903, 1}, - {0x093C, 0x093C, 1}, - {0x093E, 0x094C, 1}, - {0x094D, 0x094D, 1}, - {0x0951, 0x0954, 1}, - {0x0962, 0x0963, 1}, - {0x0966, 0x096F, 1}, - {0x0981, 0x0983, 1}, - {0x09BC, 0x09BC, 1}, - {0x09BE, 0x09BF, 1}, - {0x09C0, 0x09C4, 1}, - {0x09C7, 0x09C8, 1}, - {0x09CB, 0x09CD, 1}, - {0x09D7, 0x09D7, 1}, - {0x09E2, 0x09E3, 1}, - {0x09E6, 0x09EF, 1}, - {0x0A02, 0x0A3C, 0x3A}, - {0x0A3E, 0x0A3F, 1}, - {0x0A40, 0x0A42, 1}, - {0x0A47, 0x0A48, 1}, - {0x0A4B, 0x0A4D, 1}, - {0x0A66, 0x0A6F, 1}, - {0x0A70, 0x0A71, 1}, - {0x0A81, 0x0A83, 1}, - {0x0ABC, 0x0ABC, 1}, - {0x0ABE, 0x0AC5, 1}, - {0x0AC7, 0x0AC9, 1}, - {0x0ACB, 0x0ACD, 1}, - {0x0AE6, 0x0AEF, 1}, - {0x0B01, 0x0B03, 1}, - {0x0B3C, 0x0B3C, 1}, - {0x0B3E, 0x0B43, 1}, - {0x0B47, 0x0B48, 1}, - {0x0B4B, 0x0B4D, 1}, - {0x0B56, 0x0B57, 1}, - {0x0B66, 0x0B6F, 1}, - {0x0B82, 0x0B83, 1}, - {0x0BBE, 0x0BC2, 1}, - {0x0BC6, 0x0BC8, 1}, - {0x0BCA, 0x0BCD, 1}, - {0x0BD7, 0x0BD7, 1}, - {0x0BE7, 0x0BEF, 1}, - {0x0C01, 0x0C03, 1}, - {0x0C3E, 0x0C44, 1}, - {0x0C46, 0x0C48, 1}, - {0x0C4A, 0x0C4D, 1}, - {0x0C55, 0x0C56, 1}, - {0x0C66, 0x0C6F, 1}, - {0x0C82, 0x0C83, 1}, - {0x0CBE, 0x0CC4, 1}, - {0x0CC6, 0x0CC8, 1}, - {0x0CCA, 0x0CCD, 1}, - {0x0CD5, 0x0CD6, 1}, - {0x0CE6, 0x0CEF, 1}, - {0x0D02, 0x0D03, 1}, - {0x0D3E, 0x0D43, 1}, - {0x0D46, 0x0D48, 1}, - {0x0D4A, 0x0D4D, 1}, - {0x0D57, 0x0D57, 1}, - {0x0D66, 0x0D6F, 1}, - {0x0E31, 0x0E31, 1}, - {0x0E34, 0x0E3A, 1}, - {0x0E46, 0x0E46, 1}, - {0x0E47, 0x0E4E, 1}, - {0x0E50, 0x0E59, 1}, - {0x0EB1, 0x0EB1, 1}, - {0x0EB4, 0x0EB9, 1}, - {0x0EBB, 0x0EBC, 1}, - {0x0EC6, 0x0EC6, 1}, - {0x0EC8, 0x0ECD, 1}, - {0x0ED0, 0x0ED9, 1}, - {0x0F18, 0x0F19, 1}, - {0x0F20, 0x0F29, 1}, - {0x0F35, 0x0F39, 2}, - {0x0F3E, 0x0F3F, 1}, - {0x0F71, 0x0F84, 1}, - {0x0F86, 0x0F8B, 1}, - {0x0F90, 0x0F95, 1}, - {0x0F97, 0x0F97, 1}, - {0x0F99, 0x0FAD, 1}, - {0x0FB1, 0x0FB7, 1}, - {0x0FB9, 0x0FB9, 1}, - {0x20D0, 0x20DC, 1}, - {0x20E1, 0x3005, 0x3005 - 0x20E1}, - {0x302A, 0x302F, 1}, - {0x3031, 0x3035, 1}, - {0x3099, 0x309A, 1}, - {0x309D, 0x309E, 1}, - {0x30FC, 0x30FE, 1}, - }, -} diff --git a/vendor/github.com/antchfx/xpath/query.go b/vendor/github.com/antchfx/xpath/query.go deleted file mode 100644 index 6e99ce59c86..00000000000 --- a/vendor/github.com/antchfx/xpath/query.go +++ /dev/null @@ -1,952 +0,0 @@ -package xpath - -import ( - "bytes" - "fmt" - "hash/fnv" - "reflect" -) - -type iterator interface { - Current() NodeNavigator -} - -// An XPath query interface. -type query interface { - // Select traversing iterator returns a query matched node NodeNavigator. - Select(iterator) NodeNavigator - - // Evaluate evaluates query and returns values of the current query. - Evaluate(iterator) interface{} - - Clone() query -} - -// nopQuery is an empty query that always return nil for any query. -type nopQuery struct { - query -} - -func (nopQuery) Select(iterator) NodeNavigator { return nil } - -func (nopQuery) Evaluate(iterator) interface{} { return nil } - -func (nopQuery) Clone() query { return nopQuery{} } - -// contextQuery is returns current node on the iterator object query. -type contextQuery struct { - count int - Root bool // Moving to root-level node in the current context iterator. -} - -func (c *contextQuery) Select(t iterator) (n NodeNavigator) { - if c.count == 0 { - c.count++ - n = t.Current().Copy() - if c.Root { - n.MoveToRoot() - } - } - return n -} - -func (c *contextQuery) Evaluate(iterator) interface{} { - c.count = 0 - return c -} - -func (c *contextQuery) Clone() query { - return &contextQuery{count: 0, Root: c.Root} -} - -// ancestorQuery is an XPath ancestor node query.(ancestor::*|ancestor-self::*) -type ancestorQuery struct { - iterator func() NodeNavigator - - Self bool - Input query - Predicate func(NodeNavigator) bool -} - -func (a *ancestorQuery) Select(t iterator) NodeNavigator { - for { - if a.iterator == nil { - node := a.Input.Select(t) - if node == nil { - return nil - } - first := true - node = node.Copy() - a.iterator = func() NodeNavigator { - if first && a.Self { - first = false - if a.Predicate(node) { - return node - } - } - for node.MoveToParent() { - if !a.Predicate(node) { - continue - } - return node - } - return nil - } - } - - if node := a.iterator(); node != nil { - return node - } - a.iterator = nil - } -} - -func (a *ancestorQuery) Evaluate(t iterator) interface{} { - a.Input.Evaluate(t) - a.iterator = nil - return a -} - -func (a *ancestorQuery) Test(n NodeNavigator) bool { - return a.Predicate(n) -} - -func (a *ancestorQuery) Clone() query { - return &ancestorQuery{Self: a.Self, Input: a.Input.Clone(), Predicate: a.Predicate} -} - -// attributeQuery is an XPath attribute node query.(@*) -type attributeQuery struct { - iterator func() NodeNavigator - - Input query - Predicate func(NodeNavigator) bool -} - -func (a *attributeQuery) Select(t iterator) NodeNavigator { - for { - if a.iterator == nil { - node := a.Input.Select(t) - if node == nil { - return nil - } - node = node.Copy() - a.iterator = func() NodeNavigator { - for { - onAttr := node.MoveToNextAttribute() - if !onAttr { - return nil - } - if a.Predicate(node) { - return node - } - } - } - } - - if node := a.iterator(); node != nil { - return node - } - a.iterator = nil - } -} - -func (a *attributeQuery) Evaluate(t iterator) interface{} { - a.Input.Evaluate(t) - a.iterator = nil - return a -} - -func (a *attributeQuery) Test(n NodeNavigator) bool { - return a.Predicate(n) -} - -func (a *attributeQuery) Clone() query { - return &attributeQuery{Input: a.Input.Clone(), Predicate: a.Predicate} -} - -// childQuery is an XPath child node query.(child::*) -type childQuery struct { - posit int - iterator func() NodeNavigator - - Input query - Predicate func(NodeNavigator) bool -} - -func (c *childQuery) Select(t iterator) NodeNavigator { - for { - if c.iterator == nil { - c.posit = 0 - node := c.Input.Select(t) - if node == nil { - return nil - } - node = node.Copy() - first := true - c.iterator = func() NodeNavigator { - for { - if (first && !node.MoveToChild()) || (!first && !node.MoveToNext()) { - return nil - } - first = false - if c.Predicate(node) { - return node - } - } - } - } - - if node := c.iterator(); node != nil { - c.posit++ - return node - } - c.iterator = nil - } -} - -func (c *childQuery) Evaluate(t iterator) interface{} { - c.Input.Evaluate(t) - c.iterator = nil - return c -} - -func (c *childQuery) Test(n NodeNavigator) bool { - return c.Predicate(n) -} - -func (c *childQuery) Clone() query { - return &childQuery{Input: c.Input.Clone(), Predicate: c.Predicate} -} - -// position returns a position of current NodeNavigator. -func (c *childQuery) position() int { - return c.posit -} - -// descendantQuery is an XPath descendant node query.(descendant::* | descendant-or-self::*) -type descendantQuery struct { - iterator func() NodeNavigator - posit int - level int - - Self bool - Input query - Predicate func(NodeNavigator) bool -} - -func (d *descendantQuery) Select(t iterator) NodeNavigator { - for { - if d.iterator == nil { - d.posit = 0 - node := d.Input.Select(t) - if node == nil { - return nil - } - node = node.Copy() - d.level = 0 - positmap := make(map[int]int) - first := true - d.iterator = func() NodeNavigator { - if first && d.Self { - first = false - if d.Predicate(node) { - d.posit = 1 - positmap[d.level] = 1 - return node - } - } - - for { - if node.MoveToChild() { - d.level = d.level + 1 - positmap[d.level] = 0 - } else { - for { - if d.level == 0 { - return nil - } - if node.MoveToNext() { - break - } - node.MoveToParent() - d.level = d.level - 1 - } - } - if d.Predicate(node) { - positmap[d.level]++ - d.posit = positmap[d.level] - return node - } - } - } - } - - if node := d.iterator(); node != nil { - return node - } - d.iterator = nil - } -} - -func (d *descendantQuery) Evaluate(t iterator) interface{} { - d.Input.Evaluate(t) - d.iterator = nil - return d -} - -func (d *descendantQuery) Test(n NodeNavigator) bool { - return d.Predicate(n) -} - -// position returns a position of current NodeNavigator. -func (d *descendantQuery) position() int { - return d.posit -} - -func (d *descendantQuery) depth() int { - return d.level -} - -func (d *descendantQuery) Clone() query { - return &descendantQuery{Self: d.Self, Input: d.Input.Clone(), Predicate: d.Predicate} -} - -// followingQuery is an XPath following node query.(following::*|following-sibling::*) -type followingQuery struct { - posit int - iterator func() NodeNavigator - - Input query - Sibling bool // The matching sibling node of current node. - Predicate func(NodeNavigator) bool -} - -func (f *followingQuery) Select(t iterator) NodeNavigator { - for { - if f.iterator == nil { - f.posit = 0 - node := f.Input.Select(t) - if node == nil { - return nil - } - node = node.Copy() - if f.Sibling { - f.iterator = func() NodeNavigator { - for { - if !node.MoveToNext() { - return nil - } - if f.Predicate(node) { - f.posit++ - return node - } - } - } - } else { - var q *descendantQuery // descendant query - f.iterator = func() NodeNavigator { - for { - if q == nil { - for !node.MoveToNext() { - if !node.MoveToParent() { - return nil - } - } - q = &descendantQuery{ - Self: true, - Input: &contextQuery{}, - Predicate: f.Predicate, - } - t.Current().MoveTo(node) - } - if node := q.Select(t); node != nil { - f.posit = q.posit - return node - } - q = nil - } - } - } - } - - if node := f.iterator(); node != nil { - return node - } - f.iterator = nil - } -} - -func (f *followingQuery) Evaluate(t iterator) interface{} { - f.Input.Evaluate(t) - return f -} - -func (f *followingQuery) Test(n NodeNavigator) bool { - return f.Predicate(n) -} - -func (f *followingQuery) Clone() query { - return &followingQuery{Input: f.Input.Clone(), Sibling: f.Sibling, Predicate: f.Predicate} -} - -func (f *followingQuery) position() int { - return f.posit -} - -// precedingQuery is an XPath preceding node query.(preceding::*) -type precedingQuery struct { - iterator func() NodeNavigator - posit int - Input query - Sibling bool // The matching sibling node of current node. - Predicate func(NodeNavigator) bool -} - -func (p *precedingQuery) Select(t iterator) NodeNavigator { - for { - if p.iterator == nil { - p.posit = 0 - node := p.Input.Select(t) - if node == nil { - return nil - } - node = node.Copy() - if p.Sibling { - p.iterator = func() NodeNavigator { - for { - for !node.MoveToPrevious() { - return nil - } - if p.Predicate(node) { - p.posit++ - return node - } - } - } - } else { - var q query - p.iterator = func() NodeNavigator { - for { - if q == nil { - for !node.MoveToPrevious() { - if !node.MoveToParent() { - return nil - } - p.posit = 0 - } - q = &descendantQuery{ - Self: true, - Input: &contextQuery{}, - Predicate: p.Predicate, - } - t.Current().MoveTo(node) - } - if node := q.Select(t); node != nil { - p.posit++ - return node - } - q = nil - } - } - } - } - if node := p.iterator(); node != nil { - return node - } - p.iterator = nil - } -} - -func (p *precedingQuery) Evaluate(t iterator) interface{} { - p.Input.Evaluate(t) - return p -} - -func (p *precedingQuery) Test(n NodeNavigator) bool { - return p.Predicate(n) -} - -func (p *precedingQuery) Clone() query { - return &precedingQuery{Input: p.Input.Clone(), Sibling: p.Sibling, Predicate: p.Predicate} -} - -func (p *precedingQuery) position() int { - return p.posit -} - -// parentQuery is an XPath parent node query.(parent::*) -type parentQuery struct { - Input query - Predicate func(NodeNavigator) bool -} - -func (p *parentQuery) Select(t iterator) NodeNavigator { - for { - node := p.Input.Select(t) - if node == nil { - return nil - } - node = node.Copy() - if node.MoveToParent() && p.Predicate(node) { - return node - } - } -} - -func (p *parentQuery) Evaluate(t iterator) interface{} { - p.Input.Evaluate(t) - return p -} - -func (p *parentQuery) Clone() query { - return &parentQuery{Input: p.Input.Clone(), Predicate: p.Predicate} -} - -func (p *parentQuery) Test(n NodeNavigator) bool { - return p.Predicate(n) -} - -// selfQuery is an Self node query.(self::*) -type selfQuery struct { - Input query - Predicate func(NodeNavigator) bool -} - -func (s *selfQuery) Select(t iterator) NodeNavigator { - for { - node := s.Input.Select(t) - if node == nil { - return nil - } - - if s.Predicate(node) { - return node - } - } -} - -func (s *selfQuery) Evaluate(t iterator) interface{} { - s.Input.Evaluate(t) - return s -} - -func (s *selfQuery) Test(n NodeNavigator) bool { - return s.Predicate(n) -} - -func (s *selfQuery) Clone() query { - return &selfQuery{Input: s.Input.Clone(), Predicate: s.Predicate} -} - -// filterQuery is an XPath query for predicate filter. -type filterQuery struct { - Input query - Predicate query - posit int - positmap map[int]int -} - -func (f *filterQuery) do(t iterator) bool { - val := reflect.ValueOf(f.Predicate.Evaluate(t)) - switch val.Kind() { - case reflect.Bool: - return val.Bool() - case reflect.String: - return len(val.String()) > 0 - case reflect.Float64: - pt := getNodePosition(f.Input) - return int(val.Float()) == pt - default: - if q, ok := f.Predicate.(query); ok { - return q.Select(t) != nil - } - } - return false -} - -func (f *filterQuery) position() int { - return f.posit -} - -func (f *filterQuery) Select(t iterator) NodeNavigator { - if f.positmap == nil { - f.positmap = make(map[int]int) - } - for { - - node := f.Input.Select(t) - if node == nil { - return node - } - node = node.Copy() - - t.Current().MoveTo(node) - if f.do(t) { - // fix https://github.com/antchfx/htmlquery/issues/26 - // Calculate and keep the each of matching node's position in the same depth. - level := getNodeDepth(f.Input) - f.positmap[level]++ - f.posit = f.positmap[level] - return node - } - } -} - -func (f *filterQuery) Evaluate(t iterator) interface{} { - f.Input.Evaluate(t) - return f -} - -func (f *filterQuery) Clone() query { - return &filterQuery{Input: f.Input.Clone(), Predicate: f.Predicate.Clone()} -} - -// functionQuery is an XPath function that returns a computed value for -// the Evaluate call of the current NodeNavigator node. Select call isn't -// applicable for functionQuery. -type functionQuery struct { - Input query // Node Set - Func func(query, iterator) interface{} // The xpath function. -} - -func (f *functionQuery) Select(t iterator) NodeNavigator { - return nil -} - -// Evaluate call a specified function that will returns the -// following value type: number,string,boolean. -func (f *functionQuery) Evaluate(t iterator) interface{} { - return f.Func(f.Input, t) -} - -func (f *functionQuery) Clone() query { - return &functionQuery{Input: f.Input.Clone(), Func: f.Func} -} - -// transformFunctionQuery diffs from functionQuery where the latter computes a scalar -// value (number,string,boolean) for the current NodeNavigator node while the former -// (transformFunctionQuery) performs a mapping or transform of the current NodeNavigator -// and returns a new NodeNavigator. It is used for non-scalar XPath functions such as -// reverse(), remove(), subsequence(), unordered(), etc. -type transformFunctionQuery struct { - Input query - Func func(query, iterator) func() NodeNavigator - iterator func() NodeNavigator -} - -func (f *transformFunctionQuery) Select(t iterator) NodeNavigator { - if f.iterator == nil { - f.iterator = f.Func(f.Input, t) - } - return f.iterator() -} - -func (f *transformFunctionQuery) Evaluate(t iterator) interface{} { - f.Input.Evaluate(t) - f.iterator = nil - return f -} - -func (f *transformFunctionQuery) Clone() query { - return &transformFunctionQuery{Input: f.Input.Clone(), Func: f.Func} -} - -// constantQuery is an XPath constant operand. -type constantQuery struct { - Val interface{} -} - -func (c *constantQuery) Select(t iterator) NodeNavigator { - return nil -} - -func (c *constantQuery) Evaluate(t iterator) interface{} { - return c.Val -} - -func (c *constantQuery) Clone() query { - return c -} - -type groupQuery struct { - posit int - - Input query -} - -func (g *groupQuery) Select(t iterator) NodeNavigator { - for { - node := g.Input.Select(t) - if node == nil { - return nil - } - g.posit++ - return node.Copy() - } -} - -func (g *groupQuery) Evaluate(t iterator) interface{} { - return g.Input.Evaluate(t) -} - -func (g *groupQuery) Clone() query { - return &groupQuery{Input: g.Input} -} - -func (g *groupQuery) position() int { - return g.posit -} - -// logicalQuery is an XPath logical expression. -type logicalQuery struct { - Left, Right query - - Do func(iterator, interface{}, interface{}) interface{} -} - -func (l *logicalQuery) Select(t iterator) NodeNavigator { - // When a XPath expr is logical expression. - node := t.Current().Copy() - val := l.Evaluate(t) - switch val.(type) { - case bool: - if val.(bool) == true { - return node - } - } - return nil -} - -func (l *logicalQuery) Evaluate(t iterator) interface{} { - m := l.Left.Evaluate(t) - n := l.Right.Evaluate(t) - return l.Do(t, m, n) -} - -func (l *logicalQuery) Clone() query { - return &logicalQuery{Left: l.Left.Clone(), Right: l.Right.Clone(), Do: l.Do} -} - -// numericQuery is an XPath numeric operator expression. -type numericQuery struct { - Left, Right query - - Do func(interface{}, interface{}) interface{} -} - -func (n *numericQuery) Select(t iterator) NodeNavigator { - return nil -} - -func (n *numericQuery) Evaluate(t iterator) interface{} { - m := n.Left.Evaluate(t) - k := n.Right.Evaluate(t) - return n.Do(m, k) -} - -func (n *numericQuery) Clone() query { - return &numericQuery{Left: n.Left.Clone(), Right: n.Right.Clone(), Do: n.Do} -} - -type booleanQuery struct { - IsOr bool - Left, Right query - iterator func() NodeNavigator -} - -func (b *booleanQuery) Select(t iterator) NodeNavigator { - if b.iterator == nil { - var list []NodeNavigator - i := 0 - root := t.Current().Copy() - if b.IsOr { - for { - node := b.Left.Select(t) - if node == nil { - break - } - node = node.Copy() - list = append(list, node) - } - t.Current().MoveTo(root) - for { - node := b.Right.Select(t) - if node == nil { - break - } - node = node.Copy() - list = append(list, node) - } - } else { - var m []NodeNavigator - var n []NodeNavigator - for { - node := b.Left.Select(t) - if node == nil { - break - } - node = node.Copy() - list = append(m, node) - } - t.Current().MoveTo(root) - for { - node := b.Right.Select(t) - if node == nil { - break - } - node = node.Copy() - list = append(n, node) - } - for _, k := range m { - for _, j := range n { - if k == j { - list = append(list, k) - } - } - } - } - - b.iterator = func() NodeNavigator { - if i >= len(list) { - return nil - } - node := list[i] - i++ - return node - } - } - return b.iterator() -} - -func (b *booleanQuery) Evaluate(t iterator) interface{} { - m := b.Left.Evaluate(t) - left := asBool(t, m) - if b.IsOr && left { - return true - } else if !b.IsOr && !left { - return false - } - m = b.Right.Evaluate(t) - return asBool(t, m) -} - -func (b *booleanQuery) Clone() query { - return &booleanQuery{IsOr: b.IsOr, Left: b.Left.Clone(), Right: b.Right.Clone()} -} - -type unionQuery struct { - Left, Right query - iterator func() NodeNavigator -} - -func (u *unionQuery) Select(t iterator) NodeNavigator { - if u.iterator == nil { - var list []NodeNavigator - var m = make(map[uint64]bool) - root := t.Current().Copy() - for { - node := u.Left.Select(t) - if node == nil { - break - } - code := getHashCode(node.Copy()) - if _, ok := m[code]; !ok { - m[code] = true - list = append(list, node.Copy()) - } - } - t.Current().MoveTo(root) - for { - node := u.Right.Select(t) - if node == nil { - break - } - code := getHashCode(node.Copy()) - if _, ok := m[code]; !ok { - m[code] = true - list = append(list, node.Copy()) - } - } - var i int - u.iterator = func() NodeNavigator { - if i >= len(list) { - return nil - } - node := list[i] - i++ - return node - } - } - return u.iterator() -} - -func (u *unionQuery) Evaluate(t iterator) interface{} { - u.iterator = nil - u.Left.Evaluate(t) - u.Right.Evaluate(t) - return u -} - -func (u *unionQuery) Clone() query { - return &unionQuery{Left: u.Left.Clone(), Right: u.Right.Clone()} -} - -func getHashCode(n NodeNavigator) uint64 { - var sb bytes.Buffer - switch n.NodeType() { - case AttributeNode, TextNode, CommentNode: - sb.WriteString(fmt.Sprintf("%s=%s", n.LocalName(), n.Value())) - // https://github.com/antchfx/htmlquery/issues/25 - d := 1 - for n.MoveToPrevious() { - d++ - } - sb.WriteString(fmt.Sprintf("-%d", d)) - for n.MoveToParent() { - d = 1 - for n.MoveToPrevious() { - d++ - } - sb.WriteString(fmt.Sprintf("-%d", d)) - } - case ElementNode: - sb.WriteString(n.Prefix() + n.LocalName()) - d := 1 - for n.MoveToPrevious() { - d++ - } - sb.WriteString(fmt.Sprintf("-%d", d)) - - for n.MoveToParent() { - d = 1 - for n.MoveToPrevious() { - d++ - } - sb.WriteString(fmt.Sprintf("-%d", d)) - } - } - h := fnv.New64a() - h.Write([]byte(sb.String())) - return h.Sum64() -} - -func getNodePosition(q query) int { - type Position interface { - position() int - } - if count, ok := q.(Position); ok { - return count.position() - } - return 1 -} - -func getNodeDepth(q query) int { - type Depth interface { - depth() int - } - if count, ok := q.(Depth); ok { - return count.depth() - } - return 0 -} diff --git a/vendor/github.com/antchfx/xpath/xpath.go b/vendor/github.com/antchfx/xpath/xpath.go deleted file mode 100644 index 5f6aa89a1e1..00000000000 --- a/vendor/github.com/antchfx/xpath/xpath.go +++ /dev/null @@ -1,161 +0,0 @@ -package xpath - -import ( - "errors" - "fmt" -) - -// NodeType represents a type of XPath node. -type NodeType int - -const ( - // RootNode is a root node of the XML document or node tree. - RootNode NodeType = iota - - // ElementNode is an element, such as . - ElementNode - - // AttributeNode is an attribute, such as id='123'. - AttributeNode - - // TextNode is the text content of a node. - TextNode - - // CommentNode is a comment node, such as - CommentNode - - // allNode is any types of node, used by xpath package only to predicate match. - allNode -) - -// NodeNavigator provides cursor model for navigating XML data. -type NodeNavigator interface { - // NodeType returns the XPathNodeType of the current node. - NodeType() NodeType - - // LocalName gets the Name of the current node. - LocalName() string - - // Prefix returns namespace prefix associated with the current node. - Prefix() string - - // Value gets the value of current node. - Value() string - - // Copy does a deep copy of the NodeNavigator and all its components. - Copy() NodeNavigator - - // MoveToRoot moves the NodeNavigator to the root node of the current node. - MoveToRoot() - - // MoveToParent moves the NodeNavigator to the parent node of the current node. - MoveToParent() bool - - // MoveToNextAttribute moves the NodeNavigator to the next attribute on current node. - MoveToNextAttribute() bool - - // MoveToChild moves the NodeNavigator to the first child node of the current node. - MoveToChild() bool - - // MoveToFirst moves the NodeNavigator to the first sibling node of the current node. - MoveToFirst() bool - - // MoveToNext moves the NodeNavigator to the next sibling node of the current node. - MoveToNext() bool - - // MoveToPrevious moves the NodeNavigator to the previous sibling node of the current node. - MoveToPrevious() bool - - // MoveTo moves the NodeNavigator to the same position as the specified NodeNavigator. - MoveTo(NodeNavigator) bool -} - -// NodeIterator holds all matched Node object. -type NodeIterator struct { - node NodeNavigator - query query -} - -// Current returns current node which matched. -func (t *NodeIterator) Current() NodeNavigator { - return t.node -} - -// MoveNext moves Navigator to the next match node. -func (t *NodeIterator) MoveNext() bool { - n := t.query.Select(t) - if n != nil { - if !t.node.MoveTo(n) { - t.node = n.Copy() - } - return true - } - return false -} - -// Select selects a node set using the specified XPath expression. -// This method is deprecated, recommend using Expr.Select() method instead. -func Select(root NodeNavigator, expr string) *NodeIterator { - exp, err := Compile(expr) - if err != nil { - panic(err) - } - return exp.Select(root) -} - -// Expr is an XPath expression for query. -type Expr struct { - s string - q query -} - -type iteratorFunc func() NodeNavigator - -func (f iteratorFunc) Current() NodeNavigator { - return f() -} - -// Evaluate returns the result of the expression. -// The result type of the expression is one of the follow: bool,float64,string,NodeIterator). -func (expr *Expr) Evaluate(root NodeNavigator) interface{} { - val := expr.q.Evaluate(iteratorFunc(func() NodeNavigator { return root })) - switch val.(type) { - case query: - return &NodeIterator{query: expr.q.Clone(), node: root} - } - return val -} - -// Select selects a node set using the specified XPath expression. -func (expr *Expr) Select(root NodeNavigator) *NodeIterator { - return &NodeIterator{query: expr.q.Clone(), node: root} -} - -// String returns XPath expression string. -func (expr *Expr) String() string { - return expr.s -} - -// Compile compiles an XPath expression string. -func Compile(expr string) (*Expr, error) { - if expr == "" { - return nil, errors.New("expr expression is nil") - } - qy, err := build(expr) - if err != nil { - return nil, err - } - if qy == nil { - return nil, fmt.Errorf(fmt.Sprintf("undeclared variable in XPath expression: %s", expr)) - } - return &Expr{s: expr, q: qy}, nil -} - -// MustCompile compiles an XPath expression string and ignored error. -func MustCompile(expr string) *Expr { - exp, err := Compile(expr) - if err != nil { - return &Expr{s: expr, q: nopQuery{}} - } - return exp -} diff --git a/vendor/github.com/asticode/go-astikit/.travis.sh b/vendor/github.com/asticode/go-astikit/.travis.sh deleted file mode 100644 index f67dc1348d7..00000000000 --- a/vendor/github.com/asticode/go-astikit/.travis.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$(go list -m all)" != "github.com/asticode/go-astikit" ]; then - echo "This repo doesn't allow any external dependencies" - exit 1 -else - echo "cheers!" -fi \ No newline at end of file diff --git a/vendor/github.com/asticode/go-astikit/.travis.yml b/vendor/github.com/asticode/go-astikit/.travis.yml deleted file mode 100644 index c64e331fd7d..00000000000 --- a/vendor/github.com/asticode/go-astikit/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go: -- 1.x -- tip -install: -- bash .travis.sh -- go get -t ./... -- go get golang.org/x/tools/cmd/cover -- go get github.com/mattn/goveralls -matrix: - allow_failures: - - go: tip -script: -- go test -race -v -coverprofile=coverage.out -- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci \ No newline at end of file diff --git a/vendor/github.com/asticode/go-astikit/LICENSE b/vendor/github.com/asticode/go-astikit/LICENSE deleted file mode 100644 index 87a311287b8..00000000000 --- a/vendor/github.com/asticode/go-astikit/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Quentin Renard - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/asticode/go-astikit/README.md b/vendor/github.com/asticode/go-astikit/README.md deleted file mode 100644 index e1356c167c9..00000000000 --- a/vendor/github.com/asticode/go-astikit/README.md +++ /dev/null @@ -1,6 +0,0 @@ -[![GoReportCard](http://goreportcard.com/badge/github.com/asticode/go-astikit)](http://goreportcard.com/report/github.com/asticode/go-astikit) -[![GoDoc](https://godoc.org/github.com/asticode/go-astikit?status.svg)](https://godoc.org/github.com/asticode/go-astikit) -[![Travis](https://travis-ci.org/asticode/go-astikit.svg?branch=master)](https://travis-ci.org/asticode/go-astikit#) -[![Coveralls](https://coveralls.io/repos/github/asticode/go-astikit/badge.svg?branch=master)](https://coveralls.io/github/asticode/go-astikit) - -`astikit` is a set of golang helpers that don't require any external dependencies. \ No newline at end of file diff --git a/vendor/github.com/asticode/go-astikit/archive.go b/vendor/github.com/asticode/go-astikit/archive.go deleted file mode 100644 index cde11940402..00000000000 --- a/vendor/github.com/asticode/go-astikit/archive.go +++ /dev/null @@ -1,214 +0,0 @@ -package astikit - -import ( - "archive/zip" - "context" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -// internal shouldn't lead with a "/" -func zipInternalPath(p string) (external, internal string) { - if items := strings.Split(p, ".zip"); len(items) > 1 { - external = items[0] + ".zip" - internal = strings.TrimPrefix(strings.Join(items[1:], ".zip"), string(os.PathSeparator)) - return - } - external = p - return -} - -// Zip zips a src into a dst -// Possible dst formats are: -// - /path/to/zip.zip -// - /path/to/zip.zip/root/path -func Zip(ctx context.Context, dst, src string) (err error) { - // Get external/internal path - externalPath, internalPath := zipInternalPath(dst) - - // Make sure the directory exists - if err = os.MkdirAll(filepath.Dir(externalPath), DefaultDirMode); err != nil { - return fmt.Errorf("astikit: mkdirall %s failed: %w", filepath.Dir(externalPath), err) - } - - // Create destination file - var dstFile *os.File - if dstFile, err = os.Create(externalPath); err != nil { - return fmt.Errorf("astikit: creating %s failed: %w", externalPath, err) - } - defer dstFile.Close() - - // Create zip writer - var zw = zip.NewWriter(dstFile) - defer zw.Close() - - // Walk - if err = filepath.Walk(src, func(path string, info os.FileInfo, e error) (err error) { - // Process error - if e != nil { - err = e - return - } - - // Init header - var h *zip.FileHeader - if h, err = zip.FileInfoHeader(info); err != nil { - return fmt.Errorf("astikit: initializing zip header failed: %w", err) - } - - // Set header info - h.Name = filepath.Join(internalPath, strings.TrimPrefix(path, src)) - if info.IsDir() { - h.Name += string(os.PathSeparator) - } else { - h.Method = zip.Deflate - } - - // Create writer - var w io.Writer - if w, err = zw.CreateHeader(h); err != nil { - return fmt.Errorf("astikit: creating zip header failed: %w", err) - } - - // If path is dir, stop here - if info.IsDir() { - return - } - - // Open path - var walkFile *os.File - if walkFile, err = os.Open(path); err != nil { - return fmt.Errorf("astikit: opening %s failed: %w", path, err) - } - defer walkFile.Close() - - // Copy - if _, err = Copy(ctx, w, walkFile); err != nil { - return fmt.Errorf("astikit: copying failed: %w", err) - } - return - }); err != nil { - return fmt.Errorf("astikit: walking failed: %w", err) - } - return -} - -// Unzip unzips a src into a dst -// Possible src formats are: -// - /path/to/zip.zip -// - /path/to/zip.zip/root/path -func Unzip(ctx context.Context, dst, src string) (err error) { - // Get external/internal path - externalPath, internalPath := zipInternalPath(src) - - // Make sure the destination exists - if err = os.MkdirAll(dst, DefaultDirMode); err != nil { - return fmt.Errorf("astikit: mkdirall %s failed: %w", dst, err) - } - - // Open overall reader - var r *zip.ReadCloser - if r, err = zip.OpenReader(externalPath); err != nil { - return fmt.Errorf("astikit: opening overall zip reader on %s failed: %w", externalPath, err) - } - defer r.Close() - - // Loop through files to determine their type - var dirs, files, symlinks = make(map[string]*zip.File), make(map[string]*zip.File), make(map[string]*zip.File) - for _, f := range r.File { - // Validate internal path - if internalPath != "" && !strings.HasPrefix(f.Name, internalPath) { - continue - } - var p = filepath.Join(dst, strings.TrimPrefix(f.Name, internalPath)) - - // Check file type - if f.FileInfo().Mode()&os.ModeSymlink != 0 { - symlinks[p] = f - } else if f.FileInfo().IsDir() { - dirs[p] = f - } else { - files[p] = f - } - } - - // Invalid internal path - if internalPath != "" && len(dirs) == 0 && len(files) == 0 && len(symlinks) == 0 { - return fmt.Errorf("astikit: content in archive does not match specified internal path %s", internalPath) - } - - // Create dirs - for p, f := range dirs { - if err = os.MkdirAll(p, f.FileInfo().Mode().Perm()); err != nil { - return fmt.Errorf("astikit: mkdirall %s failed: %w", p, err) - } - } - - // Create files - for p, f := range files { - if err = createZipFile(ctx, f, p); err != nil { - return fmt.Errorf("astikit: creating zip file into %s failed: %w", p, err) - } - } - - // Create symlinks - for p, f := range symlinks { - if err = createZipSymlink(f, p); err != nil { - return fmt.Errorf("astikit: creating zip symlink into %s failed: %w", p, err) - } - } - return -} - -func createZipFile(ctx context.Context, f *zip.File, p string) (err error) { - // Open file reader - var fr io.ReadCloser - if fr, err = f.Open(); err != nil { - return fmt.Errorf("astikit: opening zip reader on file %s failed: %w", f.Name, err) - } - defer fr.Close() - - // Since dirs don't always come up we make sure the directory of the file exists with default - // file mode - if err = os.MkdirAll(filepath.Dir(p), DefaultDirMode); err != nil { - return fmt.Errorf("astikit: mkdirall %s failed: %w", filepath.Dir(p), err) - } - - // Open the file - var fl *os.File - if fl, err = os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.FileInfo().Mode().Perm()); err != nil { - return fmt.Errorf("astikit: opening file %s failed: %w", p, err) - } - defer fl.Close() - - // Copy - if _, err = Copy(ctx, fl, fr); err != nil { - return fmt.Errorf("astikit: copying %s into %s failed: %w", f.Name, p, err) - } - return -} - -func createZipSymlink(f *zip.File, p string) (err error) { - // Open file reader - var fr io.ReadCloser - if fr, err = f.Open(); err != nil { - return fmt.Errorf("astikit: opening zip reader on file %s failed: %w", f.Name, err) - } - defer fr.Close() - - // If file is a symlink we retrieve the target path that is in the content of the file - var b []byte - if b, err = ioutil.ReadAll(fr); err != nil { - return fmt.Errorf("astikit: ioutil.Readall on %s failed: %w", f.Name, err) - } - - // Create the symlink - if err = os.Symlink(string(b), p); err != nil { - return fmt.Errorf("astikit: creating symlink from %s to %s failed: %w", string(b), p, err) - } - return -} diff --git a/vendor/github.com/asticode/go-astikit/astikit.go b/vendor/github.com/asticode/go-astikit/astikit.go deleted file mode 100644 index cb6909a68f4..00000000000 --- a/vendor/github.com/asticode/go-astikit/astikit.go +++ /dev/null @@ -1,8 +0,0 @@ -package astikit - -import "os" - -// Default modes -var ( - DefaultDirMode os.FileMode = 0755 -) diff --git a/vendor/github.com/asticode/go-astikit/binary.go b/vendor/github.com/asticode/go-astikit/binary.go deleted file mode 100644 index 521c3b50e8e..00000000000 --- a/vendor/github.com/asticode/go-astikit/binary.go +++ /dev/null @@ -1,297 +0,0 @@ -package astikit - -import ( - "encoding/binary" - "errors" - "io" -) - -// BitsWriter represents an object that can write individual bits into a writer -// in a developer-friendly way. Check out the Write method for more information. -// This is particularly helpful when you want to build a slice of bytes based -// on individual bits for testing purposes. -type BitsWriter struct { - bo binary.ByteOrder - cache byte - cacheLen byte - bsCache []byte - w io.Writer - writeCb BitsWriterWriteCallback -} - -type BitsWriterWriteCallback func([]byte) - -// BitsWriterOptions represents BitsWriter options -type BitsWriterOptions struct { - ByteOrder binary.ByteOrder - // WriteCallback is called every time when full byte is written - WriteCallback BitsWriterWriteCallback - Writer io.Writer -} - -// NewBitsWriter creates a new BitsWriter -func NewBitsWriter(o BitsWriterOptions) (w *BitsWriter) { - w = &BitsWriter{ - bo: o.ByteOrder, - bsCache: make([]byte, 1), - w: o.Writer, - writeCb: o.WriteCallback, - } - if w.bo == nil { - w.bo = binary.BigEndian - } - return -} - -func (w *BitsWriter) SetWriteCallback(cb BitsWriterWriteCallback) { - w.writeCb = cb -} - -// Write writes bits into the writer. Bits are only written when there are -// enough to create a byte. When using a string or a bool, bits are added -// from left to right as if -// Available types are: -// - string("10010"): processed as n bits, n being the length of the input -// - []byte: processed as n bytes, n being the length of the input -// - bool: processed as one bit -// - uint8/uint16/uint32/uint64: processed as n bits, if type is uintn -func (w *BitsWriter) Write(i interface{}) error { - // Transform input into "10010" format - - switch a := i.(type) { - case string: - for _, r := range a { - var err error - if r == '1' { - err = w.writeBit(1) - } else { - err = w.writeBit(0) - } - if err != nil { - return err - } - } - case []byte: - for _, b := range a { - if err := w.writeFullByte(b); err != nil { - return err - } - } - case bool: - if a { - return w.writeBit(1) - } else { - return w.writeBit(0) - } - case uint8: - return w.writeFullByte(a) - case uint16: - return w.writeFullInt(uint64(a), 2) - case uint32: - return w.writeFullInt(uint64(a), 4) - case uint64: - return w.writeFullInt(a, 8) - default: - return errors.New("astikit: invalid type") - } - - return nil -} - -// Writes exactly n bytes from bs -// Writes first n bytes of bs if len(bs) > n -// Pads with padByte at the end if len(bs) < n -func (w *BitsWriter) WriteBytesN(bs []byte, n int, padByte uint8) error { - if len(bs) >= n { - return w.Write(bs[:n]) - } - - if err := w.Write(bs); err != nil { - return err - } - - // no bytes.Repeat here to avoid allocation - for i := 0; i < n-len(bs); i++ { - if err := w.Write(padByte); err != nil { - return err - } - } - - return nil -} - -func (w *BitsWriter) writeFullInt(in uint64, len int) error { - if w.bo == binary.BigEndian { - for i := len - 1; i >= 0; i-- { - err := w.writeFullByte(byte((in >> (i * 8)) & 0xff)) - if err != nil { - return err - } - } - } else { - for i := 0; i < len; i++ { - err := w.writeFullByte(byte((in >> (i * 8)) & 0xff)) - if err != nil { - return err - } - } - } - - return nil -} - -func (w *BitsWriter) flushBsCache() error { - if _, err := w.w.Write(w.bsCache); err != nil { - return err - } - - if w.writeCb != nil { - w.writeCb(w.bsCache) - } - - return nil -} - -func (w *BitsWriter) writeFullByte(b byte) error { - if w.cacheLen == 0 { - w.bsCache[0] = b - } else { - w.bsCache[0] = w.cache | (b >> w.cacheLen) - w.cache = b << (8 - w.cacheLen) - } - return w.flushBsCache() -} - -func (w *BitsWriter) writeBit(bit byte) error { - w.cache = w.cache | (bit)<<(7-w.cacheLen) - w.cacheLen++ - if w.cacheLen == 8 { - w.bsCache[0] = w.cache - if err := w.flushBsCache(); err != nil { - return err - } - - w.cacheLen = 0 - w.cache = 0 - } - return nil -} - -// WriteN writes the input into n bits -func (w *BitsWriter) WriteN(i interface{}, n int) error { - var toWrite uint64 - switch a := i.(type) { - case uint8: - toWrite = uint64(a) - case uint16: - toWrite = uint64(a) - case uint32: - toWrite = uint64(a) - case uint64: - toWrite = a - default: - return errors.New("astikit: invalid type") - } - - for i := n - 1; i >= 0; i-- { - err := w.writeBit(byte(toWrite>>i) & 0x1) - if err != nil { - return err - } - } - return nil -} - -// BitsWriterBatch allows to chain multiple Write* calls and check for error only once -// For more info see https://github.com/asticode/go-astikit/pull/6 -type BitsWriterBatch struct { - err error - w *BitsWriter -} - -func NewBitsWriterBatch(w *BitsWriter) BitsWriterBatch { - return BitsWriterBatch{ - w: w, - } -} - -// Calls BitsWriter.Write if there was no write error before -func (b *BitsWriterBatch) Write(i interface{}) { - if b.err == nil { - b.err = b.w.Write(i) - } -} - -// Calls BitsWriter.WriteN if there was no write error before -func (b *BitsWriterBatch) WriteN(i interface{}, n int) { - if b.err == nil { - b.err = b.w.WriteN(i, n) - } -} - -// Calls BitsWriter.WriteBytesN if there was no write error before -func (b *BitsWriterBatch) WriteBytesN(bs []byte, n int, padByte uint8) { - if b.err == nil { - b.err = b.w.WriteBytesN(bs, n, padByte) - } -} - -// Returns first write error -func (b *BitsWriterBatch) Err() error { - return b.err -} - -var byteHamming84Tab = [256]uint8{ - 0x01, 0xff, 0xff, 0x08, 0xff, 0x0c, 0x04, 0xff, 0xff, 0x08, 0x08, 0x08, 0x06, 0xff, 0xff, 0x08, - 0xff, 0x0a, 0x02, 0xff, 0x06, 0xff, 0xff, 0x0f, 0x06, 0xff, 0xff, 0x08, 0x06, 0x06, 0x06, 0xff, - 0xff, 0x0a, 0x04, 0xff, 0x04, 0xff, 0x04, 0x04, 0x00, 0xff, 0xff, 0x08, 0xff, 0x0d, 0x04, 0xff, - 0x0a, 0x0a, 0xff, 0x0a, 0xff, 0x0a, 0x04, 0xff, 0xff, 0x0a, 0x03, 0xff, 0x06, 0xff, 0xff, 0x0e, - 0x01, 0x01, 0x01, 0xff, 0x01, 0xff, 0xff, 0x0f, 0x01, 0xff, 0xff, 0x08, 0xff, 0x0d, 0x05, 0xff, - 0x01, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0x0f, 0xff, 0x0b, 0x03, 0xff, 0x06, 0xff, 0xff, 0x0f, - 0x01, 0xff, 0xff, 0x09, 0xff, 0x0d, 0x04, 0xff, 0xff, 0x0d, 0x03, 0xff, 0x0d, 0x0d, 0xff, 0x0d, - 0xff, 0x0a, 0x03, 0xff, 0x07, 0xff, 0xff, 0x0f, 0x03, 0xff, 0x03, 0x03, 0xff, 0x0d, 0x03, 0xff, - 0xff, 0x0c, 0x02, 0xff, 0x0c, 0x0c, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x08, 0xff, 0x0c, 0x05, 0xff, - 0x02, 0xff, 0x02, 0x02, 0xff, 0x0c, 0x02, 0xff, 0xff, 0x0b, 0x02, 0xff, 0x06, 0xff, 0xff, 0x0e, - 0x00, 0xff, 0xff, 0x09, 0xff, 0x0c, 0x04, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x0e, - 0xff, 0x0a, 0x02, 0xff, 0x07, 0xff, 0xff, 0x0e, 0x00, 0xff, 0xff, 0x0e, 0xff, 0x0e, 0x0e, 0x0e, - 0x01, 0xff, 0xff, 0x09, 0xff, 0x0c, 0x05, 0xff, 0xff, 0x0b, 0x05, 0xff, 0x05, 0xff, 0x05, 0x05, - 0xff, 0x0b, 0x02, 0xff, 0x07, 0xff, 0xff, 0x0f, 0x0b, 0x0b, 0xff, 0x0b, 0xff, 0x0b, 0x05, 0xff, - 0xff, 0x09, 0x09, 0x09, 0x07, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0xff, 0x0d, 0x05, 0xff, - 0x07, 0xff, 0xff, 0x09, 0x07, 0x07, 0x07, 0xff, 0xff, 0x0b, 0x03, 0xff, 0x07, 0xff, 0xff, 0x0e, -} - -// ByteHamming84Decode hamming 8/4 decodes -func ByteHamming84Decode(i uint8) (o uint8, ok bool) { - o = byteHamming84Tab[i] - if o == 0xff { - return - } - ok = true - return -} - -var byteParityTab = [256]uint8{ - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, -} - -// ByteParity returns the byte parity -func ByteParity(i uint8) (o uint8, ok bool) { - ok = byteParityTab[i] == 1 - o = i & 0x7f - return -} diff --git a/vendor/github.com/asticode/go-astikit/bytes.go b/vendor/github.com/asticode/go-astikit/bytes.go deleted file mode 100644 index 155e2f06a2c..00000000000 --- a/vendor/github.com/asticode/go-astikit/bytes.go +++ /dev/null @@ -1,164 +0,0 @@ -package astikit - -import "fmt" - -// BytesIterator represents an object capable of iterating sequentially and safely -// through a slice of bytes. This is particularly useful when you need to iterate -// through a slice of bytes and don't want to check for "index out of range" errors -// manually. -type BytesIterator struct { - bs []byte - offset int -} - -// NewBytesIterator creates a new BytesIterator -func NewBytesIterator(bs []byte) *BytesIterator { - return &BytesIterator{bs: bs} -} - -// NextByte returns the next byte -func (i *BytesIterator) NextByte() (b byte, err error) { - if len(i.bs) < i.offset+1 { - err = fmt.Errorf("astikit: slice length is %d, offset %d is invalid", len(i.bs), i.offset) - return - } - b = i.bs[i.offset] - i.offset++ - return -} - -// NextBytes returns the n next bytes -func (i *BytesIterator) NextBytes(n int) (bs []byte, err error) { - if len(i.bs) < i.offset+n { - err = fmt.Errorf("astikit: slice length is %d, offset %d is invalid", len(i.bs), i.offset+n) - return - } - bs = make([]byte, n) - copy(bs, i.bs[i.offset:i.offset+n]) - i.offset += n - return -} - -// NextBytesNoCopy returns the n next bytes -// Be careful with this function as it doesn't make a copy of returned data. -// bs will point to internal BytesIterator buffer. -// If you need to modify returned bytes or store it for some time, use NextBytes instead -func (i *BytesIterator) NextBytesNoCopy(n int) (bs []byte, err error) { - if len(i.bs) < i.offset+n { - err = fmt.Errorf("astikit: slice length is %d, offset %d is invalid", len(i.bs), i.offset+n) - return - } - bs = i.bs[i.offset : i.offset+n] - i.offset += n - return -} - -// Seek seeks to the nth byte -func (i *BytesIterator) Seek(n int) { - i.offset = n -} - -// Skip skips the n previous/next bytes -func (i *BytesIterator) Skip(n int) { - i.offset += n -} - -// HasBytesLeft checks whether there are bytes left -func (i *BytesIterator) HasBytesLeft() bool { - return i.offset < len(i.bs) -} - -// Offset returns the offset -func (i *BytesIterator) Offset() int { - return i.offset -} - -// Dump dumps the rest of the slice -func (i *BytesIterator) Dump() (bs []byte) { - if !i.HasBytesLeft() { - return - } - bs = make([]byte, len(i.bs)-i.offset) - copy(bs, i.bs[i.offset:len(i.bs)]) - i.offset = len(i.bs) - return -} - -// Len returns the slice length -func (i *BytesIterator) Len() int { - return len(i.bs) -} - -const ( - padRight = "right" - padLeft = "left" -) - -type bytesPadder struct { - cut bool - direction string - length int - repeat byte -} - -func newBytesPadder(repeat byte, length int) *bytesPadder { - return &bytesPadder{ - direction: padLeft, - length: length, - repeat: repeat, - } -} - -func (p *bytesPadder) pad(i []byte) []byte { - if len(i) == p.length { - return i - } else if len(i) > p.length { - if p.cut { - return i[:p.length] - } - return i - } else { - o := make([]byte, len(i)) - copy(o, i) - for idx := 0; idx < p.length-len(i); idx++ { - if p.direction == padRight { - o = append(o, p.repeat) - } else { - o = append([]byte{p.repeat}, o...) - } - o = append(o, p.repeat) - } - o = o[:p.length] - return o - } -} - -// PadOption represents a Pad option -type PadOption func(p *bytesPadder) - -// PadCut is a PadOption -// It indicates to the padder it must cut the input to the provided length -// if its original length is bigger -func PadCut(p *bytesPadder) { p.cut = true } - -// PadLeft is a PadOption -// It indicates additionnal bytes have to be added to the left -func PadLeft(p *bytesPadder) { p.direction = padLeft } - -// PadRight is a PadOption -// It indicates additionnal bytes have to be added to the right -func PadRight(p *bytesPadder) { p.direction = padRight } - -// BytesPad pads the slice of bytes with additionnal options -func BytesPad(i []byte, repeat byte, length int, options ...PadOption) []byte { - p := newBytesPadder(repeat, length) - for _, o := range options { - o(p) - } - return p.pad(i) -} - -// StrPad pads the string with additionnal options -func StrPad(i string, repeat rune, length int, options ...PadOption) string { - return string(BytesPad([]byte(i), byte(repeat), length, options...)) -} diff --git a/vendor/github.com/asticode/go-astikit/defer.go b/vendor/github.com/asticode/go-astikit/defer.go deleted file mode 100644 index ddca03702e4..00000000000 --- a/vendor/github.com/asticode/go-astikit/defer.go +++ /dev/null @@ -1,57 +0,0 @@ -package astikit - -import ( - "sync" -) - -// CloseFunc is a method that closes something -type CloseFunc func() error - -// Closer is an object that can close several things -type Closer struct { - fs []CloseFunc - m *sync.Mutex -} - -// NewCloser creates a new closer -func NewCloser() *Closer { - return &Closer{ - m: &sync.Mutex{}, - } -} - -// Close implements the io.Closer interface -func (c *Closer) Close() error { - // Lock - c.m.Lock() - defer c.m.Unlock() - - // Loop through closers - err := NewErrors() - for _, f := range c.fs { - err.Add(f()) - } - - // Reset closers - c.fs = []CloseFunc{} - - // Return - if err.IsNil() { - return nil - } - return err -} - -// Add adds a close func at the beginning of the list -func (c *Closer) Add(f CloseFunc) { - c.m.Lock() - defer c.m.Unlock() - c.fs = append([]CloseFunc{f}, c.fs...) -} - -// NewChild creates a new child closer -func (c *Closer) NewChild() (child *Closer) { - child = NewCloser() - c.Add(child.Close) - return -} diff --git a/vendor/github.com/asticode/go-astikit/errors.go b/vendor/github.com/asticode/go-astikit/errors.go deleted file mode 100644 index 46e84963a3e..00000000000 --- a/vendor/github.com/asticode/go-astikit/errors.go +++ /dev/null @@ -1,71 +0,0 @@ -package astikit - -import ( - "errors" - "strings" - "sync" -) - -// Errors is an error containing multiple errors -type Errors struct { - m *sync.Mutex // Locks p - p []error -} - -// NewErrors creates new errors -func NewErrors(errs ...error) *Errors { - return &Errors{ - m: &sync.Mutex{}, - p: errs, - } -} - -// Add adds a new error -func (errs *Errors) Add(err error) { - if err == nil { - return - } - errs.m.Lock() - defer errs.m.Unlock() - errs.p = append(errs.p, err) -} - -// IsNil checks whether the error is nil -func (errs *Errors) IsNil() bool { - errs.m.Lock() - defer errs.m.Unlock() - return len(errs.p) == 0 -} - -// Loop loops through the errors -func (errs *Errors) Loop(fn func(idx int, err error) bool) { - errs.m.Lock() - defer errs.m.Unlock() - for idx, err := range errs.p { - if stop := fn(idx, err); stop { - return - } - } -} - -// Error implements the error interface -func (errs *Errors) Error() string { - errs.m.Lock() - defer errs.m.Unlock() - var ss []string - for _, err := range errs.p { - ss = append(ss, err.Error()) - } - return strings.Join(ss, " && ") -} - -// ErrorCause returns the cause of an error -func ErrorCause(err error) error { - for { - if u := errors.Unwrap(err); u != nil { - err = u - continue - } - return err - } -} diff --git a/vendor/github.com/asticode/go-astikit/exec.go b/vendor/github.com/asticode/go-astikit/exec.go deleted file mode 100644 index 07a0e40928d..00000000000 --- a/vendor/github.com/asticode/go-astikit/exec.go +++ /dev/null @@ -1,104 +0,0 @@ -package astikit - -import ( - "context" - "fmt" - "os/exec" - "strings" - "sync" -) - -// Statuses -const ( - ExecStatusCrashed = "crashed" - ExecStatusRunning = "running" - ExecStatusStopped = "stopped" -) - -// ExecHandler represents an object capable of handling the execution of a cmd -type ExecHandler struct { - cancel context.CancelFunc - ctx context.Context - err error - o sync.Once - stopped bool -} - -// Status returns the cmd status -func (h *ExecHandler) Status() string { - if h.ctx.Err() != nil { - if h.stopped || h.err == nil { - return ExecStatusStopped - } - return ExecStatusCrashed - } - return ExecStatusRunning -} - -// Stop stops the cmd -func (h *ExecHandler) Stop() { - h.o.Do(func() { - h.cancel() - h.stopped = true - }) -} - -// ExecCmdOptions represents exec options -type ExecCmdOptions struct { - Args []string - CmdAdapter func(cmd *exec.Cmd, h *ExecHandler) error - Name string - StopFunc func(cmd *exec.Cmd) error -} - -// ExecCmd executes a cmd -// The process will be stopped when the worker stops -func ExecCmd(w *Worker, o ExecCmdOptions) (h *ExecHandler, err error) { - // Create handler - h = &ExecHandler{} - h.ctx, h.cancel = context.WithCancel(w.Context()) - - // Create command - cmd := exec.Command(o.Name, o.Args...) - - // Adapt command - if o.CmdAdapter != nil { - if err = o.CmdAdapter(cmd, h); err != nil { - err = fmt.Errorf("astikit: adapting cmd failed: %w", err) - return - } - } - - // Start - w.Logger().Infof("astikit: starting %s", strings.Join(cmd.Args, " ")) - if err = cmd.Start(); err != nil { - err = fmt.Errorf("astikit: executing %s: %w", strings.Join(cmd.Args, " "), err) - return - } - - // Handle context - go func() { - // Wait for context to be done - <-h.ctx.Done() - - // Get stop func - f := func() error { return cmd.Process.Kill() } - if o.StopFunc != nil { - f = func() error { return o.StopFunc(cmd) } - } - - // Stop - if err = f(); err != nil { - w.Logger().Error(fmt.Errorf("astikit: stopping cmd failed: %w", err)) - return - } - }() - - // Execute in a task - w.NewTask().Do(func() { - h.err = cmd.Wait() - h.cancel() - w.Logger().Infof("astikit: status is now %s for %s", h.Status(), strings.Join(cmd.Args, " ")) - }) - return -} diff --git a/vendor/github.com/asticode/go-astikit/flag.go b/vendor/github.com/asticode/go-astikit/flag.go deleted file mode 100644 index 2c533cd91dd..00000000000 --- a/vendor/github.com/asticode/go-astikit/flag.go +++ /dev/null @@ -1,48 +0,0 @@ -package astikit - -import ( - "os" - "strings" -) - -// FlagCmd retrieves the command from the input Args -func FlagCmd() (o string) { - if len(os.Args) >= 2 && os.Args[1][0] != '-' { - o = os.Args[1] - os.Args = append([]string{os.Args[0]}, os.Args[2:]...) - } - return -} - -// FlagStrings represents a flag that can be set several times and -// stores unique string values -type FlagStrings struct { - Map map[string]bool - Slice *[]string -} - -// NewFlagStrings creates a new FlagStrings -func NewFlagStrings() FlagStrings { - return FlagStrings{ - Map: make(map[string]bool), - Slice: &[]string{}, - } -} - -// String implements the flag.Value interface -func (f FlagStrings) String() string { - if f.Slice == nil { - return "" - } - return strings.Join(*f.Slice, ",") -} - -// Set implements the flag.Value interface -func (f FlagStrings) Set(i string) error { - if _, ok := f.Map[i]; ok { - return nil - } - f.Map[i] = true - *f.Slice = append(*f.Slice, i) - return nil -} diff --git a/vendor/github.com/asticode/go-astikit/float.go b/vendor/github.com/asticode/go-astikit/float.go deleted file mode 100644 index 844f673a4d7..00000000000 --- a/vendor/github.com/asticode/go-astikit/float.go +++ /dev/null @@ -1,60 +0,0 @@ -package astikit - -import ( - "bytes" - "fmt" - "strconv" -) - -// Rational represents a rational -type Rational struct{ den, num int } - -// NewRational creates a new rational -func NewRational(num, den int) *Rational { - return &Rational{ - den: den, - num: num, - } -} - -// Num returns the rational num -func (r *Rational) Num() int { - return r.num -} - -// Den returns the rational den -func (r *Rational) Den() int { - return r.den -} - -// ToFloat64 returns the rational as a float64 -func (r *Rational) ToFloat64() float64 { - return float64(r.num) / float64(r.den) -} - -// MarshalText implements the TextMarshaler interface -func (r *Rational) MarshalText() (b []byte, err error) { - b = []byte(fmt.Sprintf("%d/%d", r.num, r.den)) - return -} - -// UnmarshalText implements the TextUnmarshaler interface -func (r *Rational) UnmarshalText(b []byte) (err error) { - r.num = 0 - r.den = 1 - if len(b) == 0 { - return - } - items := bytes.Split(b, []byte("/")) - if r.num, err = strconv.Atoi(string(items[0])); err != nil { - err = fmt.Errorf("astikit: atoi of %s failed: %w", string(items[0]), err) - return - } - if len(items) > 1 { - if r.den, err = strconv.Atoi(string(items[1])); err != nil { - err = fmt.Errorf("astifloat: atoi of %s failed: %w", string(items[1]), err) - return - } - } - return -} diff --git a/vendor/github.com/asticode/go-astikit/http.go b/vendor/github.com/asticode/go-astikit/http.go deleted file mode 100644 index 72a3b0f0897..00000000000 --- a/vendor/github.com/asticode/go-astikit/http.go +++ /dev/null @@ -1,632 +0,0 @@ -package astikit - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "net/http" - "os" - "path/filepath" - "strconv" - "strings" - "sync" - "time" -) - -var ErrHTTPSenderUnmarshaledError = errors.New("astikit: unmarshaled error") - -// ServeHTTPOptions represents serve options -type ServeHTTPOptions struct { - Addr string - Handler http.Handler -} - -// ServeHTTP spawns an HTTP server -func ServeHTTP(w *Worker, o ServeHTTPOptions) { - // Create server - s := &http.Server{Addr: o.Addr, Handler: o.Handler} - - // Execute in a task - w.NewTask().Do(func() { - // Log - w.Logger().Infof("astikit: serving on %s", o.Addr) - - // Serve - var done = make(chan error) - go func() { - if err := s.ListenAndServe(); err != nil { - done <- err - } - }() - - // Wait for context or done to be done - select { - case <-w.ctx.Done(): - if w.ctx.Err() != context.Canceled { - w.Logger().Error(fmt.Errorf("astikit: context error: %w", w.ctx.Err())) - } - case err := <-done: - if err != nil { - w.Logger().Error(fmt.Errorf("astikit: serving failed: %w", err)) - } - } - - // Shutdown - w.Logger().Infof("astikit: shutting down server on %s", o.Addr) - if err := s.Shutdown(context.Background()); err != nil { - w.Logger().Error(fmt.Errorf("astikit: shutting down server on %s failed: %w", o.Addr, err)) - } - }) -} - -// HTTPClient represents an HTTP client -type HTTPClient interface { - Do(req *http.Request) (*http.Response, error) -} - -// HTTPSender represents an object capable of sending http requests -type HTTPSender struct { - client HTTPClient - l SeverityLogger - retryFunc HTTPSenderRetryFunc - retryMax int - retrySleep time.Duration - timeout time.Duration -} - -// HTTPSenderRetryFunc is a function that decides whether to retry an HTTP request -type HTTPSenderRetryFunc func(resp *http.Response) error - -// HTTPSenderOptions represents HTTPSender options -type HTTPSenderOptions struct { - Client HTTPClient - Logger StdLogger - RetryFunc HTTPSenderRetryFunc - RetryMax int - RetrySleep time.Duration - Timeout time.Duration -} - -// NewHTTPSender creates a new HTTP sender -func NewHTTPSender(o HTTPSenderOptions) (s *HTTPSender) { - s = &HTTPSender{ - client: o.Client, - l: AdaptStdLogger(o.Logger), - retryFunc: o.RetryFunc, - retryMax: o.RetryMax, - retrySleep: o.RetrySleep, - timeout: o.Timeout, - } - if s.client == nil { - s.client = &http.Client{} - } - if s.retryFunc == nil { - s.retryFunc = s.defaultHTTPRetryFunc - } - return -} - -func (s *HTTPSender) defaultHTTPRetryFunc(resp *http.Response) error { - if resp.StatusCode >= http.StatusInternalServerError { - return fmt.Errorf("astikit: invalid status code %d", resp.StatusCode) - } - return nil -} - -// Send sends a new *http.Request -func (s *HTTPSender) Send(req *http.Request) (*http.Response, error) { - return s.SendWithTimeout(req, s.timeout) -} - -// SendWithTimeout sends a new *http.Request with a timeout -func (s *HTTPSender) SendWithTimeout(req *http.Request, timeout time.Duration) (resp *http.Response, err error) { - // Set name - name := req.Method + " request" - if req.URL != nil { - name += " to " + req.URL.String() - } - - // Timeout - if timeout > 0 { - // Create context - ctx, cancel := context.WithTimeout(req.Context(), timeout) - defer cancel() - - // Update request - req = req.WithContext(ctx) - - // Update name - name += " with timeout " + timeout.String() - } - - // Loop - // We start at retryMax + 1 so that it runs at least once even if retryMax == 0 - tries := 0 - for retriesLeft := s.retryMax + 1; retriesLeft > 0; retriesLeft-- { - // Get request name - nr := name + " (" + strconv.Itoa(s.retryMax-retriesLeft+2) + "/" + strconv.Itoa(s.retryMax+1) + ")" - tries++ - - // Send request - s.l.Debugf("astikit: sending %s", nr) - if resp, err = s.client.Do(req); err != nil { - // Retry if error is temporary, stop here otherwise - if netError, ok := err.(net.Error); !ok || !netError.Temporary() { - err = fmt.Errorf("astikit: sending %s failed: %w", nr, err) - return - } - } else if err = req.Context().Err(); err != nil { - err = fmt.Errorf("astikit: request context failed: %w", err) - return - } else { - err = s.retryFunc(resp) - } - - // Retry - if err != nil { - if retriesLeft > 1 { - s.l.Errorf("astikit: sending %s failed, sleeping %s and retrying... (%d retries left): %w", nr, s.retrySleep, retriesLeft-1, err) - time.Sleep(s.retrySleep) - } - continue - } - - // Return if conditions for retrying were not met - return - } - - // Max retries limit reached - err = fmt.Errorf("astikit: sending %s failed after %d tries: %w", name, tries, err) - return -} - -// HTTPSendJSONOptions represents SendJSON options -type HTTPSendJSONOptions struct { - BodyError interface{} - BodyIn interface{} - BodyOut interface{} - Headers map[string]string - Method string - URL string -} - -// SendJSON sends a new JSON HTTP request -func (s *HTTPSender) SendJSON(o HTTPSendJSONOptions) (err error) { - // Marshal body in - var bi io.Reader - if o.BodyIn != nil { - bb := &bytes.Buffer{} - if err = json.NewEncoder(bb).Encode(o.BodyIn); err != nil { - err = fmt.Errorf("astikit: marshaling body in failed: %w", err) - return - } - bi = bb - } - - // Create request - var req *http.Request - if req, err = http.NewRequest(o.Method, o.URL, bi); err != nil { - err = fmt.Errorf("astikit: creating request failed: %w", err) - return - } - - // Add headers - for k, v := range o.Headers { - req.Header.Set(k, v) - } - - // Send request - var resp *http.Response - if resp, err = s.Send(req); err != nil { - err = fmt.Errorf("astikit: sending request failed: %w", err) - return - } - defer resp.Body.Close() - - // Process status code - if code := resp.StatusCode; code < 200 || code > 299 { - // Try unmarshaling error - if o.BodyError != nil { - if err2 := json.NewDecoder(resp.Body).Decode(o.BodyError); err2 == nil { - err = ErrHTTPSenderUnmarshaledError - return - } - } - - // Default error - err = fmt.Errorf("astikit: invalid status code %d", code) - return - } - - // Unmarshal body out - if o.BodyOut != nil { - if err = json.NewDecoder(resp.Body).Decode(o.BodyOut); err != nil { - err = fmt.Errorf("astikit: unmarshaling failed: %w", err) - return - } - } - return -} - -// HTTPResponseFunc is a func that can process an $http.Response -type HTTPResponseFunc func(resp *http.Response) error - -func defaultHTTPResponseFunc(resp *http.Response) (err error) { - if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { - err = fmt.Errorf("astikit: invalid status code %d", resp.StatusCode) - return - } - return -} - -// HTTPDownloader represents an object capable of downloading several HTTP srcs simultaneously -// and doing stuff to the results -type HTTPDownloader struct { - bp *BufferPool - l *GoroutineLimiter - responseFunc HTTPResponseFunc - s *HTTPSender -} - -// HTTPDownloaderOptions represents HTTPDownloader options -type HTTPDownloaderOptions struct { - Limiter GoroutineLimiterOptions - ResponseFunc HTTPResponseFunc - Sender HTTPSenderOptions -} - -// NewHTTPDownloader creates a new HTTPDownloader -func NewHTTPDownloader(o HTTPDownloaderOptions) (d *HTTPDownloader) { - d = &HTTPDownloader{ - bp: NewBufferPool(), - l: NewGoroutineLimiter(o.Limiter), - responseFunc: o.ResponseFunc, - s: NewHTTPSender(o.Sender), - } - if d.responseFunc == nil { - d.responseFunc = defaultHTTPResponseFunc - } - return -} - -// Close closes the downloader properly -func (d *HTTPDownloader) Close() error { - return d.l.Close() -} - -type HTTPDownloaderSrc struct { - Body io.Reader - Header http.Header - Method string - URL string -} - -// It is the responsibility of the caller to call i.Close() -type httpDownloaderFunc func(ctx context.Context, idx int, i *BufferPoolItem) error - -func (d *HTTPDownloader) do(ctx context.Context, fn httpDownloaderFunc, idx int, src HTTPDownloaderSrc) (err error) { - // Defaults - if src.Method == "" { - src.Method = http.MethodGet - } - - // Create request - var r *http.Request - if r, err = http.NewRequestWithContext(ctx, src.Method, src.URL, src.Body); err != nil { - err = fmt.Errorf("astikit: creating request to %s failed: %w", src.URL, err) - return - } - - // Copy header - for k := range src.Header { - r.Header.Set(k, src.Header.Get(k)) - } - - // Send request - var resp *http.Response - if resp, err = d.s.Send(r); err != nil { - err = fmt.Errorf("astikit: sending request to %s failed: %w", src.URL, err) - return - } - defer resp.Body.Close() - - // Create buffer pool item - buf := d.bp.New() - - // Process response - if err = d.responseFunc(resp); err != nil { - err = fmt.Errorf("astikit: response for request to %s is invalid: %w", src.URL, err) - return - } - - // Copy body - if _, err = Copy(ctx, buf, resp.Body); err != nil { - err = fmt.Errorf("astikit: copying body of %s failed: %w", src.URL, err) - return - } - - // Custom - if err = fn(ctx, idx, buf); err != nil { - err = fmt.Errorf("astikit: custom callback on %s failed: %w", src.URL, err) - return - } - return -} - -func (d *HTTPDownloader) download(ctx context.Context, srcs []HTTPDownloaderSrc, fn httpDownloaderFunc) (err error) { - // Nothing to download - if len(srcs) == 0 { - return nil - } - - // Loop through srcs - wg := &sync.WaitGroup{} - wg.Add(len(srcs)) - for idx, src := range srcs { - func(idx int, src HTTPDownloaderSrc) { - // Update error with ctx - if ctx.Err() != nil { - err = ctx.Err() - } - - // Do nothing if error - if err != nil { - wg.Done() - return - } - - // Do - d.l.Do(func() { - // Task is done - defer wg.Done() - - // Do - if errD := d.do(ctx, fn, idx, src); errD != nil && err == nil { - err = errD - return - } - }) - }(idx, src) - } - - // Wait - wg.Wait() - return -} - -// DownloadInDirectory downloads in parallel a set of srcs and saves them in a dst directory -func (d *HTTPDownloader) DownloadInDirectory(ctx context.Context, dst string, srcs ...HTTPDownloaderSrc) error { - return d.download(ctx, srcs, func(ctx context.Context, idx int, buf *BufferPoolItem) (err error) { - // Make sure to close buffer - defer buf.Close() - - // Make sure destination directory exists - if err = os.MkdirAll(dst, DefaultDirMode); err != nil { - err = fmt.Errorf("astikit: mkdirall %s failed: %w", dst, err) - return - } - - // Create destination file - var f *os.File - dst := filepath.Join(dst, filepath.Base(srcs[idx].URL)) - if f, err = os.Create(dst); err != nil { - err = fmt.Errorf("astikit: creating %s failed: %w", dst, err) - return - } - defer f.Close() - - // Copy buffer - if _, err = Copy(ctx, f, buf); err != nil { - err = fmt.Errorf("astikit: copying content to %s failed: %w", dst, err) - return - } - return - }) -} - -// DownloadInWriter downloads in parallel a set of srcs and concatenates them in a writer while -// maintaining the initial order -func (d *HTTPDownloader) DownloadInWriter(ctx context.Context, dst io.Writer, srcs ...HTTPDownloaderSrc) error { - // Init - type chunk struct { - buf *BufferPoolItem - idx int - } - var cs []chunk - var m sync.Mutex // Locks cs - var requiredIdx int - - // Make sure to close all buffers - defer func() { - for _, c := range cs { - c.buf.Close() - } - }() - - // Download - return d.download(ctx, srcs, func(ctx context.Context, idx int, buf *BufferPoolItem) (err error) { - // Lock - m.Lock() - defer m.Unlock() - - // Check where to insert chunk - var idxInsert = -1 - for idxChunk := 0; idxChunk < len(cs); idxChunk++ { - if idx < cs[idxChunk].idx { - idxInsert = idxChunk - break - } - } - - // Create chunk - c := chunk{ - buf: buf, - idx: idx, - } - - // Add chunk - if idxInsert > -1 { - cs = append(cs[:idxInsert], append([]chunk{c}, cs[idxInsert:]...)...) - } else { - cs = append(cs, c) - } - - // Loop through chunks - for idxChunk := 0; idxChunk < len(cs); idxChunk++ { - // Get chunk - c := cs[idxChunk] - - // The chunk should be copied - if c.idx == requiredIdx { - // Copy chunk content - // Do not check error right away since we still want to close the buffer - // and remove the chunk - _, err = Copy(ctx, dst, c.buf) - - // Close buffer - c.buf.Close() - - // Remove chunk - requiredIdx++ - cs = append(cs[:idxChunk], cs[idxChunk+1:]...) - idxChunk-- - - // Check error - if err != nil { - err = fmt.Errorf("astikit: copying chunk #%d to dst failed: %w", c.idx, err) - return - } - } - } - return - }) -} - -// DownloadInFile downloads in parallel a set of srcs and concatenates them in a dst file while -// maintaining the initial order -func (d *HTTPDownloader) DownloadInFile(ctx context.Context, dst string, srcs ...HTTPDownloaderSrc) (err error) { - // Make sure destination directory exists - if err = os.MkdirAll(filepath.Dir(dst), DefaultDirMode); err != nil { - err = fmt.Errorf("astikit: mkdirall %s failed: %w", filepath.Dir(dst), err) - return - } - - // Create destination file - var f *os.File - if f, err = os.Create(dst); err != nil { - err = fmt.Errorf("astikit: creating %s failed: %w", dst, err) - return - } - defer f.Close() - - // Download in writer - return d.DownloadInWriter(ctx, f, srcs...) -} - -// HTTPMiddleware represents an HTTP middleware -type HTTPMiddleware func(http.Handler) http.Handler - -// ChainHTTPMiddlewares chains HTTP middlewares -func ChainHTTPMiddlewares(h http.Handler, ms ...HTTPMiddleware) http.Handler { - return ChainHTTPMiddlewaresWithPrefix(h, []string{}, ms...) -} - -// ChainHTTPMiddlewaresWithPrefix chains HTTP middlewares if one of prefixes is present -func ChainHTTPMiddlewaresWithPrefix(h http.Handler, prefixes []string, ms ...HTTPMiddleware) http.Handler { - for _, m := range ms { - if m == nil { - continue - } - if len(prefixes) == 0 { - h = m(h) - } else { - t := h - h = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - for _, prefix := range prefixes { - if strings.HasPrefix(r.URL.EscapedPath(), prefix) { - m(t).ServeHTTP(rw, r) - return - } - } - t.ServeHTTP(rw, r) - }) - } - } - return h -} - -func handleHTTPBasicAuth(username, password string, rw http.ResponseWriter, r *http.Request) bool { - if u, p, ok := r.BasicAuth(); !ok || u != username || p != password { - rw.Header().Set("WWW-Authenticate", "Basic Realm=Please enter your credentials") - rw.WriteHeader(http.StatusUnauthorized) - return true - } - return false -} - -// HTTPMiddlewareBasicAuth adds basic HTTP auth to an HTTP handler -func HTTPMiddlewareBasicAuth(username, password string) HTTPMiddleware { - if username == "" && password == "" { - return nil - } - return func(h http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - // Handle basic auth - if handleHTTPBasicAuth(username, password, rw, r) { - return - } - - // Next handler - h.ServeHTTP(rw, r) - }) - } -} - -func setHTTPContentType(contentType string, rw http.ResponseWriter) { - rw.Header().Set("Content-Type", contentType) -} - -// HTTPMiddlewareContentType adds a content type to an HTTP handler -func HTTPMiddlewareContentType(contentType string) HTTPMiddleware { - return func(h http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - // Set content type - setHTTPContentType(contentType, rw) - - // Next handler - h.ServeHTTP(rw, r) - }) - } -} - -func setHTTPHeaders(vs map[string]string, rw http.ResponseWriter) { - for k, v := range vs { - rw.Header().Set(k, v) - } -} - -// HTTPMiddlewareHeaders adds headers to an HTTP handler -func HTTPMiddlewareHeaders(vs map[string]string) HTTPMiddleware { - return func(h http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - // Set headers - setHTTPHeaders(vs, rw) - - // Next handler - h.ServeHTTP(rw, r) - }) - } -} - -// HTTPMiddlewareCORSHeaders adds CORS headers to an HTTP handler -func HTTPMiddlewareCORSHeaders() HTTPMiddleware { - return HTTPMiddlewareHeaders(map[string]string{ - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "*", - "Access-Control-Allow-Origin": "*", - }) -} diff --git a/vendor/github.com/asticode/go-astikit/io.go b/vendor/github.com/asticode/go-astikit/io.go deleted file mode 100644 index d9a2312c620..00000000000 --- a/vendor/github.com/asticode/go-astikit/io.go +++ /dev/null @@ -1,121 +0,0 @@ -package astikit - -import ( - "bytes" - "context" - "io" -) - -// Copy is a copy with a context -func Copy(ctx context.Context, dst io.Writer, src io.Reader) (int64, error) { - return io.Copy(dst, NewCtxReader(ctx, src)) -} - -type nopCloser struct { - io.Writer -} - -func (nopCloser) Close() error { return nil } - -// NopCloser returns a WriteCloser with a no-op Close method wrapping -// the provided Writer w. -func NopCloser(w io.Writer) io.WriteCloser { - return nopCloser{w} -} - -// CtxReader represents a reader with a context -type CtxReader struct { - ctx context.Context - reader io.Reader -} - -// NewCtxReader creates a reader with a context -func NewCtxReader(ctx context.Context, r io.Reader) *CtxReader { - return &CtxReader{ - ctx: ctx, - reader: r, - } -} - -// Read implements the io.Reader interface -func (r *CtxReader) Read(p []byte) (n int, err error) { - // Check context - if err = r.ctx.Err(); err != nil { - return - } - - // Read - return r.reader.Read(p) -} - -// WriterAdapter represents an object that can adapt a Writer -type WriterAdapter struct { - buffer *bytes.Buffer - o WriterAdapterOptions -} - -// WriterAdapterOptions represents WriterAdapter options -type WriterAdapterOptions struct { - Callback func(i []byte) - Split []byte -} - -// NewWriterAdapter creates a new WriterAdapter -func NewWriterAdapter(o WriterAdapterOptions) *WriterAdapter { - return &WriterAdapter{ - buffer: &bytes.Buffer{}, - o: o, - } -} - -// Close closes the adapter properly -func (w *WriterAdapter) Close() error { - if w.buffer.Len() > 0 { - w.write(w.buffer.Bytes()) - } - return nil -} - -// Write implements the io.Writer interface -func (w *WriterAdapter) Write(i []byte) (n int, err error) { - // Update n to avoid broken pipe error - defer func() { - n = len(i) - }() - - // Split - if len(w.o.Split) > 0 { - // Split bytes are not present, write in buffer - if !bytes.Contains(i, w.o.Split) { - w.buffer.Write(i) - return - } - - // Loop in split items - items := bytes.Split(i, w.o.Split) - for i := 0; i < len(items)-1; i++ { - // If this is the first item, prepend the buffer - if i == 0 { - items[i] = append(w.buffer.Bytes(), items[i]...) - w.buffer.Reset() - } - - // Write - w.write(items[i]) - } - - // Add remaining to buffer - w.buffer.Write(items[len(items)-1]) - return - } - - // By default, forward the bytes - w.write(i) - return -} - -func (w *WriterAdapter) write(i []byte) { - if w.o.Callback != nil { - w.o.Callback(i) - } -} diff --git a/vendor/github.com/asticode/go-astikit/limiter.go b/vendor/github.com/asticode/go-astikit/limiter.go deleted file mode 100644 index 4eadfc01658..00000000000 --- a/vendor/github.com/asticode/go-astikit/limiter.go +++ /dev/null @@ -1,101 +0,0 @@ -package astikit - -import ( - "context" - "sync" - "time" -) - -// Limiter represents a limiter -type Limiter struct { - buckets map[string]*LimiterBucket - m *sync.Mutex // Locks buckets -} - -// NewLimiter creates a new limiter -func NewLimiter() *Limiter { - return &Limiter{ - buckets: make(map[string]*LimiterBucket), - m: &sync.Mutex{}, - } -} - -// Add adds a new bucket -func (l *Limiter) Add(name string, cap int, period time.Duration) *LimiterBucket { - l.m.Lock() - defer l.m.Unlock() - if _, ok := l.buckets[name]; !ok { - l.buckets[name] = newLimiterBucket(cap, period) - } - return l.buckets[name] -} - -// Bucket retrieves a bucket from the limiter -func (l *Limiter) Bucket(name string) (b *LimiterBucket, ok bool) { - l.m.Lock() - defer l.m.Unlock() - b, ok = l.buckets[name] - return -} - -// Close closes the limiter properly -func (l *Limiter) Close() { - l.m.Lock() - defer l.m.Unlock() - for _, b := range l.buckets { - b.Close() - } -} - -// LimiterBucket represents a limiter bucket -type LimiterBucket struct { - cancel context.CancelFunc - cap int - ctx context.Context - count int - period time.Duration - o *sync.Once -} - -// newLimiterBucket creates a new bucket -func newLimiterBucket(cap int, period time.Duration) (b *LimiterBucket) { - b = &LimiterBucket{ - cap: cap, - count: 0, - period: period, - o: &sync.Once{}, - } - b.ctx, b.cancel = context.WithCancel(context.Background()) - go b.tick() - return -} - -// Inc increments the bucket count -func (b *LimiterBucket) Inc() bool { - if b.count >= b.cap { - return false - } - b.count++ - return true -} - -// tick runs a ticker to purge the bucket -func (b *LimiterBucket) tick() { - var t = time.NewTicker(b.period) - defer t.Stop() - for { - select { - case <-t.C: - b.count = 0 - case <-b.ctx.Done(): - return - } - } -} - -// close closes the bucket properly -func (b *LimiterBucket) Close() { - b.o.Do(func() { - b.cancel() - }) -} diff --git a/vendor/github.com/asticode/go-astikit/logger.go b/vendor/github.com/asticode/go-astikit/logger.go deleted file mode 100644 index b7623b992ec..00000000000 --- a/vendor/github.com/asticode/go-astikit/logger.go +++ /dev/null @@ -1,171 +0,0 @@ -package astikit - -import ( - "context" -) - -// CompleteLogger represents a complete logger -type CompleteLogger interface { - StdLogger - SeverityLogger - SeverityCtxLogger -} - -// StdLogger represents a standard logger -type StdLogger interface { - Fatal(v ...interface{}) - Fatalf(format string, v ...interface{}) - Print(v ...interface{}) - Printf(format string, v ...interface{}) -} - -// SeverityLogger represents a severity logger -type SeverityLogger interface { - Debug(v ...interface{}) - Debugf(format string, v ...interface{}) - Error(v ...interface{}) - Errorf(format string, v ...interface{}) - Info(v ...interface{}) - Infof(format string, v ...interface{}) - Warn(v ...interface{}) - Warnf(format string, v ...interface{}) -} - -// SeverityCtxLogger represents a severity with context logger -type SeverityCtxLogger interface { - DebugC(ctx context.Context, v ...interface{}) - DebugCf(ctx context.Context, format string, v ...interface{}) - ErrorC(ctx context.Context, v ...interface{}) - ErrorCf(ctx context.Context, format string, v ...interface{}) - FatalC(ctx context.Context, v ...interface{}) - FatalCf(ctx context.Context, format string, v ...interface{}) - InfoC(ctx context.Context, v ...interface{}) - InfoCf(ctx context.Context, format string, v ...interface{}) - WarnC(ctx context.Context, v ...interface{}) - WarnCf(ctx context.Context, format string, v ...interface{}) -} - -type completeLogger struct { - print, debug, error, fatal, info, warn func(v ...interface{}) - printf, debugf, errorf, fatalf, infof, warnf func(format string, v ...interface{}) - debugC, errorC, fatalC, infoC, warnC func(ctx context.Context, v ...interface{}) - debugCf, errorCf, fatalCf, infoCf, warnCf func(ctx context.Context, format string, v ...interface{}) -} - -func newCompleteLogger() *completeLogger { - return &completeLogger{ - debug: func(v ...interface{}) {}, - debugf: func(format string, v ...interface{}) {}, - debugC: func(ctx context.Context, v ...interface{}) {}, - debugCf: func(ctx context.Context, format string, v ...interface{}) {}, - error: func(v ...interface{}) {}, - errorf: func(format string, v ...interface{}) {}, - errorC: func(ctx context.Context, v ...interface{}) {}, - errorCf: func(ctx context.Context, format string, v ...interface{}) {}, - fatal: func(v ...interface{}) {}, - fatalf: func(format string, v ...interface{}) {}, - fatalC: func(ctx context.Context, v ...interface{}) {}, - fatalCf: func(ctx context.Context, format string, v ...interface{}) {}, - info: func(v ...interface{}) {}, - infof: func(format string, v ...interface{}) {}, - infoC: func(ctx context.Context, v ...interface{}) {}, - infoCf: func(ctx context.Context, format string, v ...interface{}) {}, - print: func(v ...interface{}) {}, - printf: func(format string, v ...interface{}) {}, - warn: func(v ...interface{}) {}, - warnf: func(format string, v ...interface{}) {}, - warnC: func(ctx context.Context, v ...interface{}) {}, - warnCf: func(ctx context.Context, format string, v ...interface{}) {}, - } -} - -func (l *completeLogger) Debug(v ...interface{}) { l.debug(v...) } -func (l *completeLogger) Debugf(format string, v ...interface{}) { l.debugf(format, v...) } -func (l *completeLogger) DebugC(ctx context.Context, v ...interface{}) { l.debugC(ctx, v...) } -func (l *completeLogger) DebugCf(ctx context.Context, format string, v ...interface{}) { - l.debugCf(ctx, format, v...) -} -func (l *completeLogger) Error(v ...interface{}) { l.error(v...) } -func (l *completeLogger) Errorf(format string, v ...interface{}) { l.errorf(format, v...) } -func (l *completeLogger) ErrorC(ctx context.Context, v ...interface{}) { l.errorC(ctx, v...) } -func (l *completeLogger) ErrorCf(ctx context.Context, format string, v ...interface{}) { - l.errorCf(ctx, format, v...) -} -func (l *completeLogger) Fatal(v ...interface{}) { l.fatal(v...) } -func (l *completeLogger) Fatalf(format string, v ...interface{}) { l.fatalf(format, v...) } -func (l *completeLogger) FatalC(ctx context.Context, v ...interface{}) { l.fatalC(ctx, v...) } -func (l *completeLogger) FatalCf(ctx context.Context, format string, v ...interface{}) { - l.fatalCf(ctx, format, v...) -} -func (l *completeLogger) Info(v ...interface{}) { l.info(v...) } -func (l *completeLogger) Infof(format string, v ...interface{}) { l.infof(format, v...) } -func (l *completeLogger) InfoC(ctx context.Context, v ...interface{}) { l.infoC(ctx, v...) } -func (l *completeLogger) InfoCf(ctx context.Context, format string, v ...interface{}) { - l.infoCf(ctx, format, v...) -} -func (l *completeLogger) Print(v ...interface{}) { l.print(v...) } -func (l *completeLogger) Printf(format string, v ...interface{}) { l.printf(format, v...) } -func (l *completeLogger) Warn(v ...interface{}) { l.warn(v...) } -func (l *completeLogger) Warnf(format string, v ...interface{}) { l.warnf(format, v...) } -func (l *completeLogger) WarnC(ctx context.Context, v ...interface{}) { l.warnC(ctx, v...) } -func (l *completeLogger) WarnCf(ctx context.Context, format string, v ...interface{}) { - l.warnCf(ctx, format, v...) -} - -// AdaptStdLogger transforms an StdLogger into a CompleteLogger if needed -func AdaptStdLogger(i StdLogger) CompleteLogger { - if v, ok := i.(CompleteLogger); ok { - return v - } - l := newCompleteLogger() - if i == nil { - return l - } - l.fatal = i.Fatal - l.fatalf = i.Fatalf - l.print = i.Print - l.printf = i.Printf - if v, ok := i.(SeverityLogger); ok { - l.debug = v.Debug - l.debugf = v.Debugf - l.error = v.Error - l.errorf = v.Errorf - l.info = v.Info - l.infof = v.Infof - l.warn = v.Warn - l.warnf = v.Warnf - } else { - l.debug = l.print - l.debugf = l.printf - l.error = l.print - l.errorf = l.printf - l.info = l.print - l.infof = l.printf - l.warn = l.print - l.warnf = l.printf - } - if v, ok := i.(SeverityCtxLogger); ok { - l.debugC = v.DebugC - l.debugCf = v.DebugCf - l.errorC = v.ErrorC - l.errorCf = v.ErrorCf - l.fatalC = v.FatalC - l.fatalCf = v.FatalCf - l.infoC = v.InfoC - l.infoCf = v.InfoCf - l.warnC = v.WarnC - l.warnCf = v.WarnCf - } else { - l.debugC = func(ctx context.Context, v ...interface{}) { l.debug(v...) } - l.debugCf = func(ctx context.Context, format string, v ...interface{}) { l.debugf(format, v...) } - l.errorC = func(ctx context.Context, v ...interface{}) { l.error(v...) } - l.errorCf = func(ctx context.Context, format string, v ...interface{}) { l.errorf(format, v...) } - l.fatalC = func(ctx context.Context, v ...interface{}) { l.fatal(v...) } - l.fatalCf = func(ctx context.Context, format string, v ...interface{}) { l.fatalf(format, v...) } - l.infoC = func(ctx context.Context, v ...interface{}) { l.info(v...) } - l.infoCf = func(ctx context.Context, format string, v ...interface{}) { l.infof(format, v...) } - l.warnC = func(ctx context.Context, v ...interface{}) { l.warn(v...) } - l.warnCf = func(ctx context.Context, format string, v ...interface{}) { l.warnf(format, v...) } - } - return l -} diff --git a/vendor/github.com/asticode/go-astikit/map.go b/vendor/github.com/asticode/go-astikit/map.go deleted file mode 100644 index 8ec17b20fb3..00000000000 --- a/vendor/github.com/asticode/go-astikit/map.go +++ /dev/null @@ -1,67 +0,0 @@ -package astikit - -import ( - "fmt" - "sync" -) - -// BiMap represents a bidirectional map -type BiMap struct { - forward map[interface{}]interface{} - inverse map[interface{}]interface{} - m *sync.Mutex -} - -// NewBiMap creates a new BiMap -func NewBiMap() *BiMap { - return &BiMap{ - forward: make(map[interface{}]interface{}), - inverse: make(map[interface{}]interface{}), - m: &sync.Mutex{}, - } -} - -func (m *BiMap) get(k interface{}, i map[interface{}]interface{}) (v interface{}, ok bool) { - m.m.Lock() - defer m.m.Unlock() - v, ok = i[k] - return -} - -// Get gets the value in the forward map based on the provided key -func (m *BiMap) Get(k interface{}) (interface{}, bool) { return m.get(k, m.forward) } - -// GetInverse gets the value in the inverse map based on the provided key -func (m *BiMap) GetInverse(k interface{}) (interface{}, bool) { return m.get(k, m.inverse) } - -// MustGet gets the value in the forward map based on the provided key and panics if key is not found -func (m *BiMap) MustGet(k interface{}) interface{} { - v, ok := m.get(k, m.forward) - if !ok { - panic(fmt.Sprintf("astikit: key %+v not found in foward map", k)) - } - return v -} - -// MustGetInverse gets the value in the inverse map based on the provided key and panics if key is not found -func (m *BiMap) MustGetInverse(k interface{}) interface{} { - v, ok := m.get(k, m.inverse) - if !ok { - panic(fmt.Sprintf("astikit: key %+v not found in inverse map", k)) - } - return v -} - -func (m *BiMap) set(k, v interface{}, f, i map[interface{}]interface{}) *BiMap { - m.m.Lock() - defer m.m.Unlock() - f[k] = v - i[v] = k - return m -} - -// Set sets the value in the forward and inverse map for the provided forward key -func (m *BiMap) Set(k, v interface{}) *BiMap { return m.set(k, v, m.forward, m.inverse) } - -// SetInverse sets the value in the forward and inverse map for the provided inverse key -func (m *BiMap) SetInverse(k, v interface{}) *BiMap { return m.set(k, v, m.inverse, m.forward) } diff --git a/vendor/github.com/asticode/go-astikit/os.go b/vendor/github.com/asticode/go-astikit/os.go deleted file mode 100644 index 3c9895c121a..00000000000 --- a/vendor/github.com/asticode/go-astikit/os.go +++ /dev/null @@ -1,148 +0,0 @@ -package astikit - -import ( - "context" - "fmt" - "os" - "path/filepath" - "strings" -) - -// MoveFile is a cancellable move of a local file to a local or remote location -func MoveFile(ctx context.Context, dst, src string, f CopyFileFunc) (err error) { - // Copy - if err = CopyFile(ctx, dst, src, f); err != nil { - err = fmt.Errorf("astikit: copying file %s to %s failed: %w", src, dst, err) - return - } - - // Delete - if err = os.Remove(src); err != nil { - err = fmt.Errorf("astikit: removing %s failed: %w", src, err) - return - } - return -} - -// CopyFileFunc represents a CopyFile func -type CopyFileFunc func(ctx context.Context, dst string, srcStat os.FileInfo, srcFile *os.File) error - -// CopyFile is a cancellable copy of a local file to a local or remote location -func CopyFile(ctx context.Context, dst, src string, f CopyFileFunc) (err error) { - // Check context - if err = ctx.Err(); err != nil { - return - } - - // Stat src - var srcStat os.FileInfo - if srcStat, err = os.Stat(src); err != nil { - err = fmt.Errorf("astikit: stating %s failed: %w", src, err) - return - } - - // Src is a dir - if srcStat.IsDir() { - // Walk through the dir - if err = filepath.Walk(src, func(path string, info os.FileInfo, errWalk error) (err error) { - // Check error - if errWalk != nil { - err = errWalk - return - } - - // Do not process root - if src == path { - return - } - - // Copy - p := filepath.Join(dst, strings.TrimPrefix(path, filepath.Clean(src))) - if err = CopyFile(ctx, p, path, f); err != nil { - err = fmt.Errorf("astikit: copying %s to %s failed: %w", path, p, err) - return - } - return nil - }); err != nil { - err = fmt.Errorf("astikit: walking through %s failed: %w", src, err) - return - } - return - } - - // Open src - var srcFile *os.File - if srcFile, err = os.Open(src); err != nil { - err = fmt.Errorf("astikit: opening %s failed: %w", src, err) - return - } - defer srcFile.Close() - - // Custom - if err = f(ctx, dst, srcStat, srcFile); err != nil { - err = fmt.Errorf("astikit: custom failed: %w", err) - return - } - return -} - -// LocalCopyFileFunc is the local CopyFileFunc that allows doing cross partition copies -func LocalCopyFileFunc(ctx context.Context, dst string, srcStat os.FileInfo, srcFile *os.File) (err error) { - // Check context - if err = ctx.Err(); err != nil { - return - } - - // Create the destination folder - if err = os.MkdirAll(filepath.Dir(dst), DefaultDirMode); err != nil { - err = fmt.Errorf("astikit: mkdirall %s failed: %w", filepath.Dir(dst), err) - return - } - - // Create the destination file - var dstFile *os.File - if dstFile, err = os.Create(dst); err != nil { - err = fmt.Errorf("astikit: creating %s failed: %w", dst, err) - return - } - defer dstFile.Close() - - // Chmod using os.chmod instead of file.Chmod - if err = os.Chmod(dst, srcStat.Mode()); err != nil { - err = fmt.Errorf("astikit: chmod %s %s failed, %w", dst, srcStat.Mode(), err) - return - } - - // Copy the content - if _, err = Copy(ctx, dstFile, srcFile); err != nil { - err = fmt.Errorf("astikit: copying content of %s to %s failed: %w", srcFile.Name(), dstFile.Name(), err) - return - } - return -} - -// SignalHandler represents a func that can handle a signal -type SignalHandler func(s os.Signal) - -// TermSignalHandler returns a SignalHandler that is executed only on a term signal -func TermSignalHandler(f func()) SignalHandler { - return func(s os.Signal) { - if isTermSignal(s) { - f() - } - } -} - -// LoggerSignalHandler returns a SignalHandler that logs the signal -func LoggerSignalHandler(l SeverityLogger, ignoredSignals ...os.Signal) SignalHandler { - ss := make(map[os.Signal]bool) - for _, s := range ignoredSignals { - ss[s] = true - } - return func(s os.Signal) { - if _, ok := ss[s]; ok { - return - } - l.Debugf("astikit: received signal %s", s) - } -} diff --git a/vendor/github.com/asticode/go-astikit/os_js.go b/vendor/github.com/asticode/go-astikit/os_js.go deleted file mode 100644 index 5403b2455b9..00000000000 --- a/vendor/github.com/asticode/go-astikit/os_js.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build js,wasm - -package astikit - -import ( - "os" - "syscall" -) - -func isTermSignal(s os.Signal) bool { - return s == syscall.SIGKILL || s == syscall.SIGINT || s == syscall.SIGQUIT || s == syscall.SIGTERM -} diff --git a/vendor/github.com/asticode/go-astikit/os_others.go b/vendor/github.com/asticode/go-astikit/os_others.go deleted file mode 100644 index 606e178f139..00000000000 --- a/vendor/github.com/asticode/go-astikit/os_others.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !js !wasm - -package astikit - -import ( - "os" - "syscall" -) - -func isTermSignal(s os.Signal) bool { - return s == syscall.SIGABRT || s == syscall.SIGKILL || s == syscall.SIGINT || s == syscall.SIGQUIT || s == syscall.SIGTERM -} diff --git a/vendor/github.com/asticode/go-astikit/pcm.go b/vendor/github.com/asticode/go-astikit/pcm.go deleted file mode 100644 index 8d6303b7c4c..00000000000 --- a/vendor/github.com/asticode/go-astikit/pcm.go +++ /dev/null @@ -1,426 +0,0 @@ -package astikit - -import ( - "fmt" - "math" - "sync" - "time" -) - -// PCMLevel computes the PCM level of samples -// https://dsp.stackexchange.com/questions/2951/loudness-of-pcm-stream -// https://dsp.stackexchange.com/questions/290/getting-loudness-of-a-track-with-rms?noredirect=1&lq=1 -func PCMLevel(samples []int) float64 { - // Compute sum of square values - var sum float64 - for _, s := range samples { - sum += math.Pow(float64(s), 2) - } - - // Square root - return math.Sqrt(sum / float64(len(samples))) -} - -func maxPCMSample(bitDepth int) int { - return int(math.Pow(2, float64(bitDepth))/2.0) - 1 -} - -// PCMNormalize normalizes the PCM samples -func PCMNormalize(samples []int, bitDepth int) (o []int) { - // Get max sample - var m int - for _, s := range samples { - if v := int(math.Abs(float64(s))); v > m { - m = v - } - } - - // Get max for bit depth - max := maxPCMSample(bitDepth) - - // Loop through samples - for _, s := range samples { - o = append(o, s*max/m) - } - return -} - -// ConvertPCMBitDepth converts the PCM bit depth -func ConvertPCMBitDepth(srcSample int, srcBitDepth, dstBitDepth int) (dstSample int, err error) { - // Nothing to do - if srcBitDepth == dstBitDepth { - dstSample = srcSample - return - } - - // Convert - if srcBitDepth < dstBitDepth { - dstSample = srcSample << uint(dstBitDepth-srcBitDepth) - } else { - dstSample = srcSample >> uint(srcBitDepth-dstBitDepth) - } - return -} - -// PCMSampleFunc is a func that can process a sample -type PCMSampleFunc func(s int) error - -// PCMSampleRateConverter is an object capable of converting a PCM's sample rate -type PCMSampleRateConverter struct { - b [][]int - dstSampleRate int - fn PCMSampleFunc - numChannels int - numChannelsProcessed int - numSamplesOutputed int - numSamplesProcessed int - srcSampleRate int -} - -// NewPCMSampleRateConverter creates a new PCMSampleRateConverter -func NewPCMSampleRateConverter(srcSampleRate, dstSampleRate, numChannels int, fn PCMSampleFunc) *PCMSampleRateConverter { - return &PCMSampleRateConverter{ - b: make([][]int, numChannels), - dstSampleRate: dstSampleRate, - fn: fn, - numChannels: numChannels, - srcSampleRate: srcSampleRate, - } -} - -// Reset resets the converter -func (c *PCMSampleRateConverter) Reset() { - c.b = make([][]int, c.numChannels) - c.numChannelsProcessed = 0 - c.numSamplesOutputed = 0 - c.numSamplesProcessed = 0 -} - -// Add adds a new sample to the converter -func (c *PCMSampleRateConverter) Add(i int) (err error) { - // Forward sample - if c.srcSampleRate == c.dstSampleRate { - if err = c.fn(i); err != nil { - err = fmt.Errorf("astikit: handling sample failed: %w", err) - return - } - return - } - - // Increment num channels processed - c.numChannelsProcessed++ - - // Reset num channels processed - if c.numChannelsProcessed > c.numChannels { - c.numChannelsProcessed = 1 - } - - // Only increment num samples processed if all channels have been processed - if c.numChannelsProcessed == c.numChannels { - c.numSamplesProcessed++ - } - - // Append sample to buffer - c.b[c.numChannelsProcessed-1] = append(c.b[c.numChannelsProcessed-1], i) - - // Throw away data - if c.srcSampleRate > c.dstSampleRate { - // Make sure to always keep the first sample but do nothing until we have all channels or target sample has been - // reached - if (c.numSamplesOutputed > 0 && float64(c.numSamplesProcessed) < 1.0+float64(c.numSamplesOutputed)*float64(c.srcSampleRate)/float64(c.dstSampleRate)) || c.numChannelsProcessed < c.numChannels { - return - } - - // Loop through channels - for idx, b := range c.b { - // Merge samples - var s int - for _, v := range b { - s += v - } - s /= len(b) - - // Reset buffer - c.b[idx] = []int{} - - // Custom - if err = c.fn(s); err != nil { - err = fmt.Errorf("astikit: handling sample failed: %w", err) - return - } - } - - // Increment num samples outputted - c.numSamplesOutputed++ - return - } - - // Do nothing until we have all channels - if c.numChannelsProcessed < c.numChannels { - return - } - - // Repeat data - for c.numSamplesOutputed == 0 || float64(c.numSamplesProcessed)+1.0 > 1.0+float64(c.numSamplesOutputed)*float64(c.srcSampleRate)/float64(c.dstSampleRate) { - // Loop through channels - for _, b := range c.b { - // Invalid length - if len(b) != 1 { - err = fmt.Errorf("astikit: invalid buffer item length %d", len(b)) - return - } - - // Custom - if err = c.fn(b[0]); err != nil { - err = fmt.Errorf("astikit: handling sample failed: %w", err) - return - } - } - - // Increment num samples outputted - c.numSamplesOutputed++ - } - - // Reset buffer - c.b = make([][]int, c.numChannels) - return -} - -// PCMChannelsConverter is an object of converting PCM's channels -type PCMChannelsConverter struct { - dstNumChannels int - fn PCMSampleFunc - srcNumChannels int - srcSamples int -} - -// NewPCMChannelsConverter creates a new PCMChannelsConverter -func NewPCMChannelsConverter(srcNumChannels, dstNumChannels int, fn PCMSampleFunc) *PCMChannelsConverter { - return &PCMChannelsConverter{ - dstNumChannels: dstNumChannels, - fn: fn, - srcNumChannels: srcNumChannels, - } -} - -// Reset resets the converter -func (c *PCMChannelsConverter) Reset() { - c.srcSamples = 0 -} - -// Add adds a new sample to the converter -func (c *PCMChannelsConverter) Add(i int) (err error) { - // Forward sample - if c.srcNumChannels == c.dstNumChannels { - if err = c.fn(i); err != nil { - err = fmt.Errorf("astikit: handling sample failed: %w", err) - return - } - return - } - - // Reset - if c.srcSamples == c.srcNumChannels { - c.srcSamples = 0 - } - - // Increment src samples - c.srcSamples++ - - // Throw away data - if c.srcNumChannels > c.dstNumChannels { - // Throw away sample - if c.srcSamples > c.dstNumChannels { - return - } - - // Custom - if err = c.fn(i); err != nil { - err = fmt.Errorf("astikit: handling sample failed: %w", err) - return - } - return - } - - // Store - var ss []int - if c.srcSamples < c.srcNumChannels { - ss = []int{i} - } else { - // Repeat data - for idx := c.srcNumChannels; idx <= c.dstNumChannels; idx++ { - ss = append(ss, i) - } - } - - // Loop through samples - for _, s := range ss { - // Custom - if err = c.fn(s); err != nil { - err = fmt.Errorf("astikit: handling sample failed: %w", err) - return - } - } - return -} - -// PCMSilenceDetector represents a PCM silence detector -type PCMSilenceDetector struct { - analyses []pcmSilenceDetectorAnalysis - buf []int - m *sync.Mutex // Locks buf - minAnalysesPerSilence int - o PCMSilenceDetectorOptions - samplesPerAnalysis int -} - -type pcmSilenceDetectorAnalysis struct { - level float64 - samples []int -} - -// PCMSilenceDetectorOptions represents a PCM silence detector options -type PCMSilenceDetectorOptions struct { - MaxSilenceLevel float64 `toml:"max_silence_level"` - MinSilenceDuration time.Duration `toml:"min_silence_duration"` - SampleRate int `toml:"sample_rate"` - StepDuration time.Duration `toml:"step_duration"` -} - -// NewPCMSilenceDetector creates a new silence detector -func NewPCMSilenceDetector(o PCMSilenceDetectorOptions) (d *PCMSilenceDetector) { - // Create - d = &PCMSilenceDetector{ - m: &sync.Mutex{}, - o: o, - } - - // Reset - d.Reset() - - // Default option values - if d.o.MinSilenceDuration == 0 { - d.o.MinSilenceDuration = time.Second - } - if d.o.StepDuration == 0 { - d.o.StepDuration = 30 * time.Millisecond - } - - // Compute attributes depending on options - d.samplesPerAnalysis = int(math.Floor(float64(d.o.SampleRate) * d.o.StepDuration.Seconds())) - d.minAnalysesPerSilence = int(math.Floor(d.o.MinSilenceDuration.Seconds() / d.o.StepDuration.Seconds())) - return -} - -// Reset resets the silence detector -func (d *PCMSilenceDetector) Reset() { - // Lock - d.m.Lock() - defer d.m.Unlock() - - // Reset - d.analyses = []pcmSilenceDetectorAnalysis{} - d.buf = []int{} -} - -// Add adds samples to the buffer and checks whether there are valid samples between silences -func (d *PCMSilenceDetector) Add(samples []int) (validSamples [][]int) { - // Lock - d.m.Lock() - defer d.m.Unlock() - - // Append samples to buffer - d.buf = append(d.buf, samples...) - - // Analyze samples by step - for len(d.buf) >= d.samplesPerAnalysis { - // Append analysis - d.analyses = append(d.analyses, pcmSilenceDetectorAnalysis{ - level: PCMLevel(d.buf[:d.samplesPerAnalysis]), - samples: append([]int(nil), d.buf[:d.samplesPerAnalysis]...), - }) - - // Remove samples from buffer - d.buf = d.buf[d.samplesPerAnalysis:] - } - - // Loop through analyses - var leadingSilence, inBetween, trailingSilence int - for i := 0; i < len(d.analyses); i++ { - if d.analyses[i].level < d.o.MaxSilenceLevel { - // This is a silence - - // This is a leading silence - if inBetween == 0 { - leadingSilence++ - - // The leading silence is valid - // We can trim its useless part - if leadingSilence > d.minAnalysesPerSilence { - d.analyses = d.analyses[leadingSilence-d.minAnalysesPerSilence:] - i -= leadingSilence - d.minAnalysesPerSilence - leadingSilence = d.minAnalysesPerSilence - } - continue - } - - // This is a trailing silence - trailingSilence++ - - // Trailing silence is invalid - if trailingSilence < d.minAnalysesPerSilence { - continue - } - - // Trailing silence is valid - // Loop through analyses - var ss []int - for _, a := range d.analyses[:i+1] { - ss = append(ss, a.samples...) - } - - // Append valid samples - validSamples = append(validSamples, ss) - - // Remove leading silence and non silence - d.analyses = d.analyses[leadingSilence+inBetween:] - i -= leadingSilence + inBetween - - // Reset counts - leadingSilence, inBetween, trailingSilence = trailingSilence, 0, 0 - } else { - // This is not a silence - - // This is a leading non silence - // We need to remove it - if i == 0 { - d.analyses = d.analyses[1:] - i = -1 - continue - } - - // This is the first in-between - if inBetween == 0 { - // The leading silence is invalid - // We need to remove it as well as this first non silence - if leadingSilence < d.minAnalysesPerSilence { - d.analyses = d.analyses[i+1:] - i = -1 - continue - } - } - - // This non-silence was preceded by a silence not big enough to be a valid trailing silence - // We incorporate it in the in-between - if trailingSilence > 0 { - inBetween += trailingSilence - trailingSilence = 0 - } - - // This is an in-between - inBetween++ - continue - } - } - return -} diff --git a/vendor/github.com/asticode/go-astikit/ptr.go b/vendor/github.com/asticode/go-astikit/ptr.go deleted file mode 100644 index fb3e7f5aea2..00000000000 --- a/vendor/github.com/asticode/go-astikit/ptr.go +++ /dev/null @@ -1,58 +0,0 @@ -package astikit - -import "time" - -// BoolPtr transforms a bool into a *bool -func BoolPtr(i bool) *bool { - return &i -} - -// BytePtr transforms a byte into a *byte -func BytePtr(i byte) *byte { - return &i -} - -// DurationPtr transforms a time.Duration into a *time.Duration -func DurationPtr(i time.Duration) *time.Duration { - return &i -} - -// Float64Ptr transforms a float64 into a *float64 -func Float64Ptr(i float64) *float64 { - return &i -} - -// IntPtr transforms an int into an *int -func IntPtr(i int) *int { - return &i -} - -// Int64Ptr transforms an int64 into an *int64 -func Int64Ptr(i int64) *int64 { - return &i -} - -// StrSlicePtr transforms a []string into a *[]string -func StrSlicePtr(i []string) *[]string { - return &i -} - -// StrPtr transforms a string into a *string -func StrPtr(i string) *string { - return &i -} - -// TimePtr transforms a time.Time into a *time.Time -func TimePtr(i time.Time) *time.Time { - return &i -} - -// UInt8Ptr transforms a uint8 into a *uint8 -func UInt8Ptr(i uint8) *uint8 { - return &i -} - -// UInt32Ptr transforms a uint32 into a *uint32 -func UInt32Ptr(i uint32) *uint32 { - return &i -} diff --git a/vendor/github.com/asticode/go-astikit/rand.go b/vendor/github.com/asticode/go-astikit/rand.go deleted file mode 100644 index c10e6db386d..00000000000 --- a/vendor/github.com/asticode/go-astikit/rand.go +++ /dev/null @@ -1,36 +0,0 @@ -package astikit - -import ( - "math/rand" - "strings" - "time" -) - -const ( - randLetterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" - randLetterIdxBits = 6 // 6 bits to represent a letter index - randLetterIdxMask = 1<= 0; { - if remain == 0 { - cache, remain = randSrc.Int63(), randLetterIdxMax - } - if idx := int(cache & randLetterIdxMask); idx < len(randLetterBytes) { - sb.WriteByte(randLetterBytes[idx]) - i-- - } - cache >>= randLetterIdxBits - remain-- - } - return sb.String() -} diff --git a/vendor/github.com/asticode/go-astikit/sort.go b/vendor/github.com/asticode/go-astikit/sort.go deleted file mode 100644 index 45539c6f567..00000000000 --- a/vendor/github.com/asticode/go-astikit/sort.go +++ /dev/null @@ -1,13 +0,0 @@ -package astikit - -import "sort" - -// SortInt64 sorts a slice of int64s in increasing order. -func SortInt64(a []int64) { sort.Sort(SortInt64Slice(a)) } - -// SortInt64Slice attaches the methods of Interface to []int64, sorting in increasing order. -type SortInt64Slice []int64 - -func (p SortInt64Slice) Len() int { return len(p) } -func (p SortInt64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p SortInt64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/github.com/asticode/go-astikit/ssh.go b/vendor/github.com/asticode/go-astikit/ssh.go deleted file mode 100644 index 5754895f030..00000000000 --- a/vendor/github.com/asticode/go-astikit/ssh.go +++ /dev/null @@ -1,113 +0,0 @@ -package astikit - -import ( - "context" - "fmt" - "io" - "os" - "path/filepath" -) - -// SSHSession represents an SSH Session -type SSHSession interface { - Run(string) error - Start(string) error - StdinPipe() (io.WriteCloser, error) - Wait() error -} - -// SSHSessionFunc represents a func that can return an SSHSession -type SSHSessionFunc func() (s SSHSession, c *Closer, err error) - -// SSHCopyFileFunc is the SSH CopyFileFunc that allows doing SSH copies -func SSHCopyFileFunc(fn SSHSessionFunc) CopyFileFunc { - return func(ctx context.Context, dst string, srcStat os.FileInfo, srcFile *os.File) (err error) { - // Check context - if err = ctx.Err(); err != nil { - return - } - - // Using local closure allows better readibility for the defer c.Close() since it - // isolates the use of the ssh session - if err = func() (err error) { - // Create ssh session - var s SSHSession - var c *Closer - if s, c, err = fn(); err != nil { - err = fmt.Errorf("astikit: creating ssh session failed: %w", err) - return - } - defer c.Close() - - // Create the destination folder - if err = s.Run("mkdir -p " + filepath.Dir(dst)); err != nil { - err = fmt.Errorf("astikit: creating %s failed: %w", filepath.Dir(dst), err) - return - } - return - }(); err != nil { - return - } - - // Using local closure allows better readibility for the defer c.Close() since it - // isolates the use of the ssh session - if err = func() (err error) { - // Create ssh session - var s SSHSession - var c *Closer - if s, c, err = fn(); err != nil { - err = fmt.Errorf("astikit: creating ssh session failed: %w", err) - return - } - defer c.Close() - - // Create stdin pipe - var stdin io.WriteCloser - if stdin, err = s.StdinPipe(); err != nil { - err = fmt.Errorf("astikit: creating stdin pipe failed: %w", err) - return - } - defer stdin.Close() - - // Use "scp" command - if err = s.Start("scp -qt \"" + filepath.Dir(dst) + "\""); err != nil { - err = fmt.Errorf("astikit: scp to %s failed: %w", dst, err) - return - } - - // Send metadata - if _, err = fmt.Fprintln(stdin, fmt.Sprintf("C%04o", srcStat.Mode().Perm()), srcStat.Size(), filepath.Base(dst)); err != nil { - err = fmt.Errorf("astikit: sending metadata failed: %w", err) - return - } - - // Copy - if _, err = Copy(ctx, stdin, srcFile); err != nil { - err = fmt.Errorf("astikit: copying failed: %w", err) - return - } - - // Send close - if _, err = fmt.Fprint(stdin, "\x00"); err != nil { - err = fmt.Errorf("astikit: sending close failed: %w", err) - return - } - - // Close stdin - if err = stdin.Close(); err != nil { - err = fmt.Errorf("astikit: closing failed: %w", err) - return - } - - // Wait - if err = s.Wait(); err != nil { - err = fmt.Errorf("astikit: waiting failed: %w", err) - return - } - return - }(); err != nil { - return - } - return - } -} diff --git a/vendor/github.com/asticode/go-astikit/stat.go b/vendor/github.com/asticode/go-astikit/stat.go deleted file mode 100644 index 6f66aed2abc..00000000000 --- a/vendor/github.com/asticode/go-astikit/stat.go +++ /dev/null @@ -1,301 +0,0 @@ -package astikit - -import ( - "context" - "sync" - "sync/atomic" - "time" -) - -// Stater is an object that can compute and handle stats -type Stater struct { - cancel context.CancelFunc - ctx context.Context - h StatsHandleFunc - m *sync.Mutex // Locks ss - period time.Duration - running uint32 - ss map[*StatMetadata]StatOptions -} - -// StatOptions represents stat options -type StatOptions struct { - Handler StatHandler - Metadata *StatMetadata -} - -// StatsHandleFunc is a method that can handle stat values -type StatsHandleFunc func(stats []StatValue) - -// StatMetadata represents a stat metadata -type StatMetadata struct { - Description string - Label string - Name string - Unit string -} - -// StatHandler represents a stat handler -type StatHandler interface { - Start() - Stop() - Value(delta time.Duration) interface{} -} - -// StatValue represents a stat value -type StatValue struct { - *StatMetadata - Value interface{} -} - -// StaterOptions represents stater options -type StaterOptions struct { - HandleFunc StatsHandleFunc - Period time.Duration -} - -// NewStater creates a new stater -func NewStater(o StaterOptions) *Stater { - return &Stater{ - h: o.HandleFunc, - m: &sync.Mutex{}, - period: o.Period, - ss: make(map[*StatMetadata]StatOptions), - } -} - -// Start starts the stater -func (s *Stater) Start(ctx context.Context) { - // Check context - if ctx.Err() != nil { - return - } - - // Make sure to start only once - if atomic.CompareAndSwapUint32(&s.running, 0, 1) { - // Update status - defer atomic.StoreUint32(&s.running, 0) - - // Reset context - s.ctx, s.cancel = context.WithCancel(ctx) - - // Create ticker - t := time.NewTicker(s.period) - defer t.Stop() - - // Loop - lastStatAt := now() - for { - select { - case <-t.C: - // Get delta - n := now() - delta := n.Sub(lastStatAt) - lastStatAt = n - - // Loop through stats - var stats []StatValue - s.m.Lock() - for _, v := range s.ss { - stats = append(stats, StatValue{ - StatMetadata: v.Metadata, - Value: v.Handler.Value(delta), - }) - } - s.m.Unlock() - - // Handle stats - go s.h(stats) - case <-s.ctx.Done(): - return - } - } - } -} - -// Stop stops the stater -func (s *Stater) Stop() { - if s.cancel != nil { - s.cancel() - } -} - -// AddStats adds stats -func (s *Stater) AddStats(os ...StatOptions) { - s.m.Lock() - defer s.m.Unlock() - for _, o := range os { - s.ss[o.Metadata] = o - } -} - -// DelStats deletes stats -func (s *Stater) DelStats(os ...StatOptions) { - s.m.Lock() - defer s.m.Unlock() - for _, o := range os { - delete(s.ss, o.Metadata) - } -} - -type durationStat struct { - d time.Duration - fn func(d, delta time.Duration) interface{} - isStarted bool - m *sync.Mutex // Locks isStarted - startedAt time.Time -} - -func newDurationStat(fn func(d, delta time.Duration) interface{}) *durationStat { - return &durationStat{ - fn: fn, - m: &sync.Mutex{}, - } -} - -func (s *durationStat) Begin() { - s.m.Lock() - defer s.m.Unlock() - if !s.isStarted { - return - } - s.startedAt = now() -} - -func (s *durationStat) End() { - s.m.Lock() - defer s.m.Unlock() - if !s.isStarted { - return - } - s.d += now().Sub(s.startedAt) - s.startedAt = time.Time{} -} - -func (s *durationStat) Value(delta time.Duration) (o interface{}) { - // Lock - s.m.Lock() - defer s.m.Unlock() - - // Get current values - n := now() - d := s.d - - // Recording is still in process - if !s.startedAt.IsZero() { - d += n.Sub(s.startedAt) - s.startedAt = n - } - - // Compute stat - o = s.fn(d, delta) - s.d = 0 - return -} - -func (s *durationStat) Start() { - s.m.Lock() - defer s.m.Unlock() - s.d = 0 - s.isStarted = true -} - -func (s *durationStat) Stop() { - s.m.Lock() - defer s.m.Unlock() - s.isStarted = false -} - -// DurationPercentageStat is an object capable of computing the percentage of time some work is taking per second -type DurationPercentageStat struct { - *durationStat -} - -// NewDurationPercentageStat creates a new duration percentage stat -func NewDurationPercentageStat() *DurationPercentageStat { - return &DurationPercentageStat{durationStat: newDurationStat(func(d, delta time.Duration) interface{} { - if delta == 0 { - return 0 - } - return float64(d) / float64(delta) * 100 - })} -} - -type counterStat struct { - c float64 - fn func(c, t float64, delta time.Duration) interface{} - isStarted bool - m *sync.Mutex // Locks isStarted - t float64 -} - -func newCounterStat(fn func(c, t float64, delta time.Duration) interface{}) *counterStat { - return &counterStat{ - fn: fn, - m: &sync.Mutex{}, - } -} - -func (s *counterStat) Add(delta float64) { - s.m.Lock() - defer s.m.Unlock() - if !s.isStarted { - return - } - s.c += delta - s.t++ -} - -func (s *counterStat) Start() { - s.m.Lock() - defer s.m.Unlock() - s.c = 0 - s.isStarted = true - s.t = 0 -} - -func (s *counterStat) Stop() { - s.m.Lock() - defer s.m.Unlock() - s.isStarted = true -} - -func (s *counterStat) Value(delta time.Duration) interface{} { - s.m.Lock() - defer s.m.Unlock() - c := s.c - t := s.t - s.c = 0 - s.t = 0 - return s.fn(c, t, delta) -} - -// CounterAvgStat is an object capable of computing the average value of a counter -type CounterAvgStat struct { - *counterStat -} - -// NewCounterAvgStat creates a new counter avg stat -func NewCounterAvgStat() *CounterAvgStat { - return &CounterAvgStat{counterStat: newCounterStat(func(c, t float64, delta time.Duration) interface{} { - if t == 0 { - return 0 - } - return c / t - })} -} - -// CounterRateStat is an object capable of computing the average value of a counter per second -type CounterRateStat struct { - *counterStat -} - -// NewCounterRateStat creates a new counter rate stat -func NewCounterRateStat() *CounterRateStat { - return &CounterRateStat{counterStat: newCounterStat(func(c, t float64, delta time.Duration) interface{} { - if delta.Seconds() == 0 { - return 0 - } - return c / delta.Seconds() - })} -} diff --git a/vendor/github.com/asticode/go-astikit/sync.go b/vendor/github.com/asticode/go-astikit/sync.go deleted file mode 100644 index afa2158bd93..00000000000 --- a/vendor/github.com/asticode/go-astikit/sync.go +++ /dev/null @@ -1,489 +0,0 @@ -package astikit - -import ( - "bytes" - "context" - "errors" - "fmt" - "runtime" - "sync" - "sync/atomic" - "time" -) - -// Stat names -const ( - StatNameWorkRatio = "astikit.work.ratio" -) - -// Chan constants -const ( - // Calling Add() only blocks if the chan has been started and the ctx - // has not been canceled - ChanAddStrategyBlockWhenStarted = "block.when.started" - // Calling Add() never blocks - ChanAddStrategyNoBlock = "no.block" - ChanOrderFIFO = "fifo" - ChanOrderFILO = "filo" -) - -// Chan is an object capable of executing funcs in a specific order while controlling the conditions -// in which adding new funcs is blocking -// Check out ChanOptions for detailed options -type Chan struct { - cancel context.CancelFunc - c *sync.Cond - ctx context.Context - fs []func() - mc *sync.Mutex // Locks ctx - mf *sync.Mutex // Locks fs - o ChanOptions - running uint32 - statWorkRatio *DurationPercentageStat -} - -// ChanOptions are Chan options -type ChanOptions struct { - // Determines the conditions in which Add() blocks. See constants with pattern ChanAddStrategy* - // Default is ChanAddStrategyNoBlock - AddStrategy string - // Order in which the funcs will be processed. See constants with pattern ChanOrder* - // Default is ChanOrderFIFO - Order string - // By default the funcs not yet processed when the context is cancelled are dropped. - // If "ProcessAll" is true, ALL funcs are processed even after the context is cancelled. - // However, no funcs can be added after the context is cancelled - ProcessAll bool -} - -// NewChan creates a new Chan -func NewChan(o ChanOptions) *Chan { - return &Chan{ - c: sync.NewCond(&sync.Mutex{}), - mc: &sync.Mutex{}, - mf: &sync.Mutex{}, - o: o, - } -} - -// Start starts the chan by looping through functions in the buffer and -// executing them if any, or waiting for a new one otherwise -func (c *Chan) Start(ctx context.Context) { - // Make sure to start only once - if atomic.CompareAndSwapUint32(&c.running, 0, 1) { - // Update status - defer atomic.StoreUint32(&c.running, 0) - - // Create context - c.mc.Lock() - c.ctx, c.cancel = context.WithCancel(ctx) - d := c.ctx.Done() - c.mc.Unlock() - - // Handle context - go func() { - // Wait for context to be done - <-d - - // Signal - c.c.L.Lock() - c.c.Signal() - c.c.L.Unlock() - }() - - // Loop - for { - // Lock cond here in case a func is added between retrieving l and doing the if on it - c.c.L.Lock() - - // Get number of funcs in buffer - c.mf.Lock() - l := len(c.fs) - c.mf.Unlock() - - // Only return if context has been cancelled and: - // - the user wants to drop funcs that has not yet been processed - // - the buffer is empty otherwise - c.mc.Lock() - if c.ctx.Err() != nil && (!c.o.ProcessAll || l == 0) { - c.mc.Unlock() - c.c.L.Unlock() - return - } - c.mc.Unlock() - - // No funcs in buffer - if l == 0 { - c.c.Wait() - c.c.L.Unlock() - continue - } - c.c.L.Unlock() - - // Get first func - c.mf.Lock() - fn := c.fs[0] - c.mf.Unlock() - - // Execute func - if c.statWorkRatio != nil { - c.statWorkRatio.Begin() - } - fn() - if c.statWorkRatio != nil { - c.statWorkRatio.End() - } - - // Remove first func - c.mf.Lock() - c.fs = c.fs[1:] - c.mf.Unlock() - } - } -} - -// Stop stops the chan -func (c *Chan) Stop() { - c.mc.Lock() - if c.cancel != nil { - c.cancel() - } - c.mc.Unlock() -} - -// Add adds a new item to the chan -func (c *Chan) Add(i func()) { - // Check context - c.mc.Lock() - if c.ctx != nil && c.ctx.Err() != nil { - c.mc.Unlock() - return - } - c.mc.Unlock() - - // Wrap the function - var fn func() - var wg *sync.WaitGroup - if c.o.AddStrategy == ChanAddStrategyBlockWhenStarted { - wg = &sync.WaitGroup{} - wg.Add(1) - fn = func() { - defer wg.Done() - i() - } - } else { - fn = i - } - - // Add func to buffer - c.mf.Lock() - if c.o.Order == ChanOrderFILO { - c.fs = append([]func(){fn}, c.fs...) - } else { - c.fs = append(c.fs, fn) - } - c.mf.Unlock() - - // Signal - c.c.L.Lock() - c.c.Signal() - c.c.L.Unlock() - - // Wait - if wg != nil { - wg.Wait() - } -} - -// Reset resets the chan -func (c *Chan) Reset() { - c.mf.Lock() - defer c.mf.Unlock() - c.fs = []func(){} -} - -// Stats returns the chan stats -func (c *Chan) Stats() []StatOptions { - if c.statWorkRatio == nil { - c.statWorkRatio = NewDurationPercentageStat() - } - return []StatOptions{ - { - Handler: c.statWorkRatio, - Metadata: &StatMetadata{ - Description: "Percentage of time doing work", - Label: "Work ratio", - Name: StatNameWorkRatio, - Unit: "%", - }, - }, - } -} - -// BufferPool represents a *bytes.Buffer pool -type BufferPool struct { - bp *sync.Pool -} - -// NewBufferPool creates a new BufferPool -func NewBufferPool() *BufferPool { - return &BufferPool{bp: &sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}} -} - -// New creates a new BufferPoolItem -func (p *BufferPool) New() *BufferPoolItem { - return newBufferPoolItem(p.bp.Get().(*bytes.Buffer), p.bp) -} - -// BufferPoolItem represents a BufferPool item -type BufferPoolItem struct { - *bytes.Buffer - bp *sync.Pool -} - -func newBufferPoolItem(b *bytes.Buffer, bp *sync.Pool) *BufferPoolItem { - return &BufferPoolItem{ - Buffer: b, - bp: bp, - } -} - -// Close implements the io.Closer interface -func (i *BufferPoolItem) Close() error { - i.Reset() - i.bp.Put(i.Buffer) - return nil -} - -// GoroutineLimiter is an object capable of doing several things in parallel while maintaining the -// max number of things running in parallel under a threshold -type GoroutineLimiter struct { - busy int - c *sync.Cond - ctx context.Context - cancel context.CancelFunc - o GoroutineLimiterOptions -} - -// GoroutineLimiterOptions represents GoroutineLimiter options -type GoroutineLimiterOptions struct { - Max int -} - -// NewGoroutineLimiter creates a new GoroutineLimiter -func NewGoroutineLimiter(o GoroutineLimiterOptions) (l *GoroutineLimiter) { - l = &GoroutineLimiter{ - c: sync.NewCond(&sync.Mutex{}), - o: o, - } - if l.o.Max <= 0 { - l.o.Max = 1 - } - l.ctx, l.cancel = context.WithCancel(context.Background()) - go l.handleCtx() - return -} - -// Close closes the limiter properly -func (l *GoroutineLimiter) Close() error { - l.cancel() - return nil -} - -func (l *GoroutineLimiter) handleCtx() { - <-l.ctx.Done() - l.c.L.Lock() - l.c.Broadcast() - l.c.L.Unlock() -} - -// GoroutineLimiterFunc is a GoroutineLimiter func -type GoroutineLimiterFunc func() - -// Do executes custom work in a goroutine -func (l *GoroutineLimiter) Do(fn GoroutineLimiterFunc) (err error) { - // Check context in case the limiter has already been closed - if err = l.ctx.Err(); err != nil { - return - } - - // Lock - l.c.L.Lock() - - // Wait for a goroutine to be available - for l.busy >= l.o.Max { - l.c.Wait() - } - - // Check context in case the limiter has been closed while waiting - if err = l.ctx.Err(); err != nil { - return - } - - // Increment - l.busy++ - - // Unlock - l.c.L.Unlock() - - // Execute in a goroutine - go func() { - // Decrement - defer func() { - l.c.L.Lock() - l.busy-- - l.c.Signal() - l.c.L.Unlock() - }() - - // Execute - fn() - }() - return -} - -// Eventer represents an object that can dispatch simple events (name + payload) -type Eventer struct { - c *Chan - hs map[string][]EventerHandler - mh *sync.Mutex -} - -// EventerOptions represents Eventer options -type EventerOptions struct { - Chan ChanOptions -} - -// EventerHandler represents a function that can handle the payload of an event -type EventerHandler func(payload interface{}) - -// NewEventer creates a new eventer -func NewEventer(o EventerOptions) *Eventer { - return &Eventer{ - c: NewChan(o.Chan), - hs: make(map[string][]EventerHandler), - mh: &sync.Mutex{}, - } -} - -// On adds an handler for a specific name -func (e *Eventer) On(name string, h EventerHandler) { - // Lock - e.mh.Lock() - defer e.mh.Unlock() - - // Add handler - e.hs[name] = append(e.hs[name], h) -} - -// Dispatch dispatches a payload for a specific name -func (e *Eventer) Dispatch(name string, payload interface{}) { - // Lock - e.mh.Lock() - defer e.mh.Unlock() - - // No handlers - hs, ok := e.hs[name] - if !ok { - return - } - - // Loop through handlers - for _, h := range hs { - func(h EventerHandler) { - // Add to chan - e.c.Add(func() { - h(payload) - }) - }(h) - } -} - -// Start starts the eventer. It is blocking -func (e *Eventer) Start(ctx context.Context) { - e.c.Start(ctx) -} - -// Stop stops the eventer -func (e *Eventer) Stop() { - e.c.Stop() -} - -// Reset resets the eventer -func (e *Eventer) Reset() { - e.c.Reset() -} - -// RWMutex represents a RWMutex capable of logging its actions to ease deadlock debugging -type RWMutex struct { - c string // Last successful caller - l SeverityLogger - m *sync.RWMutex - n string // Name -} - -// RWMutexOptions represents RWMutex options -type RWMutexOptions struct { - Logger StdLogger - Name string -} - -// NewRWMutex creates a new RWMutex -func NewRWMutex(o RWMutexOptions) *RWMutex { - return &RWMutex{ - l: AdaptStdLogger(o.Logger), - m: &sync.RWMutex{}, - n: o.Name, - } -} - -func (m *RWMutex) caller() (o string) { - if _, file, line, ok := runtime.Caller(2); ok { - o = fmt.Sprintf("%s:%d", file, line) - } - return -} - -// Lock write locks the mutex -func (m *RWMutex) Lock() { - c := m.caller() - m.l.Debugf("astikit: requesting lock for %s at %s", m.n, c) - m.m.Lock() - m.l.Debugf("astikit: lock acquired for %s at %s", m.n, c) - m.c = c -} - -// Unlock write unlocks the mutex -func (m *RWMutex) Unlock() { - m.m.Unlock() - m.l.Debugf("astikit: unlock executed for %s", m.n) -} - -// RLock read locks the mutex -func (m *RWMutex) RLock() { - c := m.caller() - m.l.Debugf("astikit: requesting rlock for %s at %s", m.n, c) - m.m.RLock() - m.l.Debugf("astikit: rlock acquired for %s at %s", m.n, c) - m.c = c -} - -// RUnlock read unlocks the mutex -func (m *RWMutex) RUnlock() { - m.m.RUnlock() - m.l.Debugf("astikit: unlock executed for %s", m.n) -} - -// IsDeadlocked checks whether the mutex is deadlocked with a given timeout -// and returns the last caller -func (m *RWMutex) IsDeadlocked(timeout time.Duration) (bool, string) { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - go func() { - m.m.Lock() - cancel() - m.m.Unlock() - }() - <-ctx.Done() - return errors.Is(ctx.Err(), context.DeadlineExceeded), m.c -} diff --git a/vendor/github.com/asticode/go-astikit/template.go b/vendor/github.com/asticode/go-astikit/template.go deleted file mode 100644 index 804ad77e1ac..00000000000 --- a/vendor/github.com/asticode/go-astikit/template.go +++ /dev/null @@ -1,156 +0,0 @@ -package astikit - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "sync" - "text/template" -) - -// Templater represents an object capable of storing and parsing templates -type Templater struct { - layouts []string - m sync.Mutex - templates map[string]*template.Template -} - -// NewTemplater creates a new templater -func NewTemplater() *Templater { - return &Templater{templates: make(map[string]*template.Template)} -} - -// AddLayoutsFromDir walks through a dir and add files as layouts -func (t *Templater) AddLayoutsFromDir(dirPath, ext string) (err error) { - // Get layouts - if err = filepath.Walk(dirPath, func(path string, info os.FileInfo, e error) (err error) { - // Check input error - if e != nil { - err = fmt.Errorf("astikit: walking layouts has an input error for path %s: %w", path, e) - return - } - - // Only process files - if info.IsDir() { - return - } - - // Check extension - if ext != "" && filepath.Ext(path) != ext { - return - } - - // Read layout - var b []byte - if b, err = ioutil.ReadFile(path); err != nil { - err = fmt.Errorf("astikit: reading %s failed: %w", path, err) - return - } - - // Add layout - t.AddLayout(string(b)) - return - }); err != nil { - err = fmt.Errorf("astikit: walking layouts in %s failed: %w", dirPath, err) - return - } - return -} - -// AddTemplatesFromDir walks through a dir and add files as templates -func (t *Templater) AddTemplatesFromDir(dirPath, ext string) (err error) { - // Loop through templates - if err = filepath.Walk(dirPath, func(path string, info os.FileInfo, e error) (err error) { - // Check input error - if e != nil { - err = fmt.Errorf("astikit: walking templates has an input error for path %s: %w", path, e) - return - } - - // Only process files - if info.IsDir() { - return - } - - // Check extension - if ext != "" && filepath.Ext(path) != ext { - return - } - - // Read file - var b []byte - if b, err = ioutil.ReadFile(path); err != nil { - err = fmt.Errorf("astikit: reading template content of %s failed: %w", path, err) - return - } - - // Add template - // We use ToSlash to homogenize Windows path - if err = t.AddTemplate(filepath.ToSlash(strings.TrimPrefix(path, dirPath)), string(b)); err != nil { - err = fmt.Errorf("astikit: adding template failed: %w", err) - return - } - return - }); err != nil { - err = fmt.Errorf("astikit: walking templates in %s failed: %w", dirPath, err) - return - } - return -} - -// AddLayout adds a new layout -func (t *Templater) AddLayout(c string) { - t.layouts = append(t.layouts, c) -} - -// AddTemplate adds a new template -func (t *Templater) AddTemplate(path, content string) (err error) { - // Parse - var tpl *template.Template - if tpl, err = t.Parse(content); err != nil { - err = fmt.Errorf("astikit: parsing template for path %s failed: %w", path, err) - return - } - - // Add template - t.m.Lock() - t.templates[path] = tpl - t.m.Unlock() - return -} - -// DelTemplate deletes a template -func (t *Templater) DelTemplate(path string) { - t.m.Lock() - defer t.m.Unlock() - delete(t.templates, path) -} - -// Template retrieves a templates -func (t *Templater) Template(path string) (tpl *template.Template, ok bool) { - t.m.Lock() - defer t.m.Unlock() - tpl, ok = t.templates[path] - return -} - -// Parse parses the content of a template -func (t *Templater) Parse(content string) (o *template.Template, err error) { - // Parse content - o = template.New("root") - if o, err = o.Parse(content); err != nil { - err = fmt.Errorf("astikit: parsing template content failed: %w", err) - return - } - - // Parse layouts - for idx, l := range t.layouts { - if o, err = o.Parse(l); err != nil { - err = fmt.Errorf("astikit: parsing layout #%d failed: %w", idx+1, err) - return - } - } - return -} diff --git a/vendor/github.com/asticode/go-astikit/time.go b/vendor/github.com/asticode/go-astikit/time.go deleted file mode 100644 index c30fa01735f..00000000000 --- a/vendor/github.com/asticode/go-astikit/time.go +++ /dev/null @@ -1,58 +0,0 @@ -package astikit - -import ( - "context" - "strconv" - "time" -) - -var now = func() time.Time { return time.Now() } - -// Sleep is a cancellable sleep -func Sleep(ctx context.Context, d time.Duration) (err error) { - for { - select { - case <-time.After(d): - return - case <-ctx.Done(): - err = ctx.Err() - return - } - } -} - -// Timestamp represents a timestamp you can marshal and umarshal -type Timestamp struct { - time.Time -} - -// NewTimestamp creates a new timestamp -func NewTimestamp(t time.Time) *Timestamp { - return &Timestamp{Time: t} -} - -// UnmarshalJSON implements the JSONUnmarshaler interface -func (t *Timestamp) UnmarshalJSON(text []byte) error { - return t.UnmarshalText(text) -} - -// UnmarshalText implements the TextUnmarshaler interface -func (t *Timestamp) UnmarshalText(text []byte) (err error) { - var i int - if i, err = strconv.Atoi(string(text)); err != nil { - return - } - t.Time = time.Unix(int64(i), 0) - return -} - -// MarshalJSON implements the JSONMarshaler interface -func (t Timestamp) MarshalJSON() ([]byte, error) { - return t.MarshalText() -} - -// MarshalText implements the TextMarshaler interface -func (t Timestamp) MarshalText() (text []byte, err error) { - text = []byte(strconv.Itoa(int(t.UTC().Unix()))) - return -} diff --git a/vendor/github.com/asticode/go-astikit/translator.go b/vendor/github.com/asticode/go-astikit/translator.go deleted file mode 100644 index 4e2c8310cd8..00000000000 --- a/vendor/github.com/asticode/go-astikit/translator.go +++ /dev/null @@ -1,184 +0,0 @@ -package astikit - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "os" - "path/filepath" - "strings" - "sync" -) - -// Translator represents an object capable of translating stuff -type Translator struct { - m *sync.RWMutex // Lock p - o TranslatorOptions - p map[string]string -} - -// TranslatorOptions represents Translator options -type TranslatorOptions struct { - DefaultLanguage string -} - -// NewTranslator creates a new Translator -func NewTranslator(o TranslatorOptions) *Translator { - return &Translator{ - m: &sync.RWMutex{}, - o: o, - p: make(map[string]string), - } -} - -// ParseDir adds translations located in ".json" files in the specified dir -func (t *Translator) ParseDir(dirPath string) (err error) { - // Default dir path - if dirPath == "" { - if dirPath, err = os.Getwd(); err != nil { - err = fmt.Errorf("astikit: getwd failed: %w", err) - return - } - } - - // Walk through dir - if err = filepath.Walk(dirPath, func(path string, info os.FileInfo, e error) (err error) { - // Check input error - if e != nil { - err = fmt.Errorf("astikit: walking %s has an input error for path %s: %w", dirPath, path, e) - return - } - - // Only process first level files - if info.IsDir() { - if path != dirPath { - err = filepath.SkipDir - } - return - } - - // Only process ".json" files - if filepath.Ext(path) != ".json" { - return - } - - // Parse file - if err = t.ParseFile(path); err != nil { - err = fmt.Errorf("astikit: parsing %s failed: %w", path, err) - return - } - return - }); err != nil { - err = fmt.Errorf("astikit: walking %s failed: %w", dirPath, err) - return - } - return -} - -// ParseFile adds translation located in the provided path -func (t *Translator) ParseFile(path string) (err error) { - // Lock - t.m.Lock() - defer t.m.Unlock() - - // Open file - var f *os.File - if f, err = os.Open(path); err != nil { - err = fmt.Errorf("astikit: opening %s failed: %w", path, err) - return - } - defer f.Close() - - // Unmarshal - var p map[string]interface{} - if err = json.NewDecoder(f).Decode(&p); err != nil { - err = fmt.Errorf("astikit: unmarshaling %s failed: %w", path, err) - return - } - - // Parse - t.parse(p, strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))) - return -} - -func (t *Translator) key(prefix, key string) string { - return prefix + "." + key -} - -func (t *Translator) parse(i map[string]interface{}, prefix string) { - for k, v := range i { - p := t.key(prefix, k) - switch a := v.(type) { - case string: - t.p[p] = a - case map[string]interface{}: - t.parse(a, p) - } - } -} - -// HTTPMiddleware is the Translator HTTP middleware -func (t *Translator) HTTPMiddleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - // Store language in context - if l := r.Header.Get("Accept-Language"); l != "" { - *r = *r.WithContext(contextWithTranslatorLanguage(r.Context(), l)) - } - - // Next handler - h.ServeHTTP(rw, r) - }) -} - -const contextKeyTranslatorLanguage = "astikit.translator.language" - -func contextWithTranslatorLanguage(ctx context.Context, language string) context.Context { - return context.WithValue(ctx, contextKeyTranslatorLanguage, language) -} - -func translatorLanguageFromContext(ctx context.Context) string { - v, ok := ctx.Value(contextKeyTranslatorLanguage).(string) - if !ok { - return "" - } - return v -} - -func (t *Translator) language(language string) string { - if language == "" { - return t.o.DefaultLanguage - } - return language -} - -// LanguageCtx returns the translator language from the context, or the default language if not in the context -func (t *Translator) LanguageCtx(ctx context.Context) string { - return t.language(translatorLanguageFromContext(ctx)) -} - -// Translate translates a key into a specific language -func (t *Translator) Translate(language, key string) string { - // Lock - t.m.RLock() - defer t.m.RUnlock() - - // Get translation - k1 := t.key(t.language(language), key) - v, ok := t.p[k1] - if ok { - return v - } - - // Default translation - k2 := t.key(t.o.DefaultLanguage, key) - if v, ok = t.p[k2]; ok { - return v - } - return k1 -} - -// TranslateCtx translates a key using the language specified in the context -func (t *Translator) TranslateCtx(ctx context.Context, key string) string { - return t.Translate(translatorLanguageFromContext(ctx), key) -} diff --git a/vendor/github.com/asticode/go-astikit/worker.go b/vendor/github.com/asticode/go-astikit/worker.go deleted file mode 100644 index b9a95a3a949..00000000000 --- a/vendor/github.com/asticode/go-astikit/worker.go +++ /dev/null @@ -1,148 +0,0 @@ -package astikit - -import ( - "context" - "os" - "os/signal" - "sync" -) - -// Worker represents an object capable of blocking, handling signals and stopping -type Worker struct { - cancel context.CancelFunc - ctx context.Context - l SeverityLogger - os, ow sync.Once - wg *sync.WaitGroup -} - -// WorkerOptions represents worker options -type WorkerOptions struct { - Logger StdLogger -} - -// NewWorker builds a new worker -func NewWorker(o WorkerOptions) (w *Worker) { - w = &Worker{ - l: AdaptStdLogger(o.Logger), - wg: &sync.WaitGroup{}, - } - w.ctx, w.cancel = context.WithCancel(context.Background()) - w.wg.Add(1) - w.l.Info("astikit: starting worker...") - return -} - -// HandleSignals handles signals -func (w *Worker) HandleSignals(hs ...SignalHandler) { - // Prepend mandatory handler - hs = append([]SignalHandler{TermSignalHandler(w.Stop)}, hs...) - - // Notify - ch := make(chan os.Signal, 1) - signal.Notify(ch) - - // Execute in a task - w.NewTask().Do(func() { - for { - select { - case s := <-ch: - // Loop through handlers - for _, h := range hs { - h(s) - } - - // Return - if isTermSignal(s) { - return - } - case <-w.Context().Done(): - return - } - } - }) -} - -// Stop stops the Worker -func (w *Worker) Stop() { - w.os.Do(func() { - w.l.Info("astikit: stopping worker...") - w.cancel() - w.wg.Done() - }) -} - -// Wait is a blocking pattern -func (w *Worker) Wait() { - w.ow.Do(func() { - w.l.Info("astikit: worker is now waiting...") - w.wg.Wait() - }) -} - -// NewTask creates a new task -func (w *Worker) NewTask() *Task { - return newTask(w.wg) -} - -// Context returns the worker's context -func (w *Worker) Context() context.Context { - return w.ctx -} - -// Logger returns the worker's logger -func (w *Worker) Logger() SeverityLogger { - return w.l -} - -// TaskFunc represents a function that can create a new task -type TaskFunc func() *Task - -// Task represents a task -type Task struct { - od, ow sync.Once - wg, pwg *sync.WaitGroup -} - -func newTask(parentWg *sync.WaitGroup) (t *Task) { - t = &Task{ - wg: &sync.WaitGroup{}, - pwg: parentWg, - } - t.pwg.Add(1) - return -} - -// NewSubTask creates a new sub task -func (t *Task) NewSubTask() *Task { - return newTask(t.wg) -} - -// Do executes the task -func (t *Task) Do(f func()) { - go func() { - // Make sure to mark the task as done - defer t.Done() - - // Custom - f() - - // Wait for first level subtasks to be done - // Wait() can also be called in f() if something needs to be executed just after Wait() - t.Wait() - }() -} - -// Done indicates the task is done -func (t *Task) Done() { - t.od.Do(func() { - t.pwg.Done() - }) -} - -// Wait waits for first level subtasks to be finished -func (t *Task) Wait() { - t.ow.Do(func() { - t.wg.Wait() - }) -} diff --git a/vendor/github.com/asticode/go-astisub/.gitignore b/vendor/github.com/asticode/go-astisub/.gitignore deleted file mode 100644 index 5be2b41d1f5..00000000000 --- a/vendor/github.com/asticode/go-astisub/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -Thumbs.db -.idea/ -cover* -test diff --git a/vendor/github.com/asticode/go-astisub/.travis.yml b/vendor/github.com/asticode/go-astisub/.travis.yml deleted file mode 100644 index 2295f8d4ee0..00000000000 --- a/vendor/github.com/asticode/go-astisub/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -go: -- 1.x -- tip -install: -- go get -t ./... -- go get golang.org/x/tools/cmd/cover -- go get github.com/mattn/goveralls -matrix: - allow_failures: - - go: tip -script: -- go test -race -v -coverprofile=coverage.out -- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci \ No newline at end of file diff --git a/vendor/github.com/asticode/go-astisub/LICENSE b/vendor/github.com/asticode/go-astisub/LICENSE deleted file mode 100644 index 606a4160fe7..00000000000 --- a/vendor/github.com/asticode/go-astisub/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Quentin Renard - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/asticode/go-astisub/README.md b/vendor/github.com/asticode/go-astisub/README.md deleted file mode 100644 index 43e7bd62b2c..00000000000 --- a/vendor/github.com/asticode/go-astisub/README.md +++ /dev/null @@ -1,95 +0,0 @@ -[![GoReportCard](http://goreportcard.com/badge/github.com/asticode/go-astisub)](http://goreportcard.com/report/github.com/asticode/go-astisub) -[![GoDoc](https://godoc.org/github.com/asticode/go-astisub?status.svg)](https://godoc.org/github.com/asticode/go-astisub) -[![Travis](https://travis-ci.com/asticode/go-astisub.svg?branch=master)](https://travis-ci.com/asticode/go-astisub#) -[![Coveralls](https://coveralls.io/repos/github/asticode/go-astisub/badge.svg?branch=master)](https://coveralls.io/github/asticode/go-astisub) - -This is a Golang library to manipulate subtitles. - -It allows you to manipulate `srt`, `stl`, `ttml`, `ssa/ass`, `webvtt` and `teletext` files for now. - -Available operations are `parsing`, `writing`, `syncing`, `fragmenting`, `unfragmenting`, `merging` and `optimizing`. - -# Installation - -To install the library: - - go get github.com/asticode/go-astisub - -To install the CLI: - - go install github.com/asticode/go-astisub/astisub - -# Using the library in your code - -WARNING: the code below doesn't handle errors for readibility purposes. However you SHOULD! - -```go -// Open subtitles -s1, _ := astisub.OpenFile("/path/to/example.ttml") -s2, _ := astisub.ReadFromSRT(bytes.NewReader([]byte("00:01:00.000 --> 00:02:00.000\nCredits"))) - -// Add a duration to every subtitles (syncing) -s1.Add(-2*time.Second) - -// Fragment the subtitles -s1.Fragment(2*time.Second) - -// Merge subtitles -s1.Merge(s2) - -// Optimize subtitles -s1.Optimize() - -// Unfragment the subtitles -s1.Unfragment() - -// Write subtitles -s1.Write("/path/to/example.srt") -var buf = &bytes.Buffer{} -s2.WriteToTTML(buf) -``` - -# Using the CLI - -If **astisub** has been installed properly you can: - -- convert any type of subtitle to any other type of subtitle: - - astisub convert -i example.srt -o example.ttml - -- fragment any type of subtitle: - - astisub fragment -i example.srt -f 2s -o example.out.srt - -- merge any type of subtitle into any other type of subtitle: - - astisub merge -i example.srt -i example.ttml -o example.out.srt - -- optimize any type of subtitle: - - astisub optimize -i example.srt -o example.out.srt - -- unfragment any type of subtitle: - - astisub unfragment -i example.srt -o example.out.srt - -- sync any type of subtitle: - - astisub sync -i example.srt -s "-2s" -o example.out.srt - -# Features and roadmap - -- [x] parsing -- [x] writing -- [x] syncing -- [x] fragmenting/unfragmenting -- [x] merging -- [x] ordering -- [x] optimizing -- [x] .srt -- [x] .ttml -- [x] .vtt -- [x] .stl -- [x] .ssa/.ass -- [x] .teletext -- [ ] .smi diff --git a/vendor/github.com/asticode/go-astisub/language.go b/vendor/github.com/asticode/go-astisub/language.go deleted file mode 100644 index a7c762abbb6..00000000000 --- a/vendor/github.com/asticode/go-astisub/language.go +++ /dev/null @@ -1,10 +0,0 @@ -package astisub - -// Languages -const ( - LanguageChinese = "chinese" - LanguageEnglish = "english" - LanguageFrench = "french" - LanguageJapanese = "japanese" - LanguageNorwegian = "norwegian" -) diff --git a/vendor/github.com/asticode/go-astisub/srt.go b/vendor/github.com/asticode/go-astisub/srt.go deleted file mode 100644 index 8e854e558f7..00000000000 --- a/vendor/github.com/asticode/go-astisub/srt.go +++ /dev/null @@ -1,159 +0,0 @@ -package astisub - -import ( - "bufio" - "fmt" - "io" - "strconv" - "strings" - "time" -) - -// Constants -const ( - srtTimeBoundariesSeparator = " --> " -) - -// Vars -var ( - bytesSRTTimeBoundariesSeparator = []byte(srtTimeBoundariesSeparator) -) - -// parseDurationSRT parses an .srt duration -func parseDurationSRT(i string) (time.Duration, error) { - return parseDuration(i, ",", 3) -} - -// ReadFromSRT parses an .srt content -func ReadFromSRT(i io.Reader) (o *Subtitles, err error) { - // Init - o = NewSubtitles() - var scanner = bufio.NewScanner(i) - - // Scan - var line string - var lineNum int - var s = &Item{} - for scanner.Scan() { - // Fetch line - line = strings.TrimSpace(scanner.Text()) - lineNum++ - - // Remove BOM header - if lineNum == 1 { - line = strings.TrimPrefix(line, string(BytesBOM)) - } - - // Line contains time boundaries - if strings.Contains(line, srtTimeBoundariesSeparator) { - // Return the wrong number of rows - if len(s.Lines) == 0 { - err = fmt.Errorf("astisub: line %d: no lines", lineNum) - return - } - - // Remove last item of previous subtitle since it's the index - index := s.Lines[len(s.Lines)-1] - s.Lines = s.Lines[:len(s.Lines)-1] - - // Remove trailing empty lines - if len(s.Lines) > 0 { - for i := len(s.Lines) - 1; i >= 0; i-- { - if len(s.Lines[i].Items) > 0 { - for j := len(s.Lines[i].Items) - 1; j >= 0; j-- { - if len(s.Lines[i].Items[j].Text) == 0 { - s.Lines[i].Items = s.Lines[i].Items[:j] - } else { - break - } - } - if len(s.Lines[i].Items) == 0 { - s.Lines = s.Lines[:i] - } - - } - } - } - - // Init subtitle - s = &Item{} - - // Fetch Index - s.Index, _ = strconv.Atoi(index.String()) - - // Extract time boundaries - s1 := strings.Split(line, srtTimeBoundariesSeparator) - if l := len(s1); l < 2 { - err = fmt.Errorf("astisub: line %d: time boundaries has only %d element(s)", lineNum, l) - return - } - // We do this to eliminate extra stuff like positions which are not documented anywhere - s2 := strings.Split(s1[1], " ") - - // Parse time boundaries - if s.StartAt, err = parseDurationSRT(s1[0]); err != nil { - err = fmt.Errorf("astisub: line %d: parsing srt duration %s failed: %w", lineNum, s1[0], err) - return - } - if s.EndAt, err = parseDurationSRT(s2[0]); err != nil { - err = fmt.Errorf("astisub: line %d: parsing srt duration %s failed: %w", lineNum, s2[0], err) - return - } - - // Append subtitle - o.Items = append(o.Items, s) - } else { - // Add text - s.Lines = append(s.Lines, Line{Items: []LineItem{{Text: strings.TrimSpace(line)}}}) - } - } - return -} - -// formatDurationSRT formats an .srt duration -func formatDurationSRT(i time.Duration) string { - return formatDuration(i, ",", 3) -} - -// WriteToSRT writes subtitles in .srt format -func (s Subtitles) WriteToSRT(o io.Writer) (err error) { - // Do not write anything if no subtitles - if len(s.Items) == 0 { - err = ErrNoSubtitlesToWrite - return - } - - // Add BOM header - var c []byte - c = append(c, BytesBOM...) - - // Loop through subtitles - for k, v := range s.Items { - // Add time boundaries - c = append(c, []byte(strconv.Itoa(k+1))...) - c = append(c, bytesLineSeparator...) - c = append(c, []byte(formatDurationSRT(v.StartAt))...) - c = append(c, bytesSRTTimeBoundariesSeparator...) - c = append(c, []byte(formatDurationSRT(v.EndAt))...) - c = append(c, bytesLineSeparator...) - - // Loop through lines - for _, l := range v.Lines { - c = append(c, []byte(l.String())...) - c = append(c, bytesLineSeparator...) - } - - // Add new line - c = append(c, bytesLineSeparator...) - } - - // Remove last new line - c = c[:len(c)-1] - - // Write - if _, err = o.Write(c); err != nil { - err = fmt.Errorf("astisub: writing failed: %w", err) - return - } - return -} diff --git a/vendor/github.com/asticode/go-astisub/ssa.go b/vendor/github.com/asticode/go-astisub/ssa.go deleted file mode 100644 index a3a00b0001a..00000000000 --- a/vendor/github.com/asticode/go-astisub/ssa.go +++ /dev/null @@ -1,1297 +0,0 @@ -package astisub - -import ( - "bufio" - "fmt" - "io" - "log" - "regexp" - "sort" - "strconv" - "strings" - "time" - - "github.com/asticode/go-astikit" -) - -// https://www.matroska.org/technical/specs/subtitles/ssa.html -// http://moodub.free.fr/video/ass-specs.doc -// https://en.wikipedia.org/wiki/SubStation_Alpha - -// SSA alignment -const ( - ssaAlignmentCentered = 2 - ssaAlignmentLeft = 1 - ssaAlignmentLeftJustifiedTopTitle = 5 - ssaAlignmentMidTitle = 8 - ssaAlignmentRight = 3 - ssaAlignmentTopTitle = 4 -) - -// SSA border styles -const ( - ssaBorderStyleOpaqueBox = 3 - ssaBorderStyleOutlineAndDropShadow = 1 -) - -// SSA collisions -const ( - ssaCollisionsNormal = "Normal" - ssaCollisionsReverse = "Reverse" -) - -// SSA event categories -const ( - ssaEventCategoryCommand = "Command" - ssaEventCategoryComment = "Comment" - ssaEventCategoryDialogue = "Dialogue" - ssaEventCategoryMovie = "Movie" - ssaEventCategoryPicture = "Picture" - ssaEventCategorySound = "Sound" -) - -// SSA event format names -const ( - ssaEventFormatNameEffect = "Effect" - ssaEventFormatNameEnd = "End" - ssaEventFormatNameLayer = "Layer" - ssaEventFormatNameMarginL = "MarginL" - ssaEventFormatNameMarginR = "MarginR" - ssaEventFormatNameMarginV = "MarginV" - ssaEventFormatNameMarked = "Marked" - ssaEventFormatNameName = "Name" - ssaEventFormatNameStart = "Start" - ssaEventFormatNameStyle = "Style" - ssaEventFormatNameText = "Text" -) - -// SSA script info names -const ( - ssaScriptInfoNameCollisions = "Collisions" - ssaScriptInfoNameOriginalEditing = "Original Editing" - ssaScriptInfoNameOriginalScript = "Original Script" - ssaScriptInfoNameOriginalTiming = "Original Timing" - ssaScriptInfoNameOriginalTranslation = "Original Translation" - ssaScriptInfoNamePlayDepth = "PlayDepth" - ssaScriptInfoNamePlayResX = "PlayResX" - ssaScriptInfoNamePlayResY = "PlayResY" - ssaScriptInfoNameScriptType = "ScriptType" - ssaScriptInfoNameScriptUpdatedBy = "Script Updated By" - ssaScriptInfoNameSynchPoint = "Synch Point" - ssaScriptInfoNameTimer = "Timer" - ssaScriptInfoNameTitle = "Title" - ssaScriptInfoNameUpdateDetails = "Update Details" - ssaScriptInfoNameWrapStyle = "WrapStyle" -) - -// SSA section names -const ( - ssaSectionNameEvents = "events" - ssaSectionNameScriptInfo = "script.info" - ssaSectionNameStyles = "styles" - ssaSectionNameUnknown = "unknown" -) - -// SSA style format names -const ( - ssaStyleFormatNameAlignment = "Alignment" - ssaStyleFormatNameAlphaLevel = "AlphaLevel" - ssaStyleFormatNameAngle = "Angle" - ssaStyleFormatNameBackColour = "BackColour" - ssaStyleFormatNameBold = "Bold" - ssaStyleFormatNameBorderStyle = "BorderStyle" - ssaStyleFormatNameEncoding = "Encoding" - ssaStyleFormatNameFontName = "Fontname" - ssaStyleFormatNameFontSize = "Fontsize" - ssaStyleFormatNameItalic = "Italic" - ssaStyleFormatNameMarginL = "MarginL" - ssaStyleFormatNameMarginR = "MarginR" - ssaStyleFormatNameMarginV = "MarginV" - ssaStyleFormatNameName = "Name" - ssaStyleFormatNameOutline = "Outline" - ssaStyleFormatNameOutlineColour = "OutlineColour" - ssaStyleFormatNamePrimaryColour = "PrimaryColour" - ssaStyleFormatNameScaleX = "ScaleX" - ssaStyleFormatNameScaleY = "ScaleY" - ssaStyleFormatNameSecondaryColour = "SecondaryColour" - ssaStyleFormatNameShadow = "Shadow" - ssaStyleFormatNameSpacing = "Spacing" - ssaStyleFormatNameStrikeout = "Strikeout" - ssaStyleFormatNameTertiaryColour = "TertiaryColour" - ssaStyleFormatNameUnderline = "Underline" -) - -// SSA wrap style -const ( - ssaWrapStyleEndOfLineWordWrapping = "1" - ssaWrapStyleNoWordWrapping = "2" - ssaWrapStyleSmartWrapping = "0" - ssaWrapStyleSmartWrappingWithLowerLinesGettingWider = "3" -) - -// SSA regexp -var ssaRegexpEffect = regexp.MustCompile(`\{[^\{]+\}`) - -// ReadFromSSA parses an .ssa content -func ReadFromSSA(i io.Reader) (o *Subtitles, err error) { - o, err = ReadFromSSAWithOptions(i, defaultSSAOptions()) - return o, err -} - -// ReadFromSSAWithOptions parses an .ssa content -func ReadFromSSAWithOptions(i io.Reader, opts SSAOptions) (o *Subtitles, err error) { - // Init - o = NewSubtitles() - var scanner = bufio.NewScanner(i) - var si = &ssaScriptInfo{} - var ss = []*ssaStyle{} - var es = []*ssaEvent{} - - // Scan - var line, sectionName string - var format map[int]string - isFirstLine := true - for scanner.Scan() { - // Fetch line - line = strings.TrimSpace(scanner.Text()) - - // Remove BOM header - if isFirstLine { - line = strings.TrimPrefix(line, string(BytesBOM)) - isFirstLine = false - } - - // Empty line - if len(line) == 0 { - continue - } - - // Section name - if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { - switch strings.ToLower(line[1 : len(line)-1]) { - case "events": - sectionName = ssaSectionNameEvents - format = make(map[int]string) - continue - case "script info": - sectionName = ssaSectionNameScriptInfo - continue - case "v4 styles", "v4+ styles", "v4 styles+": - sectionName = ssaSectionNameStyles - format = make(map[int]string) - continue - default: - if opts.OnUnknownSectionName != nil { - opts.OnUnknownSectionName(line) - } - sectionName = ssaSectionNameUnknown - continue - } - } - - // Unknown section - if sectionName == ssaSectionNameUnknown { - continue - } - - // Comment - if len(line) > 0 && line[0] == ';' { - si.comments = append(si.comments, strings.TrimSpace(line[1:])) - continue - } - - // Split on ":" - var split = strings.Split(line, ":") - if len(split) < 2 || split[0] == "" { - if opts.OnInvalidLine != nil { - opts.OnInvalidLine(line) - } - continue - } - var header = strings.TrimSpace(split[0]) - var content = strings.TrimSpace(strings.Join(split[1:], ":")) - - // Switch on section name - switch sectionName { - case ssaSectionNameScriptInfo: - if err = si.parse(header, content); err != nil { - err = fmt.Errorf("astisub: parsing script info block failed: %w", err) - return - } - case ssaSectionNameEvents, ssaSectionNameStyles: - // Parse format - if header == "Format" { - for idx, item := range strings.Split(content, ",") { - format[idx] = strings.TrimSpace(item) - } - } else { - // No format provided - if len(format) == 0 { - err = fmt.Errorf("astisub: no %s format provided", sectionName) - return - } - - // Switch on section name - switch sectionName { - case ssaSectionNameEvents: - var e *ssaEvent - if e, err = newSSAEventFromString(header, content, format); err != nil { - err = fmt.Errorf("astisub: building new ssa event failed: %w", err) - return - } - es = append(es, e) - case ssaSectionNameStyles: - var s *ssaStyle - if s, err = newSSAStyleFromString(content, format); err != nil { - err = fmt.Errorf("astisub: building new ssa style failed: %w", err) - return - } - ss = append(ss, s) - } - } - } - } - - // Set metadata - o.Metadata = si.metadata() - - // Loop through styles - for _, s := range ss { - var st = s.style() - o.Styles[st.ID] = st - } - - // Loop through events - for _, e := range es { - // Only process dialogues - if e.category == ssaEventCategoryDialogue { - // Build item - var item *Item - if item, err = e.item(o.Styles); err != nil { - return - } - - // Append item - o.Items = append(o.Items, item) - } - } - return -} - -// newColorFromSSAColor builds a new color based on an SSA color -func newColorFromSSAColor(i string) (_ *Color, _ error) { - // Empty - if len(i) == 0 { - return - } - - // Check whether input is decimal or hexadecimal - var s = i - var base = 10 - if strings.HasPrefix(i, "&H") { - s = i[2:] - base = 16 - } - return newColorFromSSAString(s, base) -} - -// newSSAColorFromColor builds a new SSA color based on a color -func newSSAColorFromColor(i *Color) string { - return "&H" + i.SSAString() -} - -// ssaScriptInfo represents an SSA script info block -type ssaScriptInfo struct { - collisions string - comments []string - originalEditing string - originalScript string - originalTiming string - originalTranslation string - playDepth *int - playResX, playResY *int - scriptType string - scriptUpdatedBy string - synchPoint string - timer *float64 - title string - updateDetails string - wrapStyle string -} - -// newSSAScriptInfo builds an SSA script info block based on metadata -func newSSAScriptInfo(m *Metadata) (o *ssaScriptInfo) { - // Init - o = &ssaScriptInfo{} - - // Add metadata - if m != nil { - o.collisions = m.SSACollisions - o.comments = m.Comments - o.originalEditing = m.SSAOriginalEditing - o.originalScript = m.SSAOriginalScript - o.originalTiming = m.SSAOriginalTiming - o.originalTranslation = m.SSAOriginalTranslation - o.playDepth = m.SSAPlayDepth - o.playResX = m.SSAPlayResX - o.playResY = m.SSAPlayResY - o.scriptType = m.SSAScriptType - o.scriptUpdatedBy = m.SSAScriptUpdatedBy - o.synchPoint = m.SSASynchPoint - o.timer = m.SSATimer - o.title = m.Title - o.updateDetails = m.SSAUpdateDetails - o.wrapStyle = m.SSAWrapStyle - } - return -} - -// parse parses a script info header/content -func (b *ssaScriptInfo) parse(header, content string) (err error) { - switch header { - case ssaScriptInfoNameCollisions: - b.collisions = content - case ssaScriptInfoNameOriginalEditing: - b.originalEditing = content - case ssaScriptInfoNameOriginalScript: - b.originalScript = content - case ssaScriptInfoNameOriginalTiming: - b.originalTiming = content - case ssaScriptInfoNameOriginalTranslation: - b.originalTranslation = content - case ssaScriptInfoNameScriptType: - b.scriptType = content - case ssaScriptInfoNameScriptUpdatedBy: - b.scriptUpdatedBy = content - case ssaScriptInfoNameSynchPoint: - b.synchPoint = content - case ssaScriptInfoNameTitle: - b.title = content - case ssaScriptInfoNameUpdateDetails: - b.updateDetails = content - case ssaScriptInfoNameWrapStyle: - b.wrapStyle = content - // Int - case ssaScriptInfoNamePlayResX, ssaScriptInfoNamePlayResY, ssaScriptInfoNamePlayDepth: - var v int - if v, err = strconv.Atoi(content); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", content, err) - } - switch header { - case ssaScriptInfoNamePlayDepth: - b.playDepth = astikit.IntPtr(v) - case ssaScriptInfoNamePlayResX: - b.playResX = astikit.IntPtr(v) - case ssaScriptInfoNamePlayResY: - b.playResY = astikit.IntPtr(v) - } - // Float - case ssaScriptInfoNameTimer: - var v float64 - if v, err = strconv.ParseFloat(strings.Replace(content, ",", ".", -1), 64); err != nil { - err = fmt.Errorf("astisub: parseFloat of %s failed: %w", content, err) - } - b.timer = astikit.Float64Ptr(v) - } - return -} - -// metadata returns the block as Metadata -func (b *ssaScriptInfo) metadata() *Metadata { - return &Metadata{ - Comments: b.comments, - SSACollisions: b.collisions, - SSAOriginalEditing: b.originalEditing, - SSAOriginalScript: b.originalScript, - SSAOriginalTiming: b.originalTiming, - SSAOriginalTranslation: b.originalTranslation, - SSAPlayDepth: b.playDepth, - SSAPlayResX: b.playResX, - SSAPlayResY: b.playResY, - SSAScriptType: b.scriptType, - SSAScriptUpdatedBy: b.scriptUpdatedBy, - SSASynchPoint: b.synchPoint, - SSATimer: b.timer, - SSAUpdateDetails: b.updateDetails, - SSAWrapStyle: b.wrapStyle, - Title: b.title, - } -} - -// bytes returns the block as bytes -func (b *ssaScriptInfo) bytes() (o []byte) { - o = []byte("[Script Info]") - o = append(o, bytesLineSeparator...) - for _, c := range b.comments { - o = appendStringToBytesWithNewLine(o, "; "+c) - } - if len(b.collisions) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameCollisions+": "+b.collisions) - } - if len(b.originalEditing) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameOriginalEditing+": "+b.originalEditing) - } - if len(b.originalScript) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameOriginalScript+": "+b.originalScript) - } - if len(b.originalTiming) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameOriginalTiming+": "+b.originalTiming) - } - if len(b.originalTranslation) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameOriginalTranslation+": "+b.originalTranslation) - } - if b.playDepth != nil { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNamePlayDepth+": "+strconv.Itoa(*b.playDepth)) - } - if b.playResX != nil { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNamePlayResX+": "+strconv.Itoa(*b.playResX)) - } - if b.playResY != nil { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNamePlayResY+": "+strconv.Itoa(*b.playResY)) - } - if len(b.scriptType) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameScriptType+": "+b.scriptType) - } - if len(b.scriptUpdatedBy) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameScriptUpdatedBy+": "+b.scriptUpdatedBy) - } - if len(b.synchPoint) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameSynchPoint+": "+b.synchPoint) - } - if b.timer != nil { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameTimer+": "+strings.Replace(strconv.FormatFloat(*b.timer, 'f', -1, 64), ".", ",", -1)) - } - if len(b.title) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameTitle+": "+b.title) - } - if len(b.updateDetails) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameUpdateDetails+": "+b.updateDetails) - } - if len(b.wrapStyle) > 0 { - o = appendStringToBytesWithNewLine(o, ssaScriptInfoNameWrapStyle+": "+b.wrapStyle) - } - return -} - -// ssaStyle represents an SSA style -type ssaStyle struct { - alignment *int - alphaLevel *float64 - angle *float64 // degrees - backColour *Color - bold *bool - borderStyle *int - encoding *int - fontName string - fontSize *float64 - italic *bool - outline *float64 // pixels - outlineColour *Color - marginLeft *int // pixels - marginRight *int // pixels - marginVertical *int // pixels - name string - primaryColour *Color - scaleX *float64 // % - scaleY *float64 // % - secondaryColour *Color - shadow *float64 // pixels - spacing *float64 // pixels - strikeout *bool - underline *bool -} - -// newSSAStyleFromStyle returns an SSA style based on a Style -func newSSAStyleFromStyle(i Style) *ssaStyle { - return &ssaStyle{ - alignment: i.InlineStyle.SSAAlignment, - alphaLevel: i.InlineStyle.SSAAlphaLevel, - angle: i.InlineStyle.SSAAngle, - backColour: i.InlineStyle.SSABackColour, - bold: i.InlineStyle.SSABold, - borderStyle: i.InlineStyle.SSABorderStyle, - encoding: i.InlineStyle.SSAEncoding, - fontName: i.InlineStyle.SSAFontName, - fontSize: i.InlineStyle.SSAFontSize, - italic: i.InlineStyle.SSAItalic, - outline: i.InlineStyle.SSAOutline, - outlineColour: i.InlineStyle.SSAOutlineColour, - marginLeft: i.InlineStyle.SSAMarginLeft, - marginRight: i.InlineStyle.SSAMarginRight, - marginVertical: i.InlineStyle.SSAMarginVertical, - name: i.ID, - primaryColour: i.InlineStyle.SSAPrimaryColour, - scaleX: i.InlineStyle.SSAScaleX, - scaleY: i.InlineStyle.SSAScaleY, - secondaryColour: i.InlineStyle.SSASecondaryColour, - shadow: i.InlineStyle.SSAShadow, - spacing: i.InlineStyle.SSASpacing, - strikeout: i.InlineStyle.SSAStrikeout, - underline: i.InlineStyle.SSAUnderline, - } -} - -// newSSAStyleFromString returns an SSA style based on an input string and a format -func newSSAStyleFromString(content string, format map[int]string) (s *ssaStyle, err error) { - // Split content - var items = strings.Split(content, ",") - - // Not enough items - if len(items) < len(format) { - err = fmt.Errorf("astisub: content has %d items whereas style format has %d items", len(items), len(format)) - return - } - - // Loop through items - s = &ssaStyle{} - for idx, item := range items { - // Index not found in format - var attr string - var ok bool - if attr, ok = format[idx]; !ok { - err = fmt.Errorf("astisub: index %d not found in style format %+v", idx, format) - return - } - - // Switch on attribute name - switch attr { - // Bool - case ssaStyleFormatNameBold, ssaStyleFormatNameItalic, ssaStyleFormatNameStrikeout, - ssaStyleFormatNameUnderline: - var b = item == "-1" - switch attr { - case ssaStyleFormatNameBold: - s.bold = astikit.BoolPtr(b) - case ssaStyleFormatNameItalic: - s.italic = astikit.BoolPtr(b) - case ssaStyleFormatNameStrikeout: - s.strikeout = astikit.BoolPtr(b) - case ssaStyleFormatNameUnderline: - s.underline = astikit.BoolPtr(b) - } - // Color - case ssaStyleFormatNamePrimaryColour, ssaStyleFormatNameSecondaryColour, - ssaStyleFormatNameTertiaryColour, ssaStyleFormatNameOutlineColour, ssaStyleFormatNameBackColour: - // Build color - var c *Color - if c, err = newColorFromSSAColor(item); err != nil { - err = fmt.Errorf("astisub: building new %s from ssa color %s failed: %w", attr, item, err) - return - } - - // Set color - switch attr { - case ssaStyleFormatNameBackColour: - s.backColour = c - case ssaStyleFormatNamePrimaryColour: - s.primaryColour = c - case ssaStyleFormatNameSecondaryColour: - s.secondaryColour = c - case ssaStyleFormatNameTertiaryColour, ssaStyleFormatNameOutlineColour: - s.outlineColour = c - } - // Float - case ssaStyleFormatNameAlphaLevel, ssaStyleFormatNameAngle, ssaStyleFormatNameFontSize, - ssaStyleFormatNameScaleX, ssaStyleFormatNameScaleY, - ssaStyleFormatNameOutline, ssaStyleFormatNameShadow, ssaStyleFormatNameSpacing: - // Parse float - var f float64 - if f, err = strconv.ParseFloat(item, 64); err != nil { - err = fmt.Errorf("astisub: parsing float %s failed: %w", item, err) - return - } - - // Set float - switch attr { - case ssaStyleFormatNameAlphaLevel: - s.alphaLevel = astikit.Float64Ptr(f) - case ssaStyleFormatNameAngle: - s.angle = astikit.Float64Ptr(f) - case ssaStyleFormatNameFontSize: - s.fontSize = astikit.Float64Ptr(f) - case ssaStyleFormatNameScaleX: - s.scaleX = astikit.Float64Ptr(f) - case ssaStyleFormatNameScaleY: - s.scaleY = astikit.Float64Ptr(f) - case ssaStyleFormatNameOutline: - s.outline = astikit.Float64Ptr(f) - case ssaStyleFormatNameShadow: - s.shadow = astikit.Float64Ptr(f) - case ssaStyleFormatNameSpacing: - s.spacing = astikit.Float64Ptr(f) - } - // Int - case ssaStyleFormatNameAlignment, ssaStyleFormatNameBorderStyle, ssaStyleFormatNameEncoding, - ssaStyleFormatNameMarginL, ssaStyleFormatNameMarginR, ssaStyleFormatNameMarginV: - // Parse int - var i int - if i, err = strconv.Atoi(item); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", item, err) - return - } - - // Set int - switch attr { - case ssaStyleFormatNameAlignment: - s.alignment = astikit.IntPtr(i) - case ssaStyleFormatNameBorderStyle: - s.borderStyle = astikit.IntPtr(i) - case ssaStyleFormatNameEncoding: - s.encoding = astikit.IntPtr(i) - case ssaStyleFormatNameMarginL: - s.marginLeft = astikit.IntPtr(i) - case ssaStyleFormatNameMarginR: - s.marginRight = astikit.IntPtr(i) - case ssaStyleFormatNameMarginV: - s.marginVertical = astikit.IntPtr(i) - } - // String - case ssaStyleFormatNameFontName, ssaStyleFormatNameName: - switch attr { - case ssaStyleFormatNameFontName: - s.fontName = item - case ssaStyleFormatNameName: - s.name = item - } - } - } - return -} - -// ssaUpdateFormat updates an SSA format -func ssaUpdateFormat(n string, formatMap map[string]bool, format []string) []string { - if _, ok := formatMap[n]; !ok { - formatMap[n] = true - format = append(format, n) - } - return format -} - -// updateFormat updates the format based on the non empty fields -func (s ssaStyle) updateFormat(formatMap map[string]bool, format []string) []string { - if s.alignment != nil { - format = ssaUpdateFormat(ssaStyleFormatNameAlignment, formatMap, format) - } - if s.alphaLevel != nil { - format = ssaUpdateFormat(ssaStyleFormatNameAlphaLevel, formatMap, format) - } - if s.angle != nil { - format = ssaUpdateFormat(ssaStyleFormatNameAngle, formatMap, format) - } - if s.backColour != nil { - format = ssaUpdateFormat(ssaStyleFormatNameBackColour, formatMap, format) - } - if s.bold != nil { - format = ssaUpdateFormat(ssaStyleFormatNameBold, formatMap, format) - } - if s.borderStyle != nil { - format = ssaUpdateFormat(ssaStyleFormatNameBorderStyle, formatMap, format) - } - if s.encoding != nil { - format = ssaUpdateFormat(ssaStyleFormatNameEncoding, formatMap, format) - } - if len(s.fontName) > 0 { - format = ssaUpdateFormat(ssaStyleFormatNameFontName, formatMap, format) - } - if s.fontSize != nil { - format = ssaUpdateFormat(ssaStyleFormatNameFontSize, formatMap, format) - } - if s.italic != nil { - format = ssaUpdateFormat(ssaStyleFormatNameItalic, formatMap, format) - } - if s.marginLeft != nil { - format = ssaUpdateFormat(ssaStyleFormatNameMarginL, formatMap, format) - } - if s.marginRight != nil { - format = ssaUpdateFormat(ssaStyleFormatNameMarginR, formatMap, format) - } - if s.marginVertical != nil { - format = ssaUpdateFormat(ssaStyleFormatNameMarginV, formatMap, format) - } - if s.outline != nil { - format = ssaUpdateFormat(ssaStyleFormatNameOutline, formatMap, format) - } - if s.outlineColour != nil { - format = ssaUpdateFormat(ssaStyleFormatNameOutlineColour, formatMap, format) - } - if s.primaryColour != nil { - format = ssaUpdateFormat(ssaStyleFormatNamePrimaryColour, formatMap, format) - } - if s.scaleX != nil { - format = ssaUpdateFormat(ssaStyleFormatNameScaleX, formatMap, format) - } - if s.scaleY != nil { - format = ssaUpdateFormat(ssaStyleFormatNameScaleY, formatMap, format) - } - if s.secondaryColour != nil { - format = ssaUpdateFormat(ssaStyleFormatNameSecondaryColour, formatMap, format) - } - if s.shadow != nil { - format = ssaUpdateFormat(ssaStyleFormatNameShadow, formatMap, format) - } - if s.spacing != nil { - format = ssaUpdateFormat(ssaStyleFormatNameSpacing, formatMap, format) - } - if s.strikeout != nil { - format = ssaUpdateFormat(ssaStyleFormatNameStrikeout, formatMap, format) - } - if s.underline != nil { - format = ssaUpdateFormat(ssaStyleFormatNameUnderline, formatMap, format) - } - return format -} - -// string returns the block as a string -func (s ssaStyle) string(format []string) string { - var ss = []string{s.name} - for _, attr := range format { - var v string - var found = true - switch attr { - // Bool - case ssaStyleFormatNameBold, ssaStyleFormatNameItalic, ssaStyleFormatNameStrikeout, - ssaStyleFormatNameUnderline: - var b *bool - switch attr { - case ssaStyleFormatNameBold: - b = s.bold - case ssaStyleFormatNameItalic: - b = s.italic - case ssaStyleFormatNameStrikeout: - b = s.strikeout - case ssaStyleFormatNameUnderline: - b = s.underline - } - if b != nil { - v = "0" - if *b { - v = "1" - } - } - // Color - case ssaStyleFormatNamePrimaryColour, ssaStyleFormatNameSecondaryColour, - ssaStyleFormatNameOutlineColour, ssaStyleFormatNameBackColour: - var c *Color - switch attr { - case ssaStyleFormatNameBackColour: - c = s.backColour - case ssaStyleFormatNamePrimaryColour: - c = s.primaryColour - case ssaStyleFormatNameSecondaryColour: - c = s.secondaryColour - case ssaStyleFormatNameOutlineColour: - c = s.outlineColour - } - if c != nil { - v = newSSAColorFromColor(c) - } - // Float - case ssaStyleFormatNameAlphaLevel, ssaStyleFormatNameAngle, ssaStyleFormatNameFontSize, - ssaStyleFormatNameScaleX, ssaStyleFormatNameScaleY, - ssaStyleFormatNameOutline, ssaStyleFormatNameShadow, ssaStyleFormatNameSpacing: - var f *float64 - switch attr { - case ssaStyleFormatNameAlphaLevel: - f = s.alphaLevel - case ssaStyleFormatNameAngle: - f = s.angle - case ssaStyleFormatNameFontSize: - f = s.fontSize - case ssaStyleFormatNameScaleX: - f = s.scaleX - case ssaStyleFormatNameScaleY: - f = s.scaleY - case ssaStyleFormatNameOutline: - f = s.outline - case ssaStyleFormatNameShadow: - f = s.shadow - case ssaStyleFormatNameSpacing: - f = s.spacing - } - if f != nil { - v = strconv.FormatFloat(*f, 'f', 3, 64) - } - // Int - case ssaStyleFormatNameAlignment, ssaStyleFormatNameBorderStyle, ssaStyleFormatNameEncoding, - ssaStyleFormatNameMarginL, ssaStyleFormatNameMarginR, ssaStyleFormatNameMarginV: - var i *int - switch attr { - case ssaStyleFormatNameAlignment: - i = s.alignment - case ssaStyleFormatNameBorderStyle: - i = s.borderStyle - case ssaStyleFormatNameEncoding: - i = s.encoding - case ssaStyleFormatNameMarginL: - i = s.marginLeft - case ssaStyleFormatNameMarginR: - i = s.marginRight - case ssaStyleFormatNameMarginV: - i = s.marginVertical - } - if i != nil { - v = strconv.Itoa(*i) - } - // String - case ssaStyleFormatNameFontName: - switch attr { - case ssaStyleFormatNameFontName: - v = s.fontName - } - default: - found = false - } - if found { - ss = append(ss, v) - } - } - return strings.Join(ss, ",") -} - -// style converts ssaStyle to Style -func (s ssaStyle) style() (o *Style) { - o = &Style{ - ID: s.name, - InlineStyle: &StyleAttributes{ - SSAAlignment: s.alignment, - SSAAlphaLevel: s.alphaLevel, - SSAAngle: s.angle, - SSABackColour: s.backColour, - SSABold: s.bold, - SSABorderStyle: s.borderStyle, - SSAEncoding: s.encoding, - SSAFontName: s.fontName, - SSAFontSize: s.fontSize, - SSAItalic: s.italic, - SSAOutline: s.outline, - SSAOutlineColour: s.outlineColour, - SSAMarginLeft: s.marginLeft, - SSAMarginRight: s.marginRight, - SSAMarginVertical: s.marginVertical, - SSAPrimaryColour: s.primaryColour, - SSAScaleX: s.scaleX, - SSAScaleY: s.scaleY, - SSASecondaryColour: s.secondaryColour, - SSAShadow: s.shadow, - SSASpacing: s.spacing, - SSAStrikeout: s.strikeout, - SSAUnderline: s.underline, - }, - } - o.InlineStyle.propagateSSAAttributes() - return -} - -// ssaEvent represents an SSA event -type ssaEvent struct { - category string - effect string - end time.Duration - layer *int - marked *bool - marginLeft *int // pixels - marginRight *int // pixels - marginVertical *int // pixels - name string - start time.Duration - style string - text string -} - -// newSSAEventFromItem returns an SSA Event based on an input item -func newSSAEventFromItem(i Item) (e *ssaEvent) { - // Init - e = &ssaEvent{ - category: ssaEventCategoryDialogue, - end: i.EndAt, - start: i.StartAt, - } - - // Style - if i.Style != nil { - e.style = i.Style.ID - } - - // Inline style - if i.InlineStyle != nil { - e.effect = i.InlineStyle.SSAEffect - e.layer = i.InlineStyle.SSALayer - e.marginLeft = i.InlineStyle.SSAMarginLeft - e.marginRight = i.InlineStyle.SSAMarginRight - e.marginVertical = i.InlineStyle.SSAMarginVertical - e.marked = i.InlineStyle.SSAMarked - } - - // Text - var lines []string - for _, l := range i.Lines { - var items []string - for _, item := range l.Items { - var s string - if item.InlineStyle != nil && len(item.InlineStyle.SSAEffect) > 0 { - s += item.InlineStyle.SSAEffect - } - s += item.Text - items = append(items, s) - } - if len(l.VoiceName) > 0 { - e.name = l.VoiceName - } - lines = append(lines, strings.Join(items, " ")) - } - e.text = strings.Join(lines, "\\n") - return -} - -// newSSAEventFromString returns an SSA event based on an input string and a format -func newSSAEventFromString(header, content string, format map[int]string) (e *ssaEvent, err error) { - // Split content - var items = strings.Split(content, ",") - - // Not enough items - if len(items) < len(format) { - err = fmt.Errorf("astisub: content has %d items whereas style format has %d items", len(items), len(format)) - return - } - - // Last item may contain commas, therefore we need to fix it - items[len(format)-1] = strings.Join(items[len(format)-1:], ",") - items = items[:len(format)] - - // Loop through items - e = &ssaEvent{category: header} - for idx, item := range items { - // Index not found in format - var attr string - var ok bool - if attr, ok = format[idx]; !ok { - err = fmt.Errorf("astisub: index %d not found in event format %+v", idx, format) - return - } - - // Switch on attribute name - switch attr { - // Duration - case ssaEventFormatNameStart, ssaEventFormatNameEnd: - // Parse duration - var d time.Duration - if d, err = parseDurationSSA(item); err != nil { - err = fmt.Errorf("astisub: parsing ssa duration %s failed: %w", item, err) - return - } - - // Set duration - switch attr { - case ssaEventFormatNameEnd: - e.end = d - case ssaEventFormatNameStart: - e.start = d - } - // Int - case ssaEventFormatNameLayer, ssaEventFormatNameMarginL, ssaEventFormatNameMarginR, - ssaEventFormatNameMarginV: - // Parse int - var i int - if i, err = strconv.Atoi(item); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", item, err) - return - } - - // Set int - switch attr { - case ssaEventFormatNameLayer: - e.layer = astikit.IntPtr(i) - case ssaEventFormatNameMarginL: - e.marginLeft = astikit.IntPtr(i) - case ssaEventFormatNameMarginR: - e.marginRight = astikit.IntPtr(i) - case ssaEventFormatNameMarginV: - e.marginVertical = astikit.IntPtr(i) - } - // String - case ssaEventFormatNameEffect, ssaEventFormatNameName, ssaEventFormatNameStyle, ssaEventFormatNameText: - switch attr { - case ssaEventFormatNameEffect: - e.effect = item - case ssaEventFormatNameName: - e.name = item - case ssaEventFormatNameStyle: - // *Default is reserved - // http://www.tcax.org/docs/ass-specs.htm - if item == "*Default" { - e.style = "Default" - } else { - e.style = item - } - case ssaEventFormatNameText: - e.text = strings.TrimSpace(item) - } - // Marked - case ssaEventFormatNameMarked: - if item == "Marked=1" { - e.marked = astikit.BoolPtr(true) - } else { - e.marked = astikit.BoolPtr(false) - } - } - } - return -} - -// item converts an SSA event to an Item -func (e *ssaEvent) item(styles map[string]*Style) (i *Item, err error) { - // Init item - i = &Item{ - EndAt: e.end, - InlineStyle: &StyleAttributes{ - SSAEffect: e.effect, - SSALayer: e.layer, - SSAMarginLeft: e.marginLeft, - SSAMarginRight: e.marginRight, - SSAMarginVertical: e.marginVertical, - SSAMarked: e.marked, - }, - StartAt: e.start, - } - - // Set style - if len(e.style) > 0 { - var ok bool - if i.Style, ok = styles[e.style]; !ok { - err = fmt.Errorf("astisub: style %s not found", e.style) - return - } - } - - // Loop through lines - for _, s := range strings.Split(e.text, "\\n") { - // Init - s = strings.TrimSpace(s) - var l = Line{VoiceName: e.name} - - // Extract effects - var matches = ssaRegexpEffect.FindAllStringIndex(s, -1) - if len(matches) > 0 { - // Loop through matches - var lineItem *LineItem - var previousEffectEndOffset int - for _, idxs := range matches { - if lineItem != nil { - lineItem.Text = s[previousEffectEndOffset:idxs[0]] - l.Items = append(l.Items, *lineItem) - } else if idxs[0] > 0 { - l.Items = append(l.Items, LineItem{Text: s[previousEffectEndOffset:idxs[0]]}) - } - previousEffectEndOffset = idxs[1] - lineItem = &LineItem{InlineStyle: &StyleAttributes{SSAEffect: s[idxs[0]:idxs[1]]}} - } - lineItem.Text = s[previousEffectEndOffset:] - l.Items = append(l.Items, *lineItem) - } else { - l.Items = append(l.Items, LineItem{Text: s}) - } - - // Add line - i.Lines = append(i.Lines, l) - } - return -} - -// updateFormat updates the format based on the non empty fields -func (e ssaEvent) updateFormat(formatMap map[string]bool, format []string) []string { - if len(e.effect) > 0 { - format = ssaUpdateFormat(ssaEventFormatNameEffect, formatMap, format) - } - if e.layer != nil { - format = ssaUpdateFormat(ssaEventFormatNameLayer, formatMap, format) - } - if e.marginLeft != nil { - format = ssaUpdateFormat(ssaEventFormatNameMarginL, formatMap, format) - } - if e.marginRight != nil { - format = ssaUpdateFormat(ssaEventFormatNameMarginR, formatMap, format) - } - if e.marginVertical != nil { - format = ssaUpdateFormat(ssaEventFormatNameMarginV, formatMap, format) - } - if e.marked != nil { - format = ssaUpdateFormat(ssaEventFormatNameMarked, formatMap, format) - } - if len(e.name) > 0 { - format = ssaUpdateFormat(ssaEventFormatNameName, formatMap, format) - } - if len(e.style) > 0 { - format = ssaUpdateFormat(ssaEventFormatNameStyle, formatMap, format) - } - return format -} - -// formatDurationSSA formats an .ssa duration -func formatDurationSSA(i time.Duration) string { - return formatDuration(i, ".", 2) -} - -// string returns the block as a string -func (e *ssaEvent) string(format []string) string { - var ss []string - for _, attr := range format { - var v string - var found = true - switch attr { - // Duration - case ssaEventFormatNameEnd, ssaEventFormatNameStart: - switch attr { - case ssaEventFormatNameEnd: - v = formatDurationSSA(e.end) - case ssaEventFormatNameStart: - v = formatDurationSSA(e.start) - } - // Marked - case ssaEventFormatNameMarked: - if e.marked != nil { - if *e.marked { - v = "Marked=1" - } else { - v = "Marked=0" - } - } - // Int - case ssaEventFormatNameLayer, ssaEventFormatNameMarginL, ssaEventFormatNameMarginR, - ssaEventFormatNameMarginV: - var i *int - switch attr { - case ssaEventFormatNameLayer: - i = e.layer - case ssaEventFormatNameMarginL: - i = e.marginLeft - case ssaEventFormatNameMarginR: - i = e.marginRight - case ssaEventFormatNameMarginV: - i = e.marginVertical - } - if i != nil { - v = strconv.Itoa(*i) - } - // String - case ssaEventFormatNameEffect, ssaEventFormatNameName, ssaEventFormatNameStyle, ssaEventFormatNameText: - switch attr { - case ssaEventFormatNameEffect: - v = e.effect - case ssaEventFormatNameName: - v = e.name - case ssaEventFormatNameStyle: - v = e.style - case ssaEventFormatNameText: - v = e.text - } - default: - found = false - } - if found { - ss = append(ss, v) - } - } - return strings.Join(ss, ",") -} - -// parseDurationSSA parses an .ssa duration -func parseDurationSSA(i string) (time.Duration, error) { - return parseDuration(i, ".", 3) -} - -// WriteToSSA writes subtitles in .ssa format -func (s Subtitles) WriteToSSA(o io.Writer) (err error) { - // Do not write anything if no subtitles - if len(s.Items) == 0 { - err = ErrNoSubtitlesToWrite - return - } - - // Write Script Info block - var si = newSSAScriptInfo(s.Metadata) - if _, err = o.Write(si.bytes()); err != nil { - err = fmt.Errorf("astisub: writing script info block failed: %w", err) - return - } - - // Write Styles block - if len(s.Styles) > 0 { - // Header - var b = []byte("\n[V4 Styles]\n") - - // Format - var formatMap = make(map[string]bool) - var format = []string{ssaStyleFormatNameName} - var styles = make(map[string]*ssaStyle) - var styleNames []string - for _, s := range s.Styles { - var ss = newSSAStyleFromStyle(*s) - format = ss.updateFormat(formatMap, format) - styles[ss.name] = ss - styleNames = append(styleNames, ss.name) - } - b = append(b, []byte("Format: "+strings.Join(format, ", ")+"\n")...) - - // Styles - sort.Strings(styleNames) - for _, n := range styleNames { - b = append(b, []byte("Style: "+styles[n].string(format)+"\n")...) - } - - // Write - if _, err = o.Write(b); err != nil { - err = fmt.Errorf("astisub: writing styles block failed: %w", err) - return - } - } - - // Write Events block - if len(s.Items) > 0 { - // Header - var b = []byte("\n[Events]\n") - - // Format - var formatMap = make(map[string]bool) - var format = []string{ - ssaEventFormatNameStart, - ssaEventFormatNameEnd, - } - var events []*ssaEvent - for _, i := range s.Items { - var e = newSSAEventFromItem(*i) - format = e.updateFormat(formatMap, format) - events = append(events, e) - } - format = append(format, ssaEventFormatNameText) - b = append(b, []byte("Format: "+strings.Join(format, ", ")+"\n")...) - - // Styles - for _, e := range events { - b = append(b, []byte(ssaEventCategoryDialogue+": "+e.string(format)+"\n")...) - } - - // Write - if _, err = o.Write(b); err != nil { - err = fmt.Errorf("astisub: writing events block failed: %w", err) - return - } - } - return -} - -// SSAOptions -type SSAOptions struct { - OnUnknownSectionName func(name string) - OnInvalidLine func(line string) -} - -func defaultSSAOptions() SSAOptions { - return SSAOptions{ - OnUnknownSectionName: func(name string) { - log.Printf("astisub: unknown section: %s", name) - }, - OnInvalidLine: func(line string) { - log.Printf("astisub: not understood: '%s', ignoring", line) - }, - } -} diff --git a/vendor/github.com/asticode/go-astisub/stl.go b/vendor/github.com/asticode/go-astisub/stl.go deleted file mode 100644 index 81a5d593823..00000000000 --- a/vendor/github.com/asticode/go-astisub/stl.go +++ /dev/null @@ -1,1085 +0,0 @@ -package astisub - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "math" - "strconv" - "strings" - "time" - - "github.com/asticode/go-astikit" - "golang.org/x/text/unicode/norm" -) - -// https://tech.ebu.ch/docs/tech/tech3264.pdf -// https://github.com/yanncoupin/stl2srt/blob/master/to_srt.py - -// STL block sizes -const ( - stlBlockSizeGSI = 1024 - stlBlockSizeTTI = 128 -) - -// STL character code table number -const ( - stlCharacterCodeTableNumberLatin uint16 = 12336 - stlCharacterCodeTableNumberLatinCyrillic uint16 = 12337 - stlCharacterCodeTableNumberLatinArabic uint16 = 12338 - stlCharacterCodeTableNumberLatinGreek uint16 = 12339 - stlCharacterCodeTableNumberLatinHebrew uint16 = 12340 -) - -// STL character code tables -// TODO Add missing tables -var ( - stlCharacterCodeTables = map[uint16]*astikit.BiMap{ - stlCharacterCodeTableNumberLatin: astikit.NewBiMap(). - Set(0x20, " ").Set(0x21, "!").Set(0x22, "\"").Set(0x23, "#"). - Set(0x24, "¤").Set(0x25, "%").Set(0x26, "&").Set(0x27, "'"). - Set(0x28, "(").Set(0x29, ")").Set(0x2a, "*").Set(0x2b, "+"). - Set(0x2c, ",").Set(0x2d, "-").Set(0x2e, ".").Set(0x2f, "/"). - Set(0x30, "0").Set(0x31, "1").Set(0x32, "2").Set(0x33, "3"). - Set(0x34, "4").Set(0x35, "5").Set(0x36, "6").Set(0x37, "7"). - Set(0x38, "8").Set(0x39, "9").Set(0x3a, ":").Set(0x3b, ";"). - Set(0x3c, "<").Set(0x3d, "=").Set(0x3e, ">").Set(0x3f, "?"). - Set(0x40, "@").Set(0x41, "A").Set(0x42, "B").Set(0x43, "C"). - Set(0x44, "D").Set(0x45, "E").Set(0x46, "F").Set(0x47, "G"). - Set(0x48, "H").Set(0x49, "I").Set(0x4a, "J").Set(0x4b, "K"). - Set(0x4c, "L").Set(0x4d, "M").Set(0x4e, "N").Set(0x4f, "O"). - Set(0x50, "P").Set(0x51, "Q").Set(0x52, "R").Set(0x53, "S"). - Set(0x54, "T").Set(0x55, "U").Set(0x56, "V").Set(0x57, "W"). - Set(0x58, "X").Set(0x59, "Y").Set(0x5a, "Z").Set(0x5b, "["). - Set(0x5c, "\\").Set(0x5d, "]").Set(0x5e, "^").Set(0x5f, "_"). - Set(0x60, "`").Set(0x61, "a").Set(0x62, "b").Set(0x63, "c"). - Set(0x64, "d").Set(0x65, "e").Set(0x66, "f").Set(0x67, "g"). - Set(0x68, "h").Set(0x69, "i").Set(0x6a, "j").Set(0x6b, "k"). - Set(0x6c, "l").Set(0x6d, "m").Set(0x6e, "n").Set(0x6f, "o"). - Set(0x70, "p").Set(0x71, "q").Set(0x72, "r").Set(0x73, "s"). - Set(0x74, "t").Set(0x75, "u").Set(0x76, "v").Set(0x77, "w"). - Set(0x78, "x").Set(0x79, "y").Set(0x7a, "z").Set(0x7b, "{"). - Set(0x7c, "|").Set(0x7d, "}").Set(0x7e, "~"). - Set(0xa0, string([]byte{0xC2, 0xA0})).Set(0xa1, "¡").Set(0xa2, "¢"). - Set(0xa3, "£").Set(0xa4, "$").Set(0xa5, "¥").Set(0xa7, "§"). - Set(0xa9, "‘").Set(0xaa, "“").Set(0xab, "«").Set(0xac, "←"). - Set(0xad, "↑").Set(0xae, "→").Set(0xaf, "↓"). - Set(0xb0, "°").Set(0xb1, "±").Set(0xb2, "²").Set(0xb3, "³"). - Set(0xb4, "×").Set(0xb5, "µ").Set(0xb6, "¶").Set(0xb7, "·"). - Set(0xb8, "÷").Set(0xb9, "’").Set(0xba, "”").Set(0xbb, "»"). - Set(0xbc, "¼").Set(0xbd, "½").Set(0xbe, "¾").Set(0xbf, "¿"). - Set(0xc1, string([]byte{0xCC, 0x80})).Set(0xc2, string([]byte{0xCC, 0x81})). - Set(0xc3, string([]byte{0xCC, 0x82})).Set(0xc4, string([]byte{0xCC, 0x83})). - Set(0xc5, string([]byte{0xCC, 0x84})).Set(0xc6, string([]byte{0xCC, 0x86})). - Set(0xc7, string([]byte{0xCC, 0x87})).Set(0xc8, string([]byte{0xCC, 0x88})). - Set(0xca, string([]byte{0xCC, 0x8A})).Set(0xcb, string([]byte{0xCC, 0xA7})). - Set(0xcd, string([]byte{0xCC, 0x8B})).Set(0xce, string([]byte{0xCC, 0xA8})). - Set(0xcf, string([]byte{0xCC, 0x8C})). - Set(0xd0, "―").Set(0xd1, "¹").Set(0xd2, "®").Set(0xd3, "©"). - Set(0xd4, "™").Set(0xd5, "♪").Set(0xd6, "¬").Set(0xd7, "¦"). - Set(0xdc, "⅛").Set(0xdd, "⅜").Set(0xde, "⅝").Set(0xdf, "⅞"). - Set(0xe0, "Ω").Set(0xe1, "Æ").Set(0xe2, "Đ").Set(0xe3, "ª"). - Set(0xe4, "Ħ").Set(0xe6, "IJ").Set(0xe7, "Ŀ").Set(0xe8, "Ł"). - Set(0xe9, "Ø").Set(0xea, "Œ").Set(0xeb, "º").Set(0xec, "Þ"). - Set(0xed, "Ŧ").Set(0xee, "Ŋ").Set(0xef, "ʼn"). - Set(0xf0, "ĸ").Set(0xf1, "æ").Set(0xf2, "đ").Set(0xf3, "ð"). - Set(0xf4, "ħ").Set(0xf5, "ı").Set(0xf6, "ij").Set(0xf7, "ŀ"). - Set(0xf8, "ł").Set(0xf9, "ø").Set(0xfa, "œ").Set(0xfb, "ß"). - Set(0xfc, "þ").Set(0xfd, "ŧ").Set(0xfe, "ŋ").Set(0xff, string([]byte{0xC2, 0xAD})), - } -) - -// STL code page numbers -const ( - stlCodePageNumberCanadaFrench uint32 = 3683891 - stlCodePageNumberMultilingual uint32 = 3683632 - stlCodePageNumberNordic uint32 = 3683893 - stlCodePageNumberPortugal uint32 = 3683888 - stlCodePageNumberUnitedStates uint32 = 3420983 -) - -// STL comment flag -const ( - stlCommentFlagTextContainsSubtitleData = '\x00' - stlCommentFlagTextContainsCommentsNotIntendedForTransmission = '\x01' -) - -// STL country codes -const ( - stlCountryCodeChinese = "CHN" - stlCountryCodeFrance = "FRA" - stlCountryCodeJapan = "JPN" - stlCountryCodeNorway = "NOR" -) - -// STL cumulative status -const ( - stlCumulativeStatusFirstSubtitleOfACumulativeSet = '\x01' - stlCumulativeStatusIntermediateSubtitleOfACumulativeSet = '\x02' - stlCumulativeStatusLastSubtitleOfACumulativeSet = '\x03' - stlCumulativeStatusSubtitleNotPartOfACumulativeSet = '\x00' -) - -// STL display standard code -const ( - stlDisplayStandardCodeOpenSubtitling = "0" - stlDisplayStandardCodeLevel1Teletext = "1" - stlDisplayStandardCodeLevel2Teletext = "2" -) - -// STL framerate mapping -var stlFramerateMapping = astikit.NewBiMap(). - Set("STL25.01", 25). - Set("STL30.01", 30) - -// STL justification code -const ( - stlJustificationCodeCentredText = '\x02' - stlJustificationCodeLeftJustifiedText = '\x01' - stlJustificationCodeRightJustifiedText = '\x03' - stlJustificationCodeUnchangedPresentation = '\x00' -) - -// STL language codes -const ( - stlLanguageCodeChinese = "75" - stlLanguageCodeEnglish = "09" - stlLanguageCodeFrench = "0F" - stllanguageCodeJapanese = "69" - stlLanguageCodeNorwegian = "1E" -) - -// STL language mapping -var stlLanguageMapping = astikit.NewBiMap(). - Set(stlLanguageCodeChinese, LanguageChinese). - Set(stlLanguageCodeEnglish, LanguageEnglish). - Set(stlLanguageCodeFrench, LanguageFrench). - Set(stllanguageCodeJapanese, LanguageJapanese). - Set(stlLanguageCodeNorwegian, LanguageNorwegian) - - // STL timecode status -const ( - stlTimecodeStatusNotIntendedForUse = "0" - stlTimecodeStatusIntendedForUse = "1" -) - -// TTI Special Extension Block Number -const extensionBlockNumberReservedUserData = 0xfe - -const stlLineSeparator = 0x8a - -type STLPosition struct { - VerticalPosition int - MaxRows int - Rows int -} - -// STLOptions represents STL parsing options -type STLOptions struct { - // IgnoreTimecodeStartOfProgramme - set STLTimecodeStartOfProgramme to zero before parsing - IgnoreTimecodeStartOfProgramme bool -} - -// ReadFromSTL parses an .stl content -func ReadFromSTL(i io.Reader, opts STLOptions) (o *Subtitles, err error) { - // Init - o = NewSubtitles() - - // Read GSI block - var b []byte - if b, err = readNBytes(i, stlBlockSizeGSI); err != nil { - return - } - - // Parse GSI block - var g *gsiBlock - if g, err = parseGSIBlock(b); err != nil { - err = fmt.Errorf("astisub: building gsi block failed: %w", err) - return - } - - // Create character handler - var ch *stlCharacterHandler - if ch, err = newSTLCharacterHandler(g.characterCodeTableNumber); err != nil { - err = fmt.Errorf("astisub: creating stl character handler failed: %w", err) - return - } - - // Update metadata - // TODO Add more STL fields to metadata - o.Metadata = &Metadata{ - Framerate: g.framerate, - STLCountryOfOrigin: g.countryOfOrigin, - STLCreationDate: &g.creationDate, - STLDisplayStandardCode: g.displayStandardCode, - STLMaximumNumberOfDisplayableCharactersInAnyTextRow: astikit.IntPtr(g.maximumNumberOfDisplayableCharactersInAnyTextRow), - STLMaximumNumberOfDisplayableRows: astikit.IntPtr(g.maximumNumberOfDisplayableRows), - STLPublisher: g.publisher, - STLRevisionDate: &g.revisionDate, - STLSubtitleListReferenceCode: g.subtitleListReferenceCode, - Title: g.originalProgramTitle, - } - if !opts.IgnoreTimecodeStartOfProgramme { - o.Metadata.STLTimecodeStartOfProgramme = g.timecodeStartOfProgramme - } - if v, ok := stlLanguageMapping.Get(g.languageCode); ok { - o.Metadata.Language = v.(string) - } - - // Parse Text and Timing Information (TTI) blocks. - for { - // Read TTI block - if b, err = readNBytes(i, stlBlockSizeTTI); err != nil { - if err == io.EOF { - err = nil - break - } - return - } - - // Parse TTI block - var t = parseTTIBlock(b, g.framerate) - - // Do not process reserved user data - if t.extensionBlockNumber == extensionBlockNumberReservedUserData { - continue - } - - justification := parseSTLJustificationCode(t.justificationCode) - rows := bytes.Split(t.text, []byte{stlLineSeparator}) - - position := STLPosition{ - MaxRows: g.maximumNumberOfDisplayableRows, - Rows: len(rows), - VerticalPosition: t.verticalPosition, - } - - styleAttributes := StyleAttributes{ - STLJustification: &justification, - STLPosition: &position, - } - styleAttributes.propagateSTLAttributes() - - // Create item - var i = &Item{ - EndAt: t.timecodeOut - o.Metadata.STLTimecodeStartOfProgramme, - InlineStyle: &styleAttributes, - StartAt: t.timecodeIn - o.Metadata.STLTimecodeStartOfProgramme, - } - - // Loop through rows - for _, text := range bytes.Split(t.text, []byte{stlLineSeparator}) { - if g.displayStandardCode == stlDisplayStandardCodeOpenSubtitling { - err = parseOpenSubtitleRow(i, ch, func() styler { return newSTLStyler() }, text) - if err != nil { - return nil, err - } - } else { - parseTeletextRow(i, ch, func() styler { return newSTLStyler() }, text) - } - } - - // Append item - o.Items = append(o.Items, i) - - } - return -} - -// readNBytes reads n bytes -func readNBytes(i io.Reader, c int) (o []byte, err error) { - o = make([]byte, c) - var n int - if n, err = i.Read(o); err != nil || n != len(o) { - if err != nil { - if err == io.EOF { - return - } - err = fmt.Errorf("astisub: reading %d bytes failed: %w", c, err) - return - } - err = fmt.Errorf("astisub: read %d bytes, should have read %d", n, c) - return - } - return -} - -// gsiBlock represents a GSI block -type gsiBlock struct { - characterCodeTableNumber uint16 - codePageNumber uint32 - countryOfOrigin string - creationDate time.Time - diskSequenceNumber int - displayStandardCode string - editorContactDetails string - editorName string - framerate int - languageCode string - maximumNumberOfDisplayableCharactersInAnyTextRow int - maximumNumberOfDisplayableRows int - originalEpisodeTitle string - originalProgramTitle string - publisher string - revisionDate time.Time - revisionNumber int - subtitleListReferenceCode string - timecodeFirstInCue time.Duration - timecodeStartOfProgramme time.Duration - timecodeStatus string - totalNumberOfDisks int - totalNumberOfSubtitleGroups int - totalNumberOfSubtitles int - totalNumberOfTTIBlocks int - translatedEpisodeTitle string - translatedProgramTitle string - translatorContactDetails string - translatorName string - userDefinedArea string -} - -// newGSIBlock builds the subtitles GSI block -func newGSIBlock(s Subtitles) (g *gsiBlock) { - // Init - g = &gsiBlock{ - characterCodeTableNumber: stlCharacterCodeTableNumberLatin, - codePageNumber: stlCodePageNumberMultilingual, - countryOfOrigin: stlCountryCodeFrance, - creationDate: Now(), - diskSequenceNumber: 1, - displayStandardCode: stlDisplayStandardCodeLevel1Teletext, - framerate: 25, - languageCode: stlLanguageCodeFrench, - maximumNumberOfDisplayableCharactersInAnyTextRow: 40, - maximumNumberOfDisplayableRows: 23, - revisionDate: Now(), - subtitleListReferenceCode: "", - timecodeStatus: stlTimecodeStatusIntendedForUse, - timecodeStartOfProgramme: 0, - totalNumberOfDisks: 1, - totalNumberOfSubtitleGroups: 1, - totalNumberOfSubtitles: len(s.Items), - totalNumberOfTTIBlocks: len(s.Items), - } - - // Add metadata - if s.Metadata != nil { - if s.Metadata.STLCreationDate != nil { - g.creationDate = *s.Metadata.STLCreationDate - } - g.countryOfOrigin = s.Metadata.STLCountryOfOrigin - g.displayStandardCode = s.Metadata.STLDisplayStandardCode - g.framerate = s.Metadata.Framerate - if v, ok := stlLanguageMapping.GetInverse(s.Metadata.Language); ok { - g.languageCode = v.(string) - } - g.originalProgramTitle = s.Metadata.Title - if s.Metadata.STLMaximumNumberOfDisplayableCharactersInAnyTextRow != nil { - g.maximumNumberOfDisplayableCharactersInAnyTextRow = *s.Metadata.STLMaximumNumberOfDisplayableCharactersInAnyTextRow - } - if s.Metadata.STLMaximumNumberOfDisplayableRows != nil { - g.maximumNumberOfDisplayableRows = *s.Metadata.STLMaximumNumberOfDisplayableRows - } - g.publisher = s.Metadata.STLPublisher - if s.Metadata.STLRevisionDate != nil { - g.revisionDate = *s.Metadata.STLRevisionDate - } - g.subtitleListReferenceCode = s.Metadata.STLSubtitleListReferenceCode - g.timecodeStartOfProgramme = s.Metadata.STLTimecodeStartOfProgramme - } - - // Timecode first in cue - if len(s.Items) > 0 { - g.timecodeFirstInCue = s.Items[0].StartAt - } - return -} - -// parseGSIBlock parses a GSI block -func parseGSIBlock(b []byte) (g *gsiBlock, err error) { - // Init - g = &gsiBlock{ - characterCodeTableNumber: binary.BigEndian.Uint16(b[12:14]), - countryOfOrigin: string(bytes.TrimSpace(b[274:277])), - codePageNumber: binary.BigEndian.Uint32(append([]byte{0x0}, b[0:3]...)), - displayStandardCode: string(bytes.TrimSpace([]byte{b[11]})), - editorName: string(bytes.TrimSpace(b[309:341])), - editorContactDetails: string(bytes.TrimSpace(b[341:373])), - languageCode: string(bytes.TrimSpace(b[14:16])), - originalEpisodeTitle: string(bytes.TrimSpace(b[48:80])), - originalProgramTitle: string(bytes.TrimSpace(b[16:48])), - publisher: string(bytes.TrimSpace(b[277:309])), - subtitleListReferenceCode: string(bytes.TrimSpace(b[208:224])), - timecodeStatus: string(bytes.TrimSpace([]byte{b[255]})), - translatedEpisodeTitle: string(bytes.TrimSpace(b[80:112])), - translatedProgramTitle: string(bytes.TrimSpace(b[112:144])), - translatorContactDetails: string(bytes.TrimSpace(b[176:208])), - translatorName: string(bytes.TrimSpace(b[144:176])), - userDefinedArea: string(bytes.TrimSpace(b[448:])), - } - - // Framerate - if v, ok := stlFramerateMapping.Get(string(b[3:11])); ok { - g.framerate = v.(int) - } - - // Creation date - if v := strings.TrimSpace(string(b[224:230])); len(v) > 0 { - if g.creationDate, err = time.Parse("060102", v); err != nil { - err = fmt.Errorf("astisub: parsing date %s failed: %w", v, err) - return - } - } - - // Revision date - if v := strings.TrimSpace(string(b[230:236])); len(v) > 0 { - if g.revisionDate, err = time.Parse("060102", v); err != nil { - err = fmt.Errorf("astisub: parsing date %s failed: %w", v, err) - return - } - } - - // Revision number - if v := strings.TrimSpace(string(b[236:238])); len(v) > 0 { - if g.revisionNumber, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Total number of TTI blocks - if v := strings.TrimSpace(string(b[238:243])); len(v) > 0 { - if g.totalNumberOfTTIBlocks, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Total number of subtitles - if v := strings.TrimSpace(string(b[243:248])); len(v) > 0 { - if g.totalNumberOfSubtitles, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Total number of subtitle groups - if v := strings.TrimSpace(string(b[248:251])); len(v) > 0 { - if g.totalNumberOfSubtitleGroups, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Maximum number of displayable characters in any text row - if v := strings.TrimSpace(string(b[251:253])); len(v) > 0 { - if g.maximumNumberOfDisplayableCharactersInAnyTextRow, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Maximum number of displayable rows - if v := strings.TrimSpace(string(b[253:255])); len(v) > 0 { - if g.maximumNumberOfDisplayableRows, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Timecode start of programme - if v := strings.TrimSpace(string(b[256:264])); len(v) > 0 { - if g.timecodeStartOfProgramme, err = parseDurationSTL(v, g.framerate); err != nil { - err = fmt.Errorf("astisub: parsing of stl duration %s failed: %w", v, err) - return - } - } - - // Timecode first in cue - if v := strings.TrimSpace(string(b[264:272])); len(v) > 0 { - if g.timecodeFirstInCue, err = parseDurationSTL(v, g.framerate); err != nil { - err = fmt.Errorf("astisub: parsing of stl duration %s failed: %w", v, err) - return - } - } - - // Total number of disks - if v := strings.TrimSpace(string(b[272])); len(v) > 0 { - if g.totalNumberOfDisks, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - - // Disk sequence number - if v := strings.TrimSpace(string(b[273])); len(v) > 0 { - if g.diskSequenceNumber, err = strconv.Atoi(v); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", v, err) - return - } - } - return -} - -// bytes transforms the GSI block into []byte -func (b gsiBlock) bytes() (o []byte) { - bs := make([]byte, 4) - binary.BigEndian.PutUint32(bs, b.codePageNumber) - o = append(o, astikit.BytesPad(bs[1:], ' ', 3, astikit.PadRight, astikit.PadCut)...) // Code page number - // Disk format code - var f string - if v, ok := stlFramerateMapping.GetInverse(b.framerate); ok { - f = v.(string) - } - o = append(o, astikit.BytesPad([]byte(f), ' ', 8, astikit.PadRight, astikit.PadCut)...) - o = append(o, astikit.BytesPad([]byte(b.displayStandardCode), ' ', 1, astikit.PadRight, astikit.PadCut)...) // Display standard code - binary.BigEndian.PutUint16(bs, b.characterCodeTableNumber) - o = append(o, astikit.BytesPad(bs[:2], ' ', 2, astikit.PadRight, astikit.PadCut)...) // Character code table number - o = append(o, astikit.BytesPad([]byte(b.languageCode), ' ', 2, astikit.PadRight, astikit.PadCut)...) // Language code - o = append(o, astikit.BytesPad([]byte(b.originalProgramTitle), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Original program title - o = append(o, astikit.BytesPad([]byte(b.originalEpisodeTitle), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Original episode title - o = append(o, astikit.BytesPad([]byte(b.translatedProgramTitle), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Translated program title - o = append(o, astikit.BytesPad([]byte(b.translatedEpisodeTitle), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Translated episode title - o = append(o, astikit.BytesPad([]byte(b.translatorName), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Translator's name - o = append(o, astikit.BytesPad([]byte(b.translatorContactDetails), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Translator's contact details - o = append(o, astikit.BytesPad([]byte(b.subtitleListReferenceCode), ' ', 16, astikit.PadRight, astikit.PadCut)...) // Subtitle list reference code - o = append(o, astikit.BytesPad([]byte(b.creationDate.Format("060102")), ' ', 6, astikit.PadRight, astikit.PadCut)...) // Creation date - o = append(o, astikit.BytesPad([]byte(b.revisionDate.Format("060102")), ' ', 6, astikit.PadRight, astikit.PadCut)...) // Revision date - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.revisionNumber)), '0', 2, astikit.PadCut)...) // Revision number - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.totalNumberOfTTIBlocks)), '0', 5, astikit.PadCut)...) // Total number of TTI blocks - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.totalNumberOfSubtitles)), '0', 5, astikit.PadCut)...) // Total number of subtitles - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.totalNumberOfSubtitleGroups)), '0', 3, astikit.PadCut)...) // Total number of subtitle groups - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.maximumNumberOfDisplayableCharactersInAnyTextRow)), '0', 2, astikit.PadCut)...) // Maximum number of displayable characters in any text row - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.maximumNumberOfDisplayableRows)), '0', 2, astikit.PadCut)...) // Maximum number of displayable rows - o = append(o, astikit.BytesPad([]byte(b.timecodeStatus), ' ', 1, astikit.PadRight, astikit.PadCut)...) // Timecode status - o = append(o, astikit.BytesPad([]byte(formatDurationSTL(b.timecodeStartOfProgramme, b.framerate)), ' ', 8, astikit.PadRight, astikit.PadCut)...) // Timecode start of a programme - o = append(o, astikit.BytesPad([]byte(formatDurationSTL(b.timecodeFirstInCue, b.framerate)), ' ', 8, astikit.PadRight, astikit.PadCut)...) // Timecode first in cue - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.totalNumberOfDisks)), ' ', 1, astikit.PadRight, astikit.PadCut)...) // Total number of disks - o = append(o, astikit.BytesPad([]byte(strconv.Itoa(b.diskSequenceNumber)), ' ', 1, astikit.PadRight, astikit.PadCut)...) // Disk sequence number - o = append(o, astikit.BytesPad([]byte(b.countryOfOrigin), ' ', 3, astikit.PadRight, astikit.PadCut)...) // Country of origin - o = append(o, astikit.BytesPad([]byte(b.publisher), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Publisher - o = append(o, astikit.BytesPad([]byte(b.editorName), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Editor's name - o = append(o, astikit.BytesPad([]byte(b.editorContactDetails), ' ', 32, astikit.PadRight, astikit.PadCut)...) // Editor's contact details - o = append(o, astikit.BytesPad([]byte{}, ' ', 75+576, astikit.PadRight, astikit.PadCut)...) // Spare bytes + user defined area // // Editor's contact details - return -} - -// parseDurationSTL parses a STL duration -func parseDurationSTL(i string, framerate int) (d time.Duration, err error) { - // Parse hours - var hours, hoursString = 0, i[0:2] - if hours, err = strconv.Atoi(hoursString); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", hoursString, err) - return - } - - // Parse minutes - var minutes, minutesString = 0, i[2:4] - if minutes, err = strconv.Atoi(minutesString); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", minutesString, err) - return - } - - // Parse seconds - var seconds, secondsString = 0, i[4:6] - if seconds, err = strconv.Atoi(secondsString); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", secondsString, err) - return - } - - // Parse frames - var frames, framesString = 0, i[6:8] - if frames, err = strconv.Atoi(framesString); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", framesString, err) - return - } - - // Set duration - d = time.Duration(hours)*time.Hour + time.Duration(minutes)*time.Minute + time.Duration(seconds)*time.Second + time.Duration(1e9*frames/framerate)*time.Nanosecond - return -} - -// formatDurationSTL formats a STL duration -func formatDurationSTL(d time.Duration, framerate int) (o string) { - // Add hours - if d.Hours() < 10 { - o += "0" - } - var delta = int(math.Floor(d.Hours())) - o += strconv.Itoa(delta) - d -= time.Duration(delta) * time.Hour - - // Add minutes - if d.Minutes() < 10 { - o += "0" - } - delta = int(math.Floor(d.Minutes())) - o += strconv.Itoa(delta) - d -= time.Duration(delta) * time.Minute - - // Add seconds - if d.Seconds() < 10 { - o += "0" - } - delta = int(math.Floor(d.Seconds())) - o += strconv.Itoa(delta) - d -= time.Duration(delta) * time.Second - - // Add frames - var frames = int(int(d.Nanoseconds()) * framerate / 1e9) - if frames < 10 { - o += "0" - } - o += strconv.Itoa(frames) - return -} - -// ttiBlock represents a TTI block -type ttiBlock struct { - commentFlag byte - cumulativeStatus byte - extensionBlockNumber int - justificationCode byte - subtitleGroupNumber int - subtitleNumber int - text []byte - timecodeIn time.Duration - timecodeOut time.Duration - verticalPosition int -} - -// newTTIBlock builds an item TTI block -func newTTIBlock(i *Item, idx int) (t *ttiBlock) { - // Init - t = &ttiBlock{ - commentFlag: stlCommentFlagTextContainsSubtitleData, - cumulativeStatus: stlCumulativeStatusSubtitleNotPartOfACumulativeSet, - extensionBlockNumber: 255, - justificationCode: stlJustificationCodeLeftJustifiedText, - subtitleGroupNumber: 0, - subtitleNumber: idx, - timecodeIn: i.StartAt, - timecodeOut: i.EndAt, - verticalPosition: stlVerticalPositionFromStyle(i.InlineStyle), - } - - // Add text - var lines []string - for _, l := range i.Lines { - var lineItems []string - for _, li := range l.Items { - lineItems = append(lineItems, li.STLString()) - } - lines = append(lines, strings.Join(lineItems, " ")) - } - t.text = []byte(strings.Join(lines, string(rune(stlLineSeparator)))) - return -} - -func stlVerticalPositionFromStyle(sa *StyleAttributes) int { - if sa != nil && sa.STLPosition != nil { - return sa.STLPosition.VerticalPosition - } else { - return 20 - } -} - -func (li LineItem) STLString() string { - rs := li.Text - if li.InlineStyle != nil { - if li.InlineStyle.STLItalics != nil && *li.InlineStyle.STLItalics { - rs = string(rune(0x80)) + rs + string(rune(0x81)) - } - if li.InlineStyle.STLUnderline != nil && *li.InlineStyle.STLUnderline { - rs = string(rune(0x82)) + rs + string(rune(0x83)) - } - if li.InlineStyle.STLBoxing != nil && *li.InlineStyle.STLBoxing { - rs = string(rune(0x84)) + rs + string(rune(0x85)) - } - } - return rs -} - -// parseTTIBlock parses a TTI block -func parseTTIBlock(p []byte, framerate int) *ttiBlock { - return &ttiBlock{ - commentFlag: p[15], - cumulativeStatus: p[4], - extensionBlockNumber: int(uint8(p[3])), - justificationCode: p[14], - subtitleGroupNumber: int(uint8(p[0])), - subtitleNumber: int(binary.LittleEndian.Uint16(p[1:3])), - text: p[16:128], - timecodeIn: parseDurationSTLBytes(p[5:9], framerate), - timecodeOut: parseDurationSTLBytes(p[9:13], framerate), - verticalPosition: int(uint8(p[13])), - } -} - -// bytes transforms the TTI block into []byte -func (t *ttiBlock) bytes(g *gsiBlock) (o []byte) { - o = append(o, byte(uint8(t.subtitleGroupNumber))) // Subtitle group number - var b = make([]byte, 2) - binary.LittleEndian.PutUint16(b, uint16(t.subtitleNumber)) - o = append(o, b...) // Subtitle number - o = append(o, byte(uint8(t.extensionBlockNumber))) // Extension block number - o = append(o, t.cumulativeStatus) // Cumulative status - o = append(o, formatDurationSTLBytes(t.timecodeIn, g.framerate)...) // Timecode in - o = append(o, formatDurationSTLBytes(t.timecodeOut, g.framerate)...) // Timecode out - o = append(o, validateVerticalPosition(t.verticalPosition, g.displayStandardCode)) // Vertical position - o = append(o, t.justificationCode) // Justification code - o = append(o, t.commentFlag) // Comment flag - o = append(o, astikit.BytesPad(encodeTextSTL(string(t.text)), '\x8f', 112, astikit.PadRight, astikit.PadCut)...) // Text field - return -} - -// According to EBU 3264 (https://tech.ebu.ch/docs/tech/tech3264.pdf): -// page 12: -// for teletext subtitles, VP contains a value in the range 1-23 decimal (01h-17h) -// corresponding to theteletext row number of the first subtitle row. -// page 6: -// Teletext ("closed") subtitles are indicated via the Display Standard Code -// in the GSI block. -func validateVerticalPosition(vp int, dsc string) byte { - closed := false - switch dsc { - case stlDisplayStandardCodeLevel1Teletext, stlDisplayStandardCodeLevel2Teletext: - closed = true - } - if vp < 1 && closed { - vp = 1 - } - if vp > 23 && closed { - vp = 23 - } - return byte(uint8(vp)) -} - -// formatDurationSTLBytes formats a STL duration in bytes -func formatDurationSTLBytes(d time.Duration, framerate int) (o []byte) { - // Add hours - var hours = int(math.Floor(d.Hours())) - o = append(o, byte(uint8(hours))) - d -= time.Duration(hours) * time.Hour - - // Add minutes - var minutes = int(math.Floor(d.Minutes())) - o = append(o, byte(uint8(minutes))) - d -= time.Duration(minutes) * time.Minute - - // Add seconds - var seconds = int(math.Floor(d.Seconds())) - o = append(o, byte(uint8(seconds))) - d -= time.Duration(seconds) * time.Second - - // Add frames - var frames = int(int(d.Nanoseconds()) * framerate / 1e9) - o = append(o, byte(uint8(frames))) - return -} - -// parseDurationSTLBytes parses a STL duration in bytes -func parseDurationSTLBytes(b []byte, framerate int) time.Duration { - return time.Duration(uint8(b[0]))*time.Hour + time.Duration(uint8(b[1]))*time.Minute + time.Duration(uint8(b[2]))*time.Second + time.Duration(1e9*int(uint8(b[3]))/framerate)*time.Nanosecond -} - -type stlCharacterHandler struct { - accent string - c uint16 - m *astikit.BiMap -} - -func newSTLCharacterHandler(characterCodeTable uint16) (*stlCharacterHandler, error) { - if v, ok := stlCharacterCodeTables[characterCodeTable]; ok { - return &stlCharacterHandler{ - c: characterCodeTable, - m: v, - }, nil - } - return nil, fmt.Errorf("astisub: table doesn't exist for character code table %d", characterCodeTable) -} - -// TODO Use this instead of encodeTextSTL => use in teletext process like for decode -// TODO Test -func (h *stlCharacterHandler) encode(i []byte) byte { - return ' ' -} - -func (h *stlCharacterHandler) decode(i byte) (o []byte) { - k := int(i) - vi, ok := h.m.Get(k) - if !ok { - return - } - v := vi.(string) - if len(h.accent) > 0 { - o = norm.NFC.Bytes([]byte(v + h.accent)) - h.accent = "" - return - } else if h.c == stlCharacterCodeTableNumberLatin && k >= 0xc0 && k <= 0xcf { - h.accent = v - return - } - return []byte(v) -} - -type stlStyler struct { - boxing *bool - italics *bool - underline *bool -} - -func newSTLStyler() *stlStyler { - return &stlStyler{} -} - -func (s *stlStyler) parseSpacingAttribute(i byte) { - switch i { - case 0x80: - s.italics = astikit.BoolPtr(true) - case 0x81: - s.italics = astikit.BoolPtr(false) - case 0x82: - s.underline = astikit.BoolPtr(true) - case 0x83: - s.underline = astikit.BoolPtr(false) - case 0x84: - s.boxing = astikit.BoolPtr(true) - case 0x85: - s.boxing = astikit.BoolPtr(false) - } -} - -func (s *stlStyler) hasBeenSet() bool { - return s.italics != nil || s.boxing != nil || s.underline != nil -} - -func (s *stlStyler) hasChanged(sa *StyleAttributes) bool { - return s.boxing != sa.STLBoxing || s.italics != sa.STLItalics || s.underline != sa.STLUnderline -} - -func (s *stlStyler) propagateStyleAttributes(sa *StyleAttributes) { - sa.propagateSTLAttributes() -} - -func (s *stlStyler) update(sa *StyleAttributes) { - if s.boxing != nil && s.boxing != sa.STLBoxing { - sa.STLBoxing = s.boxing - } - if s.italics != nil && s.italics != sa.STLItalics { - sa.STLItalics = s.italics - } - if s.underline != nil && s.underline != sa.STLUnderline { - sa.STLUnderline = s.underline - } -} - -// WriteToSTL writes subtitles in .stl format -func (s Subtitles) WriteToSTL(o io.Writer) (err error) { - // Do not write anything if no subtitles - if len(s.Items) == 0 { - err = ErrNoSubtitlesToWrite - return - } - - // Write GSI block - var g = newGSIBlock(s) - if _, err = o.Write(g.bytes()); err != nil { - err = fmt.Errorf("astisub: writing gsi block failed: %w", err) - return - } - - // Loop through items - for idx, item := range s.Items { - // Write tti block - if _, err = o.Write(newTTIBlock(item, idx+1).bytes(g)); err != nil { - err = fmt.Errorf("astisub: writing tti block #%d failed: %w", idx+1, err) - return - } - } - return -} - -// TODO Remove below - -// STL unicode diacritic -var stlUnicodeDiacritic = astikit.NewBiMap(). - Set(byte('\xc1'), "\u0300"). // Grave accent - Set(byte('\xc2'), "\u0301"). // Acute accent - Set(byte('\xc3'), "\u0302"). // Circumflex - Set(byte('\xc4'), "\u0303"). // Tilde - Set(byte('\xc5'), "\u0304"). // Macron - Set(byte('\xc6'), "\u0306"). // Breve - Set(byte('\xc7'), "\u0307"). // Dot - Set(byte('\xc8'), "\u0308"). // Umlaut - Set(byte('\xca'), "\u030a"). // Ring - Set(byte('\xcb'), "\u0327"). // Cedilla - Set(byte('\xcd'), "\u030B"). // Double acute accent - Set(byte('\xce'), "\u0328"). // Ogonek - Set(byte('\xcf'), "\u030c") // Caron - -// STL unicode mapping -var stlUnicodeMapping = astikit.NewBiMap(). - Set(byte('\x8a'), "\u000a"). // Line break - Set(byte('\xa8'), "\u00a4"). // ¤ - Set(byte('\xa9'), "\u2018"). // ‘ - Set(byte('\xaa'), "\u201C"). // “ - Set(byte('\xab'), "\u00AB"). // « - Set(byte('\xac'), "\u2190"). // ← - Set(byte('\xad'), "\u2191"). // ↑ - Set(byte('\xae'), "\u2192"). // → - Set(byte('\xaf'), "\u2193"). // ↓ - Set(byte('\xb4'), "\u00D7"). // × - Set(byte('\xb8'), "\u00F7"). // ÷ - Set(byte('\xb9'), "\u2019"). // ’ - Set(byte('\xba'), "\u201D"). // ” - Set(byte('\xbc'), "\u00BC"). // ¼ - Set(byte('\xbd'), "\u00BD"). // ½ - Set(byte('\xbe'), "\u00BE"). // ¾ - Set(byte('\xbf'), "\u00BF"). // ¿ - Set(byte('\xd0'), "\u2015"). // ― - Set(byte('\xd1'), "\u00B9"). // ¹ - Set(byte('\xd2'), "\u00AE"). // ® - Set(byte('\xd3'), "\u00A9"). // © - Set(byte('\xd4'), "\u2122"). // ™ - Set(byte('\xd5'), "\u266A"). // ♪ - Set(byte('\xd6'), "\u00AC"). // ¬ - Set(byte('\xd7'), "\u00A6"). // ¦ - Set(byte('\xdc'), "\u215B"). // ⅛ - Set(byte('\xdd'), "\u215C"). // ⅜ - Set(byte('\xde'), "\u215D"). // ⅝ - Set(byte('\xdf'), "\u215E"). // ⅞ - Set(byte('\xe0'), "\u2126"). // Ohm Ω - Set(byte('\xe1'), "\u00C6"). // Æ - Set(byte('\xe2'), "\u0110"). // Đ - Set(byte('\xe3'), "\u00AA"). // ª - Set(byte('\xe4'), "\u0126"). // Ħ - Set(byte('\xe6'), "\u0132"). // IJ - Set(byte('\xe7'), "\u013F"). // Ŀ - Set(byte('\xe8'), "\u0141"). // Ł - Set(byte('\xe9'), "\u00D8"). // Ø - Set(byte('\xea'), "\u0152"). // Œ - Set(byte('\xeb'), "\u00BA"). // º - Set(byte('\xec'), "\u00DE"). // Þ - Set(byte('\xed'), "\u0166"). // Ŧ - Set(byte('\xee'), "\u014A"). // Ŋ - Set(byte('\xef'), "\u0149"). // ʼn - Set(byte('\xf0'), "\u0138"). // ĸ - Set(byte('\xf1'), "\u00E6"). // æ - Set(byte('\xf2'), "\u0111"). // đ - Set(byte('\xf3'), "\u00F0"). // ð - Set(byte('\xf4'), "\u0127"). // ħ - Set(byte('\xf5'), "\u0131"). // ı - Set(byte('\xf6'), "\u0133"). // ij - Set(byte('\xf7'), "\u0140"). // ŀ - Set(byte('\xf8'), "\u0142"). // ł - Set(byte('\xf9'), "\u00F8"). // ø - Set(byte('\xfa'), "\u0153"). // œ - Set(byte('\xfb'), "\u00DF"). // ß - Set(byte('\xfc'), "\u00FE"). // þ - Set(byte('\xfd'), "\u0167"). // ŧ - Set(byte('\xfe'), "\u014B"). // ŋ - Set(byte('\xff'), "\u00AD") // Soft hyphen - -// encodeTextSTL encodes the STL text -func encodeTextSTL(i string) (o []byte) { - i = string(norm.NFD.Bytes([]byte(i))) - for _, c := range i { - if v, ok := stlUnicodeMapping.GetInverse(string(c)); ok { - o = append(o, v.(byte)) - } else if v, ok := stlUnicodeDiacritic.GetInverse(string(c)); ok { - o = append(o[:len(o)-1], v.(byte), o[len(o)-1]) - } else { - o = append(o, byte(c)) - } - } - return -} - -func parseSTLJustificationCode(i byte) Justification { - switch i { - case 0x00: - return JustificationUnchanged - case 0x01: - return JustificationLeft - case 0x02: - return JustificationCentered - case 0x03: - return JustificationRight - default: - return JustificationUnchanged - } -} - -func isTeletextControlCode(i byte) (b bool) { - return i <= 0x1f -} - -func parseOpenSubtitleRow(i *Item, d decoder, fs func() styler, row []byte) error { - // Loop through columns - var l = Line{} - var li = LineItem{InlineStyle: &StyleAttributes{}} - var s styler - for _, v := range row { - // Create specific styler - if fs != nil { - s = fs() - } - - if isTeletextControlCode(v) { - return errors.New("teletext control code in open text") - } - if s != nil { - s.parseSpacingAttribute(v) - } - - // Style has been set - if s != nil && s.hasBeenSet() { - // Style has changed - if s.hasChanged(li.InlineStyle) { - if len(li.Text) > 0 { - // Append line item - appendOpenSubtitleLineItem(&l, li, s) - - // Create new line item - sa := &StyleAttributes{} - *sa = *li.InlineStyle - li = LineItem{InlineStyle: sa} - } - s.update(li.InlineStyle) - } - } else { - // Append text - li.Text += string(d.decode(v)) - } - } - - appendOpenSubtitleLineItem(&l, li, s) - - // Append line - if len(l.Items) > 0 { - i.Lines = append(i.Lines, l) - } - return nil -} - -func appendOpenSubtitleLineItem(l *Line, li LineItem, s styler) { - // There's some text - if len(strings.TrimSpace(li.Text)) > 0 { - // Make sure inline style exists - if li.InlineStyle == nil { - li.InlineStyle = &StyleAttributes{} - } - - // Propagate style attributes - if s != nil { - s.propagateStyleAttributes(li.InlineStyle) - } - - // Append line item - li.Text = strings.TrimSpace(li.Text) - l.Items = append(l.Items, li) - } -} diff --git a/vendor/github.com/asticode/go-astisub/subtitles.go b/vendor/github.com/asticode/go-astisub/subtitles.go deleted file mode 100644 index e6617998e68..00000000000 --- a/vendor/github.com/asticode/go-astisub/subtitles.go +++ /dev/null @@ -1,779 +0,0 @@ -package astisub - -import ( - "errors" - "fmt" - "math" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/asticode/go-astikit" -) - -// Bytes -var ( - BytesBOM = []byte{239, 187, 191} - bytesLineSeparator = []byte("\n") - bytesSpace = []byte(" ") -) - -// Colors -var ( - ColorBlack = &Color{} - ColorBlue = &Color{Blue: 255} - ColorCyan = &Color{Blue: 255, Green: 255} - ColorGray = &Color{Blue: 128, Green: 128, Red: 128} - ColorGreen = &Color{Green: 128} - ColorLime = &Color{Green: 255} - ColorMagenta = &Color{Blue: 255, Red: 255} - ColorMaroon = &Color{Red: 128} - ColorNavy = &Color{Blue: 128} - ColorOlive = &Color{Green: 128, Red: 128} - ColorPurple = &Color{Blue: 128, Red: 128} - ColorRed = &Color{Red: 255} - ColorSilver = &Color{Blue: 192, Green: 192, Red: 192} - ColorTeal = &Color{Blue: 128, Green: 128} - ColorYellow = &Color{Green: 255, Red: 255} - ColorWhite = &Color{Blue: 255, Green: 255, Red: 255} -) - -// Errors -var ( - ErrInvalidExtension = errors.New("astisub: invalid extension") - ErrNoSubtitlesToWrite = errors.New("astisub: no subtitles to write") -) - -// Now allows testing functions using it -var Now = func() time.Time { - return time.Now() -} - -// Options represents open or write options -type Options struct { - Filename string - Teletext TeletextOptions - STL STLOptions -} - -// Open opens a subtitle reader based on options -func Open(o Options) (s *Subtitles, err error) { - // Open the file - var f *os.File - if f, err = os.Open(o.Filename); err != nil { - err = fmt.Errorf("astisub: opening %s failed: %w", o.Filename, err) - return - } - defer f.Close() - - // Parse the content - switch filepath.Ext(strings.ToLower(o.Filename)) { - case ".srt": - s, err = ReadFromSRT(f) - case ".ssa", ".ass": - s, err = ReadFromSSA(f) - case ".stl": - s, err = ReadFromSTL(f, o.STL) - case ".ts": - s, err = ReadFromTeletext(f, o.Teletext) - case ".ttml": - s, err = ReadFromTTML(f) - case ".vtt": - s, err = ReadFromWebVTT(f) - default: - err = ErrInvalidExtension - } - return -} - -// OpenFile opens a file regardless of other options -func OpenFile(filename string) (*Subtitles, error) { - return Open(Options{Filename: filename}) -} - -// Subtitles represents an ordered list of items with formatting -type Subtitles struct { - Items []*Item - Metadata *Metadata - Regions map[string]*Region - Styles map[string]*Style -} - -// NewSubtitles creates new subtitles -func NewSubtitles() *Subtitles { - return &Subtitles{ - Regions: make(map[string]*Region), - Styles: make(map[string]*Style), - } -} - -// Item represents a text to show between 2 time boundaries with formatting -type Item struct { - Comments []string - Index int - EndAt time.Duration - InlineStyle *StyleAttributes - Lines []Line - Region *Region - StartAt time.Duration - Style *Style -} - -// String implements the Stringer interface -func (i Item) String() string { - var os []string - for _, l := range i.Lines { - os = append(os, l.String()) - } - return strings.Join(os, " - ") -} - -// Color represents a color -type Color struct { - Alpha, Blue, Green, Red uint8 -} - -// newColorFromSSAString builds a new color based on an SSA string -func newColorFromSSAString(s string, base int) (c *Color, err error) { - var i int64 - if i, err = strconv.ParseInt(s, base, 64); err != nil { - err = fmt.Errorf("parsing int %s with base %d failed: %w", s, base, err) - return - } - c = &Color{ - Alpha: uint8(i>>24) & 0xff, - Blue: uint8(i>>16) & 0xff, - Green: uint8(i>>8) & 0xff, - Red: uint8(i) & 0xff, - } - return -} - -// SSAString expresses the color as an SSA string -func (c *Color) SSAString() string { - return fmt.Sprintf("%.8x", uint32(c.Alpha)<<24|uint32(c.Blue)<<16|uint32(c.Green)<<8|uint32(c.Red)) -} - -// TTMLString expresses the color as a TTML string -func (c *Color) TTMLString() string { - return fmt.Sprintf("%.6x", uint32(c.Red)<<16|uint32(c.Green)<<8|uint32(c.Blue)) -} - -type Justification int - -var ( - JustificationUnchanged = Justification(1) - JustificationLeft = Justification(2) - JustificationCentered = Justification(3) - JustificationRight = Justification(4) -) - -// StyleAttributes represents style attributes -type StyleAttributes struct { - SSAAlignment *int - SSAAlphaLevel *float64 - SSAAngle *float64 // degrees - SSABackColour *Color - SSABold *bool - SSABorderStyle *int - SSAEffect string - SSAEncoding *int - SSAFontName string - SSAFontSize *float64 - SSAItalic *bool - SSALayer *int - SSAMarginLeft *int // pixels - SSAMarginRight *int // pixels - SSAMarginVertical *int // pixels - SSAMarked *bool - SSAOutline *float64 // pixels - SSAOutlineColour *Color - SSAPrimaryColour *Color - SSAScaleX *float64 // % - SSAScaleY *float64 // % - SSASecondaryColour *Color - SSAShadow *float64 // pixels - SSASpacing *float64 // pixels - SSAStrikeout *bool - SSAUnderline *bool - STLBoxing *bool - STLItalics *bool - STLJustification *Justification - STLPosition *STLPosition - STLUnderline *bool - TeletextColor *Color - TeletextDoubleHeight *bool - TeletextDoubleSize *bool - TeletextDoubleWidth *bool - TeletextSpacesAfter *int - TeletextSpacesBefore *int - // TODO Use pointers with real types below - TTMLBackgroundColor *string // https://htmlcolorcodes.com/fr/ - TTMLColor *string - TTMLDirection *string - TTMLDisplay *string - TTMLDisplayAlign *string - TTMLExtent *string - TTMLFontFamily *string - TTMLFontSize *string - TTMLFontStyle *string - TTMLFontWeight *string - TTMLLineHeight *string - TTMLOpacity *string - TTMLOrigin *string - TTMLOverflow *string - TTMLPadding *string - TTMLShowBackground *string - TTMLTextAlign *string - TTMLTextDecoration *string - TTMLTextOutline *string - TTMLUnicodeBidi *string - TTMLVisibility *string - TTMLWrapOption *string - TTMLWritingMode *string - TTMLZIndex *int - WebVTTAlign string - WebVTTItalics bool - WebVTTLine string - WebVTTLines int - WebVTTPosition string - WebVTTRegionAnchor string - WebVTTScroll string - WebVTTSize string - WebVTTVertical string - WebVTTViewportAnchor string - WebVTTWidth string -} - -func (sa *StyleAttributes) propagateSSAAttributes() {} - -func (sa *StyleAttributes) propagateSTLAttributes() { - if sa.STLJustification != nil { - switch *sa.STLJustification { - case JustificationCentered: - // default to middle anyway? - case JustificationRight: - sa.WebVTTAlign = "right" - case JustificationLeft: - sa.WebVTTAlign = "left" - } - } -} - -func (sa *StyleAttributes) propagateTeletextAttributes() { - if sa.TeletextColor != nil { - sa.TTMLColor = astikit.StrPtr("#" + sa.TeletextColor.TTMLString()) - } -} - -//reference for migration: https://w3c.github.io/ttml-webvtt-mapping/ -func (sa *StyleAttributes) propagateTTMLAttributes() { - if sa.TTMLTextAlign != nil { - sa.WebVTTAlign = *sa.TTMLTextAlign - } - if sa.TTMLExtent != nil { - //region settings - lineHeight := 5 //assuming height of line as 5.33vh - dimensions := strings.Split(*sa.TTMLExtent, " ") - if len(dimensions) > 1 { - sa.WebVTTWidth = dimensions[0] - if height, err := strconv.Atoi(strings.ReplaceAll(dimensions[1], "%", "")); err == nil { - sa.WebVTTLines = height / lineHeight - } - //cue settings - //default TTML WritingMode is lrtb i.e. left to right, top to bottom - sa.WebVTTSize = dimensions[1] - if sa.TTMLWritingMode != nil && strings.HasPrefix(*sa.TTMLWritingMode, "tb") { - sa.WebVTTSize = dimensions[0] - } - } - } - if sa.TTMLOrigin != nil { - //region settings - sa.WebVTTRegionAnchor = "0%,0%" - sa.WebVTTViewportAnchor = strings.ReplaceAll(strings.TrimSpace(*sa.TTMLOrigin), " ", ",") - sa.WebVTTScroll = "up" - //cue settings - coordinates := strings.Split(*sa.TTMLOrigin, " ") - if len(coordinates) > 1 { - sa.WebVTTLine = coordinates[0] - sa.WebVTTPosition = coordinates[1] - if sa.TTMLWritingMode != nil && strings.HasPrefix(*sa.TTMLWritingMode, "tb") { - sa.WebVTTLine = coordinates[1] - sa.WebVTTPosition = coordinates[0] - } - } - } -} - -func (sa *StyleAttributes) propagateWebVTTAttributes() {} - -// Metadata represents metadata -// TODO Merge attributes -type Metadata struct { - Comments []string - Framerate int - Language string - SSACollisions string - SSAOriginalEditing string - SSAOriginalScript string - SSAOriginalTiming string - SSAOriginalTranslation string - SSAPlayDepth *int - SSAPlayResX, SSAPlayResY *int - SSAScriptType string - SSAScriptUpdatedBy string - SSASynchPoint string - SSATimer *float64 - SSAUpdateDetails string - SSAWrapStyle string - STLCountryOfOrigin string - STLCreationDate *time.Time - STLDisplayStandardCode string - STLMaximumNumberOfDisplayableCharactersInAnyTextRow *int - STLMaximumNumberOfDisplayableRows *int - STLPublisher string - STLRevisionDate *time.Time - STLSubtitleListReferenceCode string - STLTimecodeStartOfProgramme time.Duration - Title string - TTMLCopyright string -} - -// Region represents a subtitle's region -type Region struct { - ID string - InlineStyle *StyleAttributes - Style *Style -} - -// Style represents a subtitle's style -type Style struct { - ID string - InlineStyle *StyleAttributes - Style *Style -} - -// Line represents a set of formatted line items -type Line struct { - Items []LineItem - VoiceName string -} - -// String implement the Stringer interface -func (l Line) String() string { - var texts []string - for _, i := range l.Items { - texts = append(texts, i.Text) - } - return strings.Join(texts, " ") -} - -// LineItem represents a formatted line item -type LineItem struct { - InlineStyle *StyleAttributes - Style *Style - Text string -} - -// Add adds a duration to each time boundaries. As in the time package, duration can be negative. -func (s *Subtitles) Add(d time.Duration) { - for idx := 0; idx < len(s.Items); idx++ { - s.Items[idx].EndAt += d - s.Items[idx].StartAt += d - if s.Items[idx].EndAt <= 0 && s.Items[idx].StartAt <= 0 { - s.Items = append(s.Items[:idx], s.Items[idx+1:]...) - idx-- - } else if s.Items[idx].StartAt <= 0 { - s.Items[idx].StartAt = time.Duration(0) - } - } -} - -// Duration returns the subtitles duration -func (s Subtitles) Duration() time.Duration { - if len(s.Items) == 0 { - return time.Duration(0) - } - return s.Items[len(s.Items)-1].EndAt -} - -// ForceDuration updates the subtitles duration. -// If requested duration is bigger, then we create a dummy item. -// If requested duration is smaller, then we remove useless items and we cut the last item or add a dummy item. -func (s *Subtitles) ForceDuration(d time.Duration, addDummyItem bool) { - // Requested duration is the same as the subtitles'one - if s.Duration() == d { - return - } - - // Requested duration is bigger than subtitles'one - if s.Duration() > d { - // Find last item before input duration and update end at - var lastIndex = -1 - for index, i := range s.Items { - // Start at is bigger than input duration, we've found the last item - if i.StartAt >= d { - lastIndex = index - break - } else if i.EndAt > d { - s.Items[index].EndAt = d - } - } - - // Last index has been found - if lastIndex != -1 { - s.Items = s.Items[:lastIndex] - } - } - - // Add dummy item with the minimum duration possible - if addDummyItem && s.Duration() < d { - s.Items = append(s.Items, &Item{EndAt: d, Lines: []Line{{Items: []LineItem{{Text: "..."}}}}, StartAt: d - time.Millisecond}) - } -} - -// Fragment fragments subtitles with a specific fragment duration -func (s *Subtitles) Fragment(f time.Duration) { - // Nothing to fragment - if len(s.Items) == 0 { - return - } - - // Here we want to simulate fragments of duration f until there are no subtitles left in that period of time - var fragmentStartAt, fragmentEndAt = time.Duration(0), f - for fragmentStartAt < s.Items[len(s.Items)-1].EndAt { - // We loop through subtitles and process the ones that either contain the fragment start at, - // or contain the fragment end at - // - // It's useless processing subtitles contained between fragment start at and end at - // |____________________| <- subtitle - // | | - // fragment start at fragment end at - for i, sub := range s.Items { - // Init - var newSub = &Item{} - *newSub = *sub - - // A switch is more readable here - switch { - // Subtitle contains fragment start at - // |____________________| <- subtitle - // | | - // fragment start at fragment end at - case sub.StartAt < fragmentStartAt && sub.EndAt > fragmentStartAt: - sub.StartAt = fragmentStartAt - newSub.EndAt = fragmentStartAt - // Subtitle contains fragment end at - // |____________________| <- subtitle - // | | - // fragment start at fragment end at - case sub.StartAt < fragmentEndAt && sub.EndAt > fragmentEndAt: - sub.StartAt = fragmentEndAt - newSub.EndAt = fragmentEndAt - default: - continue - } - - // Insert new sub - s.Items = append(s.Items[:i], append([]*Item{newSub}, s.Items[i:]...)...) - } - - // Update fragments boundaries - fragmentStartAt += f - fragmentEndAt += f - } - - // Order - s.Order() -} - -// IsEmpty returns whether the subtitles are empty -func (s Subtitles) IsEmpty() bool { - return len(s.Items) == 0 -} - -// Merge merges subtitles i into subtitles -func (s *Subtitles) Merge(i *Subtitles) { - // Append items - s.Items = append(s.Items, i.Items...) - s.Order() - - // Add regions - for _, region := range i.Regions { - if _, ok := s.Regions[region.ID]; !ok { - s.Regions[region.ID] = region - } - } - - // Add styles - for _, style := range i.Styles { - if _, ok := s.Styles[style.ID]; !ok { - s.Styles[style.ID] = style - } - } -} - -// Optimize optimizes subtitles -func (s *Subtitles) Optimize() { - // Nothing to optimize - if len(s.Items) == 0 { - return - } - - // Remove unused regions and style - s.removeUnusedRegionsAndStyles() -} - -// removeUnusedRegionsAndStyles removes unused regions and styles -func (s *Subtitles) removeUnusedRegionsAndStyles() { - // Loop through items - var usedRegions, usedStyles = make(map[string]bool), make(map[string]bool) - for _, item := range s.Items { - // Add region - if item.Region != nil { - usedRegions[item.Region.ID] = true - } - - // Add style - if item.Style != nil { - usedStyles[item.Style.ID] = true - } - - // Loop through lines - for _, line := range item.Lines { - // Loop through line items - for _, lineItem := range line.Items { - // Add style - if lineItem.Style != nil { - usedStyles[lineItem.Style.ID] = true - } - } - } - } - - // Loop through regions - for id, region := range s.Regions { - if _, ok := usedRegions[region.ID]; ok { - if region.Style != nil { - usedStyles[region.Style.ID] = true - } - } else { - delete(s.Regions, id) - } - } - - // Loop through style - for id, style := range s.Styles { - if _, ok := usedStyles[style.ID]; !ok { - delete(s.Styles, id) - } - } -} - -// Order orders items -func (s *Subtitles) Order() { - // Nothing to do if less than 1 element - if len(s.Items) <= 1 { - return - } - - // Order - var swapped = true - for swapped { - swapped = false - for index := 1; index < len(s.Items); index++ { - if s.Items[index-1].StartAt > s.Items[index].StartAt { - var tmp = s.Items[index-1] - s.Items[index-1] = s.Items[index] - s.Items[index] = tmp - swapped = true - } - } - } -} - -// RemoveStyling removes the styling from the subtitles -func (s *Subtitles) RemoveStyling() { - s.Regions = map[string]*Region{} - s.Styles = map[string]*Style{} - for _, i := range s.Items { - i.Region = nil - i.Style = nil - i.InlineStyle = nil - for idxLine, l := range i.Lines { - for idxLineItem := range l.Items { - i.Lines[idxLine].Items[idxLineItem].InlineStyle = nil - i.Lines[idxLine].Items[idxLineItem].Style = nil - } - } - } -} - -// Unfragment unfragments subtitles -func (s *Subtitles) Unfragment() { - // Nothing to do if less than 1 element - if len(s.Items) <= 1 { - return - } - - // Order - s.Order() - - // Loop through items - for i := 0; i < len(s.Items)-1; i++ { - for j := i + 1; j < len(s.Items); j++ { - // Items are the same - if s.Items[i].String() == s.Items[j].String() && s.Items[i].EndAt >= s.Items[j].StartAt { - // Only override end time if longer - if s.Items[i].EndAt < s.Items[j].EndAt { - s.Items[i].EndAt = s.Items[j].EndAt - } - s.Items = append(s.Items[:j], s.Items[j+1:]...) - j-- - } else if s.Items[i].EndAt < s.Items[j].StartAt { - break - } - } - } -} - -// Write writes subtitles to a file -func (s Subtitles) Write(dst string) (err error) { - // Create the file - var f *os.File - if f, err = os.Create(dst); err != nil { - err = fmt.Errorf("astisub: creating %s failed: %w", dst, err) - return - } - defer f.Close() - - // Write the content - switch filepath.Ext(strings.ToLower(dst)) { - case ".srt": - err = s.WriteToSRT(f) - case ".ssa", ".ass": - err = s.WriteToSSA(f) - case ".stl": - err = s.WriteToSTL(f) - case ".ttml": - err = s.WriteToTTML(f) - case ".vtt": - err = s.WriteToWebVTT(f) - default: - err = ErrInvalidExtension - } - return -} - -// parseDuration parses a duration in "00:00:00.000", "00:00:00,000" or "0:00:00:00" format -func parseDuration(i, millisecondSep string, numberOfMillisecondDigits int) (o time.Duration, err error) { - // Split milliseconds - var parts = strings.Split(i, millisecondSep) - var milliseconds int - var s string - if len(parts) >= 2 { - // Invalid number of millisecond digits - s = strings.TrimSpace(parts[len(parts)-1]) - if len(s) > 3 { - err = fmt.Errorf("astisub: Invalid number of millisecond digits detected in %s", i) - return - } - - // Parse milliseconds - if milliseconds, err = strconv.Atoi(s); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", s, err) - return - } - milliseconds *= int(math.Pow10(numberOfMillisecondDigits - len(s))) - s = strings.Join(parts[:len(parts)-1], millisecondSep) - } else { - s = i - } - - // Split hours, minutes and seconds - parts = strings.Split(strings.TrimSpace(s), ":") - var partSeconds, partMinutes, partHours string - if len(parts) == 2 { - partSeconds = parts[1] - partMinutes = parts[0] - } else if len(parts) == 3 { - partSeconds = parts[2] - partMinutes = parts[1] - partHours = parts[0] - } else { - err = fmt.Errorf("astisub: No hours, minutes or seconds detected in %s", i) - return - } - - // Parse seconds - var seconds int - s = strings.TrimSpace(partSeconds) - if seconds, err = strconv.Atoi(s); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", s, err) - return - } - - // Parse minutes - var minutes int - s = strings.TrimSpace(partMinutes) - if minutes, err = strconv.Atoi(s); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", s, err) - return - } - - // Parse hours - var hours int - if len(partHours) > 0 { - s = strings.TrimSpace(partHours) - if hours, err = strconv.Atoi(s); err != nil { - err = fmt.Errorf("astisub: atoi of %s failed: %w", s, err) - return - } - } - - // Generate output - o = time.Duration(milliseconds)*time.Millisecond + time.Duration(seconds)*time.Second + time.Duration(minutes)*time.Minute + time.Duration(hours)*time.Hour - return -} - -// formatDuration formats a duration -func formatDuration(i time.Duration, millisecondSep string, numberOfMillisecondDigits int) (s string) { - // Parse hours - var hours = int(i / time.Hour) - var n = i % time.Hour - if hours < 10 { - s += "0" - } - s += strconv.Itoa(hours) + ":" - - // Parse minutes - var minutes = int(n / time.Minute) - n = i % time.Minute - if minutes < 10 { - s += "0" - } - s += strconv.Itoa(minutes) + ":" - - // Parse seconds - var seconds = int(n / time.Second) - n = i % time.Second - if seconds < 10 { - s += "0" - } - s += strconv.Itoa(seconds) + millisecondSep - - // Parse milliseconds - var milliseconds = float64(n/time.Millisecond) / float64(1000) - s += fmt.Sprintf("%."+strconv.Itoa(numberOfMillisecondDigits)+"f", milliseconds)[2:] - return -} - -// appendStringToBytesWithNewLine adds a string to bytes then adds a new line -func appendStringToBytesWithNewLine(i []byte, s string) (o []byte) { - o = append(i, []byte(s)...) - o = append(o, bytesLineSeparator...) - return -} diff --git a/vendor/github.com/asticode/go-astisub/teletext.go b/vendor/github.com/asticode/go-astisub/teletext.go deleted file mode 100644 index 3223f778c3b..00000000000 --- a/vendor/github.com/asticode/go-astisub/teletext.go +++ /dev/null @@ -1,997 +0,0 @@ -package astisub - -import ( - "context" - "errors" - "fmt" - "io" - "log" - "math/bits" - "sort" - "strings" - "time" - - "github.com/asticode/go-astikit" - "github.com/asticode/go-astits" -) - -// Errors -var ( - ErrNoValidTeletextPID = errors.New("astisub: no valid teletext PID") -) - -type teletextCharset [96][]byte - -type teletextNationalSubset [13][]byte - -// Chapter: 15.2 | Page: 109 | Link: http://www.etsi.org/deliver/etsi_i_ets/300700_300799/300706/01_60/ets_300706e01p.pdf -// It is indexed by triplet1 then by national option subset code -var teletextCharsets = map[uint8]map[uint8]struct { - g0 *teletextCharset - g2 *teletextCharset - national *teletextNationalSubset -}{ - 0: { - 0: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetEnglish}, - 1: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetFrench}, - 2: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetSwedishFinnishHungarian}, - 3: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetCzechSlovak}, - 4: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetGerman}, - 5: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetPortugueseSpanish}, - 6: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetItalian}, - 7: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - }, - 1: { - 0: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetPolish}, - 1: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetFrench}, - 2: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetSwedishFinnishHungarian}, - 3: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetCzechSlovak}, - 4: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetGerman}, - 5: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 6: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetItalian}, - 7: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - }, - 2: { - 0: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetEnglish}, - 1: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetFrench}, - 2: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetSwedishFinnishHungarian}, - 3: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetCzechSlovak}, - 4: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetGerman}, - 5: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetPortugueseSpanish}, - 6: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetItalian}, - 7: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - }, - 3: { - 0: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 1: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 2: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 3: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 4: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 5: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetSerbianCroatianSlovenian}, - 6: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin}, - 7: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetRomanian}, - }, - 4: { - 0: {g0: teletextCharsetG0CyrillicOption1, g2: teletextCharsetG2Cyrillic}, - 1: {g0: teletextCharsetG0CyrillicOption2, g2: teletextCharsetG2Cyrillic}, - 2: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetEstonian}, - 3: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetCzechSlovak}, - 4: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetGerman}, - 5: {g0: teletextCharsetG0CyrillicOption3, g2: teletextCharsetG2Cyrillic}, - 6: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetLettishLithuanian}, - }, - 6: { - 3: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Latin, national: teletextNationalSubsetTurkish}, - 7: {g0: teletextCharsetG0Greek, g2: teletextCharsetG2Greek}, - }, - 8: { - 0: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Arabic, national: teletextNationalSubsetEnglish}, - 1: {g0: teletextCharsetG0Latin, g2: teletextCharsetG2Arabic, national: teletextNationalSubsetFrench}, - 7: {g0: teletextCharsetG0Arabic, g2: teletextCharsetG2Arabic}, - }, - 10: { - 5: {g0: teletextCharsetG0Hebrew, g2: teletextCharsetG2Arabic}, - 7: {g0: teletextCharsetG0Arabic, g2: teletextCharsetG2Arabic}, - }, -} - -// Teletext G0 charsets -var ( - teletextCharsetG0CyrillicOption1 = &teletextCharset{ - []byte{0x20}, []byte{0x21}, []byte{0x22}, []byte{0x23}, []byte{0x24}, []byte{0x25}, []byte{0xd1, 0x8b}, - []byte{0x27}, []byte{0x28}, []byte{0x29}, []byte{0x2a}, []byte{0x2b}, []byte{0x2c}, []byte{0x2d}, - []byte{0x2e}, []byte{0x2f}, []byte{0x30}, []byte{0x31}, []byte{0xe3, 0x88, 0x80}, []byte{0x33}, []byte{0x34}, - []byte{0x35}, []byte{0x36}, []byte{0x37}, []byte{0x38}, []byte{0x39}, []byte{0x3a}, []byte{0x3b}, - []byte{0x3c}, []byte{0x3d}, []byte{0x3e}, []byte{0x3f}, []byte{0xd0, 0xa7}, []byte{0xd0, 0x90}, - []byte{0xd0, 0x91}, []byte{0xd0, 0xa6}, []byte{0xd0, 0x94}, []byte{0xd0, 0x95}, []byte{0xd0, 0xa4}, - []byte{0xd0, 0x93}, []byte{0xd0, 0xa5}, []byte{0xd0, 0x98}, []byte{0xd0, 0x88}, []byte{0xd0, 0x9a}, - []byte{0xd0, 0x9b}, []byte{0xd0, 0x9c}, []byte{0xd0, 0x9d}, []byte{0xd0, 0x9e}, []byte{0xd0, 0x9f}, - []byte{0xd0, 0x8c}, []byte{0xd0, 0xa0}, []byte{0xd0, 0xa1}, []byte{0xd0, 0xa2}, []byte{0xd0, 0xa3}, - []byte{0xd0, 0x92}, []byte{0xd0, 0x83}, []byte{0xd0, 0x89}, []byte{0xd0, 0x8a}, []byte{0xd0, 0x97}, - []byte{0xd0, 0x8b}, []byte{0xd0, 0x96}, []byte{0xd0, 0x82}, []byte{0xd0, 0xa8}, []byte{0xd0, 0x8f}, - []byte{0xd1, 0x87}, []byte{0xd0, 0xb0}, []byte{0xd0, 0xb1}, []byte{0xd1, 0x86}, []byte{0xd0, 0xb4}, - []byte{0xd0, 0xb5}, []byte{0xd1, 0x84}, []byte{0xd0, 0xb3}, []byte{0xd1, 0x85}, []byte{0xd0, 0xb8}, - []byte{0xd0, 0xa8}, []byte{0xd0, 0xba}, []byte{0xd0, 0xbb}, []byte{0xd0, 0xbc}, []byte{0xd0, 0xbd}, - []byte{0xd0, 0xbe}, []byte{0xd0, 0xbf}, []byte{0xd0, 0xac}, []byte{0xd1, 0x80}, []byte{0xd1, 0x81}, - []byte{0xd1, 0x82}, []byte{0xd1, 0x83}, []byte{0xd0, 0xb2}, []byte{0xd0, 0xa3}, []byte{0xd0, 0xa9}, - []byte{0xd0, 0xaa}, []byte{0xd0, 0xb7}, []byte{0xd0, 0xab}, []byte{0xd0, 0xb6}, []byte{0xd0, 0xa2}, - []byte{0xd1, 0x88}, []byte{0xd0, 0xaf}, - } - teletextCharsetG0CyrillicOption2 = &teletextCharset{ - []byte{0x20}, []byte{0x21}, []byte{0x22}, []byte{0x23}, []byte{0x24}, []byte{0x25}, []byte{0xd1, 0x8b}, - []byte{0x27}, []byte{0x28}, []byte{0x29}, []byte{0x2a}, []byte{0x2b}, []byte{0x2c}, []byte{0x2d}, - []byte{0x2e}, []byte{0x2f}, []byte{0x30}, []byte{0x31}, []byte{0x32}, []byte{0x33}, []byte{0x34}, - []byte{0x35}, []byte{0x36}, []byte{0x37}, []byte{0x38}, []byte{0x39}, []byte{0x3a}, []byte{0x3b}, - []byte{0x3c}, []byte{0x3d}, []byte{0x3e}, []byte{0x3f}, []byte{0xd0, 0xae}, []byte{0xd0, 0x90}, - []byte{0xd0, 0x91}, []byte{0xd0, 0xa6}, []byte{0xd0, 0x94}, []byte{0xd0, 0x95}, []byte{0xd0, 0xa4}, - []byte{0xd0, 0x93}, []byte{0xd0, 0xa5}, []byte{0xd0, 0x98}, []byte{0xd0, 0x99}, []byte{0xd0, 0x9a}, - []byte{0xd0, 0x9b}, []byte{0xd0, 0x9c}, []byte{0xd0, 0x9d}, []byte{0xd0, 0x9e}, []byte{0xd0, 0x9f}, - []byte{0xd0, 0xaf}, []byte{0xd0, 0xa0}, []byte{0xd0, 0xa1}, []byte{0xd0, 0xa2}, []byte{0xd0, 0xa3}, - []byte{0xd0, 0x96}, []byte{0xd0, 0x92}, []byte{0xd0, 0xac}, []byte{0xd0, 0xaa}, []byte{0xd0, 0x97}, - []byte{0xd0, 0xa8}, []byte{0xd0, 0xad}, []byte{0xd0, 0xa9}, []byte{0xd0, 0xa7}, []byte{0xd0, 0xab}, - []byte{0xd1, 0x8e}, []byte{0xd0, 0xb0}, []byte{0xd0, 0xb1}, []byte{0xd1, 0x86}, []byte{0xd0, 0xb4}, - []byte{0xd0, 0xb5}, []byte{0xd1, 0x84}, []byte{0xd0, 0xb3}, []byte{0xd1, 0x85}, []byte{0xd0, 0xb8}, - []byte{0xd0, 0xb9}, []byte{0xd0, 0xba}, []byte{0xd0, 0xbb}, []byte{0xd0, 0xbc}, []byte{0xd0, 0xbd}, - []byte{0xd0, 0xbe}, []byte{0xd0, 0xbf}, []byte{0xd1, 0x8f}, []byte{0xd1, 0x80}, []byte{0xd1, 0x81}, - []byte{0xd1, 0x82}, []byte{0xd1, 0x83}, []byte{0xd0, 0xb6}, []byte{0xd0, 0xb2}, []byte{0xd1, 0x8c}, - []byte{0xd1, 0x8a}, []byte{0xd0, 0xb7}, []byte{0xd1, 0x88}, []byte{0xd1, 0x8d}, []byte{0xd1, 0x89}, - []byte{0xd1, 0x87}, []byte{0xd1, 0x8b}, - } - teletextCharsetG0CyrillicOption3 = &teletextCharset{ - []byte{0x20}, []byte{0x21}, []byte{0x22}, []byte{0x23}, []byte{0x24}, []byte{0x25}, []byte{0xc3, 0xaf}, - []byte{0x27}, []byte{0x28}, []byte{0x29}, []byte{0x2a}, []byte{0x2b}, []byte{0x2c}, []byte{0x2d}, - []byte{0x2e}, []byte{0x2f}, []byte{0x30}, []byte{0x31}, []byte{0x32}, []byte{0x33}, []byte{0x34}, - []byte{0x35}, []byte{0x36}, []byte{0x37}, []byte{0x38}, []byte{0x39}, []byte{0x3a}, []byte{0x3b}, - []byte{0x3c}, []byte{0x3d}, []byte{0x3e}, []byte{0x3f}, []byte{0xd0, 0xae}, []byte{0xd0, 0x90}, - []byte{0xd0, 0x91}, []byte{0xd0, 0xa6}, []byte{0xd0, 0x94}, []byte{0xd0, 0x95}, []byte{0xd0, 0xa4}, - []byte{0xd0, 0x93}, []byte{0xd0, 0xa5}, []byte{0xd0, 0x98}, []byte{0xd0, 0x99}, []byte{0xd0, 0x9a}, - []byte{0xd0, 0x9b}, []byte{0xd0, 0x9c}, []byte{0xd0, 0x9d}, []byte{0xd0, 0x9e}, []byte{0xd0, 0x9f}, - []byte{0xd0, 0xaf}, []byte{0xd0, 0xa0}, []byte{0xd0, 0xa1}, []byte{0xd0, 0xa2}, []byte{0xd0, 0xa3}, - []byte{0xd0, 0x96}, []byte{0xd0, 0x92}, []byte{0xd0, 0xac}, []byte{0x49}, []byte{0xd0, 0x97}, - []byte{0xd0, 0xa8}, []byte{0xd0, 0xad}, []byte{0xd0, 0xa9}, []byte{0xd0, 0xa7}, []byte{0xc3, 0x8f}, - []byte{0xd1, 0x8e}, []byte{0xd0, 0xb0}, []byte{0xd0, 0xb1}, []byte{0xd1, 0x86}, []byte{0xd0, 0xb4}, - []byte{0xd0, 0xb5}, []byte{0xd1, 0x84}, []byte{0xd0, 0xb3}, []byte{0xd1, 0x85}, []byte{0xd0, 0xb8}, - []byte{0xd0, 0xb9}, []byte{0xd0, 0xba}, []byte{0xd0, 0xbb}, []byte{0xd0, 0xbc}, []byte{0xd0, 0xbd}, - []byte{0xd0, 0xbe}, []byte{0xd0, 0xbf}, []byte{0xd1, 0x8f}, []byte{0xd1, 0x80}, []byte{0xd1, 0x81}, - []byte{0xd1, 0x82}, []byte{0xd1, 0x83}, []byte{0xd0, 0xb6}, []byte{0xd0, 0xb2}, []byte{0xd1, 0x8c}, - []byte{0x69}, []byte{0xd0, 0xb7}, []byte{0xd1, 0x88}, []byte{0xd1, 0x8d}, []byte{0xd1, 0x89}, - []byte{0xd1, 0x87}, []byte{0xc3, 0xbf}, - } - teletextCharsetG0Greek = &teletextCharset{ - []byte{0x20}, []byte{0x21}, []byte{0x22}, []byte{0x23}, []byte{0x24}, []byte{0x25}, []byte{0x26}, - []byte{0x27}, []byte{0x28}, []byte{0x29}, []byte{0x2a}, []byte{0x2b}, []byte{0x2c}, []byte{0x2d}, - []byte{0x2e}, []byte{0x2f}, []byte{0x30}, []byte{0x31}, []byte{0x32}, []byte{0x33}, []byte{0x34}, - []byte{0x35}, []byte{0x36}, []byte{0x37}, []byte{0x38}, []byte{0x39}, []byte{0x3a}, []byte{0x3b}, - []byte{0x3c}, []byte{0x3d}, []byte{0x3e}, []byte{0x3f}, []byte{0xce, 0x90}, []byte{0xce, 0x91}, - []byte{0xce, 0x92}, []byte{0xce, 0x93}, []byte{0xce, 0x94}, []byte{0xce, 0x95}, []byte{0xce, 0x96}, - []byte{0xce, 0x97}, []byte{0xce, 0x98}, []byte{0xce, 0x99}, []byte{0xce, 0x9a}, []byte{0xce, 0x9b}, - []byte{0xce, 0x9c}, []byte{0xce, 0x9d}, []byte{0xce, 0x9e}, []byte{0xce, 0x9f}, []byte{0xce, 0xa0}, - []byte{0xce, 0xa1}, []byte{0xce, 0xa2}, []byte{0xce, 0xa3}, []byte{0xce, 0xa4}, []byte{0xce, 0xa5}, - []byte{0xce, 0xa6}, []byte{0xce, 0xa7}, []byte{0xce, 0xa8}, []byte{0xce, 0xa9}, []byte{0xce, 0xaa}, - []byte{0xce, 0xab}, []byte{0xce, 0xac}, []byte{0xce, 0xad}, []byte{0xce, 0xae}, []byte{0xce, 0xaf}, - []byte{0xce, 0xb0}, []byte{0xce, 0xb1}, []byte{0xce, 0xb2}, []byte{0xce, 0xb3}, []byte{0xce, 0xb4}, - []byte{0xce, 0xb5}, []byte{0xce, 0xb6}, []byte{0xce, 0xb7}, []byte{0xce, 0xb8}, []byte{0xce, 0xb9}, - []byte{0xce, 0xba}, []byte{0xce, 0xbb}, []byte{0xce, 0xbc}, []byte{0xce, 0xbd}, []byte{0xce, 0xbe}, - []byte{0xce, 0xbf}, []byte{0xcf, 0x80}, []byte{0xcf, 0x81}, []byte{0xcf, 0x82}, []byte{0xcf, 0x83}, - []byte{0xcf, 0x84}, []byte{0xcf, 0x85}, []byte{0xcf, 0x86}, []byte{0xcf, 0x87}, []byte{0xcf, 0x88}, - []byte{0xcf, 0x89}, []byte{0xcf, 0x8a}, []byte{0xcf, 0x8b}, []byte{0xcf, 0x8c}, []byte{0xcf, 0x8d}, - []byte{0xcf, 0x8e}, []byte{0xcf, 0x8f}, - } - teletextCharsetG0Latin = &teletextCharset{ - []byte{0x20}, []byte{0x21}, []byte{0x22}, []byte{0xc2, 0xa3}, []byte{0x24}, []byte{0x25}, []byte{0x26}, - []byte{0x27}, []byte{0x28}, []byte{0x29}, []byte{0x2a}, []byte{0x2b}, []byte{0x2c}, []byte{0x2d}, - []byte{0x2e}, []byte{0x2f}, []byte{0x30}, []byte{0x31}, []byte{0x32}, []byte{0x33}, []byte{0x34}, - []byte{0x35}, []byte{0x36}, []byte{0x37}, []byte{0x38}, []byte{0x39}, []byte{0x3a}, []byte{0x3b}, - []byte{0x3c}, []byte{0x3d}, []byte{0x3e}, []byte{0x3f}, []byte{0x40}, []byte{0x41}, []byte{0x42}, - []byte{0x43}, []byte{0x44}, []byte{0x45}, []byte{0x46}, []byte{0x47}, []byte{0x48}, []byte{0x49}, - []byte{0x4a}, []byte{0x4b}, []byte{0x4c}, []byte{0x4d}, []byte{0x4e}, []byte{0x4f}, []byte{0x50}, - []byte{0x51}, []byte{0x52}, []byte{0x53}, []byte{0x54}, []byte{0x55}, []byte{0x56}, []byte{0x57}, - []byte{0x58}, []byte{0x59}, []byte{0x5a}, []byte{0xc2, 0xab}, []byte{0xc2, 0xbd}, []byte{0xc2, 0xbb}, - []byte{0x5e}, []byte{0x23}, []byte{0x2d}, []byte{0x61}, []byte{0x62}, []byte{0x63}, []byte{0x64}, - []byte{0x65}, []byte{0x66}, []byte{0x67}, []byte{0x68}, []byte{0x69}, []byte{0x6a}, []byte{0x6b}, - []byte{0x6c}, []byte{0x6d}, []byte{0x6e}, []byte{0x6f}, []byte{0x70}, []byte{0x71}, []byte{0x72}, - []byte{0x73}, []byte{0x74}, []byte{0x75}, []byte{0x76}, []byte{0x77}, []byte{0x78}, []byte{0x79}, - []byte{0x7a}, []byte{0xc2, 0xbc}, []byte{0xc2, 0xa6}, []byte{0xc2, 0xbe}, []byte{0xc3, 0xb7}, []byte{0x7f}, - } - // TODO Add - teletextCharsetG0Arabic = teletextCharsetG0Latin - teletextCharsetG0Hebrew = teletextCharsetG0Latin -) - -// Teletext G2 charsets -var ( - teletextCharsetG2Latin = &teletextCharset{ - []byte{0x20}, []byte{0xc2, 0xa1}, []byte{0xc2, 0xa2}, []byte{0xc2, 0xa3}, []byte{0x24}, - []byte{0xc2, 0xa5}, []byte{0x23}, []byte{0xc2, 0xa7}, []byte{0xc2, 0xa4}, []byte{0xe2, 0x80, 0x98}, - []byte{0xe2, 0x80, 0x9c}, []byte{0xc2, 0xab}, []byte{0xe2, 0x86, 0x90}, []byte{0xe2, 0x86, 0x91}, - []byte{0xe2, 0x86, 0x92}, []byte{0xe2, 0x86, 0x93}, []byte{0xc2, 0xb0}, []byte{0xc2, 0xb1}, - []byte{0xc2, 0xb2}, []byte{0xc2, 0xb3}, []byte{0xc3, 0x97}, []byte{0xc2, 0xb5}, []byte{0xc2, 0xb6}, - []byte{0xc2, 0xb7}, []byte{0xc3, 0xb7}, []byte{0xe2, 0x80, 0x99}, []byte{0xe2, 0x80, 0x9d}, - []byte{0xc2, 0xbb}, []byte{0xc2, 0xbc}, []byte{0xc2, 0xbd}, []byte{0xc2, 0xbe}, []byte{0xc2, 0xbf}, - []byte{0x20}, []byte{0xcc, 0x80}, []byte{0xcc, 0x81}, []byte{0xcc, 0x82}, []byte{0xcc, 0x83}, - []byte{0xcc, 0x84}, []byte{0xcc, 0x86}, []byte{0xcc, 0x87}, []byte{0xcc, 0x88}, []byte{0x00}, - []byte{0xcc, 0x8a}, []byte{0xcc, 0xa7}, []byte{0x5f}, []byte{0xcc, 0x8b}, []byte{0xcc, 0xa8}, - []byte{0xcc, 0x8c}, []byte{0xe2, 0x80, 0x95}, []byte{0xc2, 0xb9}, []byte{0xc2, 0xae}, []byte{0xc2, 0xa9}, - []byte{0xe2, 0x84, 0xa2}, []byte{0xe2, 0x99, 0xaa}, []byte{0xe2, 0x82, 0xac}, []byte{0xe2, 0x80, 0xb0}, - []byte{0xce, 0xb1}, []byte{0x00}, []byte{0x00}, []byte{0x00}, []byte{0xe2, 0x85, 0x9b}, - []byte{0xe2, 0x85, 0x9c}, []byte{0xe2, 0x85, 0x9d}, []byte{0xe2, 0x85, 0x9e}, []byte{0xce, 0xa9}, - []byte{0xc3, 0x86}, []byte{0xc4, 0x90}, []byte{0xc2, 0xaa}, []byte{0xc4, 0xa6}, []byte{0x00}, - []byte{0xc4, 0xb2}, []byte{0xc4, 0xbf}, []byte{0xc5, 0x81}, []byte{0xc3, 0x98}, []byte{0xc5, 0x92}, - []byte{0xc2, 0xba}, []byte{0xc3, 0x9e}, []byte{0xc5, 0xa6}, []byte{0xc5, 0x8a}, []byte{0xc5, 0x89}, - []byte{0xc4, 0xb8}, []byte{0xc3, 0xa6}, []byte{0xc4, 0x91}, []byte{0xc3, 0xb0}, []byte{0xc4, 0xa7}, - []byte{0xc4, 0xb1}, []byte{0xc4, 0xb3}, []byte{0xc5, 0x80}, []byte{0xc5, 0x82}, []byte{0xc3, 0xb8}, - []byte{0xc5, 0x93}, []byte{0xc3, 0x9f}, []byte{0xc3, 0xbe}, []byte{0xc5, 0xa7}, []byte{0xc5, 0x8b}, - []byte{0x20}, - } - // TODO Add - teletextCharsetG2Arabic = teletextCharsetG2Latin - teletextCharsetG2Cyrillic = teletextCharsetG2Latin - teletextCharsetG2Greek = teletextCharsetG2Latin -) - -var teletextNationalSubsetCharactersPositionInG0 = [13]uint8{0x03, 0x04, 0x20, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x5b, 0x5c, 0x5d, 0x5e} - -// Teletext national subsets -var ( - teletextNationalSubsetCzechSlovak = &teletextNationalSubset{ - []byte{0x23}, []byte{0xc5, 0xaf}, []byte{0xc4, 0x8d}, []byte{0xc5, 0xa5}, []byte{0xc5, 0xbe}, - []byte{0xc3, 0xbd}, []byte{0xc3, 0xad}, []byte{0xc5, 0x99}, []byte{0xc3, 0xa9}, []byte{0xc3, 0xa1}, - []byte{0xc4, 0x9b}, []byte{0xc3, 0xba}, []byte{0xc5, 0xa1}, - } - teletextNationalSubsetEnglish = &teletextNationalSubset{ - []byte{0xc2, 0xa3}, []byte{0x24}, []byte{0x40}, []byte{0xc2, 0xab}, []byte{0xc2, 0xbd}, []byte{0xc2, 0xbb}, - []byte{0x5e}, []byte{0x23}, []byte{0x2d}, []byte{0xc2, 0xbc}, []byte{0xc2, 0xa6}, []byte{0xc2, 0xbe}, - []byte{0xc3, 0xb7}, - } - teletextNationalSubsetEstonian = &teletextNationalSubset{ - []byte{0x23}, []byte{0xc3, 0xb5}, []byte{0xc5, 0xa0}, []byte{0xc3, 0x84}, []byte{0xc3, 0x96}, - []byte{0xc5, 0xbe}, []byte{0xc3, 0x9c}, []byte{0xc3, 0x95}, []byte{0xc5, 0xa1}, []byte{0xc3, 0xa4}, - []byte{0xc3, 0xb6}, []byte{0xc5, 0xbe}, []byte{0xc3, 0xbc}, - } - teletextNationalSubsetFrench = &teletextNationalSubset{ - []byte{0xc3, 0xa9}, []byte{0xc3, 0xaf}, []byte{0xc3, 0xa0}, []byte{0xc3, 0xab}, []byte{0xc3, 0xaa}, - []byte{0xc3, 0xb9}, []byte{0xc3, 0xae}, []byte{0x23}, []byte{0xc3, 0xa8}, []byte{0xc3, 0xa2}, - []byte{0xc3, 0xb4}, []byte{0xc3, 0xbb}, []byte{0xc3, 0xa7}, - } - teletextNationalSubsetGerman = &teletextNationalSubset{ - []byte{0x23}, []byte{0x24}, []byte{0xc2, 0xa7}, []byte{0xc3, 0x84}, []byte{0xc3, 0x96}, []byte{0xc3, 0x9c}, - []byte{0x5e}, []byte{0x5f}, []byte{0xc2, 0xb0}, []byte{0xc3, 0xa4}, []byte{0xc3, 0xb6}, []byte{0xc3, 0xbc}, - []byte{0xc3, 0x9f}, - } - teletextNationalSubsetItalian = &teletextNationalSubset{ - []byte{0xc2, 0xa3}, []byte{0x24}, []byte{0xc3, 0xa9}, []byte{0xc2, 0xb0}, []byte{0xc3, 0xa7}, - []byte{0xc2, 0xbb}, []byte{0x5e}, []byte{0x23}, []byte{0xc3, 0xb9}, []byte{0xc3, 0xa0}, []byte{0xc3, 0xb2}, - []byte{0xc3, 0xa8}, []byte{0xc3, 0xac}, - } - teletextNationalSubsetLettishLithuanian = &teletextNationalSubset{ - []byte{0x23}, []byte{0x24}, []byte{0xc5, 0xa0}, []byte{0xc4, 0x97}, []byte{0xc4, 0x99}, []byte{0xc5, 0xbd}, - []byte{0xc4, 0x8d}, []byte{0xc5, 0xab}, []byte{0xc5, 0xa1}, []byte{0xc4, 0x85}, []byte{0xc5, 0xb3}, - []byte{0xc5, 0xbe}, []byte{0xc4, 0xaf}, - } - teletextNationalSubsetPolish = &teletextNationalSubset{ - []byte{0x23}, []byte{0xc5, 0x84}, []byte{0xc4, 0x85}, []byte{0xc5, 0xbb}, []byte{0xc5, 0x9a}, - []byte{0xc5, 0x81}, []byte{0xc4, 0x87}, []byte{0xc3, 0xb3}, []byte{0xc4, 0x99}, []byte{0xc5, 0xbc}, - []byte{0xc5, 0x9b}, []byte{0xc5, 0x82}, []byte{0xc5, 0xba}, - } - teletextNationalSubsetPortugueseSpanish = &teletextNationalSubset{ - []byte{0xc3, 0xa7}, []byte{0x24}, []byte{0xc2, 0xa1}, []byte{0xc3, 0xa1}, []byte{0xc3, 0xa9}, - []byte{0xc3, 0xad}, []byte{0xc3, 0xb3}, []byte{0xc3, 0xba}, []byte{0xc2, 0xbf}, []byte{0xc3, 0xbc}, - []byte{0xc3, 0xb1}, []byte{0xc3, 0xa8}, []byte{0xc3, 0xa0}, - } - teletextNationalSubsetRomanian = &teletextNationalSubset{ - []byte{0x23}, []byte{0xc2, 0xa4}, []byte{0xc5, 0xa2}, []byte{0xc3, 0x82}, []byte{0xc5, 0x9e}, - []byte{0xc4, 0x82}, []byte{0xc3, 0x8e}, []byte{0xc4, 0xb1}, []byte{0xc5, 0xa3}, []byte{0xc3, 0xa2}, - []byte{0xc5, 0x9f}, []byte{0xc4, 0x83}, []byte{0xc3, 0xae}, - } - teletextNationalSubsetSerbianCroatianSlovenian = &teletextNationalSubset{ - []byte{0x23}, []byte{0xc3, 0x8b}, []byte{0xc4, 0x8c}, []byte{0xc4, 0x86}, []byte{0xc5, 0xbd}, - []byte{0xc4, 0x90}, []byte{0xc5, 0xa0}, []byte{0xc3, 0xab}, []byte{0xc4, 0x8d}, []byte{0xc4, 0x87}, - []byte{0xc5, 0xbe}, []byte{0xc4, 0x91}, []byte{0xc5, 0xa1}, - } - teletextNationalSubsetSwedishFinnishHungarian = &teletextNationalSubset{ - []byte{0x23}, []byte{0xc2, 0xa4}, []byte{0xc3, 0x89}, []byte{0xc3, 0x84}, []byte{0xc3, 0x96}, - []byte{0xc3, 0x85}, []byte{0xc3, 0x9c}, []byte{0x5f}, []byte{0xc3, 0xa9}, []byte{0xc3, 0xa4}, - []byte{0xc3, 0xb6}, []byte{0xc3, 0xa5}, []byte{0xc3, 0xbc}, - } - teletextNationalSubsetTurkish = &teletextNationalSubset{ - []byte{0x54}, []byte{0xc4, 0x9f}, []byte{0xc4, 0xb0}, []byte{0xc5, 0x9e}, []byte{0xc3, 0x96}, - []byte{0xc3, 0x87}, []byte{0xc3, 0x9c}, []byte{0xc4, 0x9e}, []byte{0xc4, 0xb1}, []byte{0xc5, 0x9f}, - []byte{0xc3, 0xb6}, []byte{0xc3, 0xa7}, []byte{0xc3, 0xbc}, - } -) - -// Teletext PES data types -const ( - teletextPESDataTypeEBU = "EBU" - teletextPESDataTypeUnknown = "unknown" -) - -func teletextPESDataType(dataIdentifier uint8) string { - switch { - case dataIdentifier >= 0x10 && dataIdentifier <= 0x1f: - return teletextPESDataTypeEBU - } - return teletextPESDataTypeUnknown -} - -// Teletext PES data unit ids -const ( - teletextPESDataUnitIDEBUNonSubtitleData = 0x2 - teletextPESDataUnitIDEBUSubtitleData = 0x3 - teletextPESDataUnitIDStuffing = 0xff -) - -// TeletextOptions represents teletext options -type TeletextOptions struct { - Page int - PID int -} - -// ReadFromTeletext parses a teletext content -// http://www.etsi.org/deliver/etsi_en/300400_300499/300472/01.03.01_60/en_300472v010301p.pdf -// http://www.etsi.org/deliver/etsi_i_ets/300700_300799/300706/01_60/ets_300706e01p.pdf -// TODO Update README -// TODO Add tests -func ReadFromTeletext(r io.Reader, o TeletextOptions) (s *Subtitles, err error) { - // Init - s = &Subtitles{} - var dmx = astits.NewDemuxer(context.Background(), r) - - // Get the teletext PID - var pid uint16 - if pid, err = teletextPID(dmx, o); err != nil { - if err != ErrNoValidTeletextPID { - err = fmt.Errorf("astisub: getting teletext PID failed: %w", err) - } - return - } - - // Create character decoder - cd := newTeletextCharacterDecoder() - - // Create page buffer - b := newTeletextPageBuffer(o.Page, cd) - - // Loop in data - var firstTime, lastTime time.Time - var d *astits.DemuxerData - var ps []*teletextPage - for { - // Fetch next data - if d, err = dmx.NextData(); err != nil { - if err == astits.ErrNoMorePackets { - err = nil - break - } - err = fmt.Errorf("astisub: fetching next data failed: %w", err) - return - } - - // We only parse PES data - if d.PES == nil { - continue - } - - // This data is not of interest to us - if d.PID != pid || d.PES.Header.StreamID != astits.StreamIDPrivateStream1 { - continue - } - - // Get time - t := teletextDataTime(d) - if t.IsZero() { - continue - } - - // First and last time - if firstTime.IsZero() || firstTime.After(t) { - firstTime = t - } - if lastTime.IsZero() || lastTime.Before(t) { - lastTime = t - } - - // Append pages - ps = append(ps, b.process(d.PES, t)...) - } - - // Dump buffer - ps = append(ps, b.dump(lastTime)...) - - // Parse pages - for _, p := range ps { - p.parse(s, cd, firstTime) - } - return -} - -// TODO Add tests -func teletextDataTime(d *astits.DemuxerData) time.Time { - if d.PES.Header != nil && d.PES.Header.OptionalHeader != nil && d.PES.Header.OptionalHeader.PTS != nil { - return d.PES.Header.OptionalHeader.PTS.Time() - } else if d.FirstPacket != nil && d.FirstPacket.AdaptationField != nil && d.FirstPacket.AdaptationField.PCR != nil { - return d.FirstPacket.AdaptationField.PCR.Time() - } - return time.Time{} -} - -// If the PID teletext option is not indicated, it will walk through the ts data until it reaches a PMT packet to -// detect the first valid teletext PID -// TODO Add tests -func teletextPID(dmx *astits.Demuxer, o TeletextOptions) (pid uint16, err error) { - // PID is in the options - if o.PID > 0 { - pid = uint16(o.PID) - return - } - - // Loop in data - var d *astits.DemuxerData - for { - // Fetch next data - if d, err = dmx.NextData(); err != nil { - if err == astits.ErrNoMorePackets { - err = ErrNoValidTeletextPID - return - } - err = fmt.Errorf("astisub: fetching next data failed: %w", err) - return - } - - // PMT data - if d.PMT != nil { - // Retrieve valid teletext PIDs - var pids []uint16 - for _, s := range d.PMT.ElementaryStreams { - for _, dsc := range s.ElementaryStreamDescriptors { - if dsc.Tag == astits.DescriptorTagTeletext || dsc.Tag == astits.DescriptorTagVBITeletext { - pids = append(pids, s.ElementaryPID) - } - } - } - - // No valid teletext PIDs - if len(pids) == 0 { - err = ErrNoValidTeletextPID - return - } - - // Set pid - pid = pids[0] - log.Printf("astisub: no teletext pid specified, using pid %d", pid) - - // Rewind - if _, err = dmx.Rewind(); err != nil { - err = fmt.Errorf("astisub: rewinding failed: %w", err) - return - } - return - } - } -} - -type teletextPageBuffer struct { - cd *teletextCharacterDecoder - currentPage *teletextPage - donePages []*teletextPage - magazineNumber uint8 - pageNumber int - receiving bool -} - -func newTeletextPageBuffer(page int, cd *teletextCharacterDecoder) *teletextPageBuffer { - return &teletextPageBuffer{ - cd: cd, - magazineNumber: uint8(page / 100), - pageNumber: page % 100, - } -} - -// TODO Add tests -func (b *teletextPageBuffer) dump(lastTime time.Time) (ps []*teletextPage) { - if b.currentPage != nil { - b.currentPage.end = lastTime - ps = []*teletextPage{b.currentPage} - } - return -} - -// TODO Add tests -func (b *teletextPageBuffer) process(d *astits.PESData, t time.Time) (ps []*teletextPage) { - // Data identifier - var offset int - dataIdentifier := uint8(d.Data[offset]) - offset += 1 - - // Check data type - if teletextPESDataType(dataIdentifier) != teletextPESDataTypeEBU { - return - } - - // Loop through data units - for offset < len(d.Data) { - // ID - id := uint8(d.Data[offset]) - offset += 1 - - // Length - length := uint8(d.Data[offset]) - offset += 1 - - // Offset end - offsetEnd := offset + int(length) - if offsetEnd > len(d.Data) { - break - } - - // Parse data unit - b.parseDataUnit(d.Data[offset:offsetEnd], id, t) - - // Seek to end of data unit - offset = offsetEnd - } - - // Dump buffer - ps = b.donePages - b.donePages = []*teletextPage(nil) - return ps -} - -// TODO Add tests -func (b *teletextPageBuffer) parseDataUnit(i []byte, id uint8, t time.Time) { - // Check id - if id != teletextPESDataUnitIDEBUSubtitleData { - return - } - - // Field parity: i[0]&0x20 > 0 - // Line offset: uint8(i[0] & 0x1f) - // Framing code - framingCode := uint8(i[1]) - - // Check framing code - if framingCode != 0xe4 { - return - } - - // Magazine number and packet number - h1, ok := astikit.ByteHamming84Decode(i[2]) - if !ok { - return - } - h2, ok := astikit.ByteHamming84Decode(i[3]) - if !ok { - return - } - h := h2<<4 | h1 - magazineNumber := h & 0x7 - if magazineNumber == 0 { - magazineNumber = 8 - } - packetNumber := h >> 3 - - // Parse packet - b.parsePacket(i[4:], magazineNumber, packetNumber, t) -} - -// TODO Add tests -func (b *teletextPageBuffer) parsePacket(i []byte, magazineNumber, packetNumber uint8, t time.Time) { - if packetNumber == 0 { - b.parsePacketHeader(i, magazineNumber, t) - } else if b.receiving && magazineNumber == b.magazineNumber && (packetNumber >= 1 && packetNumber <= 25) { - b.parsePacketData(i, packetNumber) - } else { - // Designation code - designationCode, ok := astikit.ByteHamming84Decode(i[0]) - if !ok { - return - } - - // Parse packet - if b.receiving && magazineNumber == b.magazineNumber && packetNumber == 26 { - // TODO Implement - } else if b.receiving && magazineNumber == b.magazineNumber && packetNumber == 28 { - b.parsePacket28And29(i[1:], packetNumber, designationCode) - } else if magazineNumber == b.magazineNumber && packetNumber == 29 { - b.parsePacket28And29(i[1:], packetNumber, designationCode) - } else if magazineNumber == 8 && packetNumber == 30 { - b.parsePacket30(i, designationCode) - } - } -} - -// TODO Add tests -func (b *teletextPageBuffer) parsePacketHeader(i []byte, magazineNumber uint8, t time.Time) (transmissionDone bool) { - // Page number units - pageNumberUnits, ok := astikit.ByteHamming84Decode(i[0]) - if !ok { - return - } - - // Page number tens - pageNumberTens, ok := astikit.ByteHamming84Decode(i[1]) - if !ok { - return - } - pageNumber := int(pageNumberTens)*10 + int(pageNumberUnits) - - // 0xff is a reserved page number value - if pageNumberTens == 0xf && pageNumberUnits == 0xf { - return - } - - // Update magazine and page number - if b.magazineNumber == 0 && b.pageNumber == 0 { - // C6 - controlBits, ok := astikit.ByteHamming84Decode(i[5]) - if !ok { - return - } - subtitleFlag := controlBits&0x8 > 0 - - // This is a subtitle page - if subtitleFlag { - b.magazineNumber = magazineNumber - b.pageNumber = pageNumber - log.Printf("astisub: no teletext page specified, using page %d%.2d", b.magazineNumber, b.pageNumber) - } - } - - // C11 --> C14 - controlBits, ok := astikit.ByteHamming84Decode(i[7]) - if !ok { - return - } - magazineSerial := controlBits&0x1 > 0 - charsetCode := controlBits >> 1 - - // Page transmission is done - if b.receiving && ((magazineSerial && pageNumber != b.pageNumber) || - (!magazineSerial && pageNumber != b.pageNumber && magazineNumber == b.magazineNumber)) { - b.receiving = false - return - } - - // Invalid magazine or page number - if pageNumber != b.pageNumber || magazineNumber != b.magazineNumber { - return - } - - // Now that we know when the previous page ends we can add it to the done slice - if b.currentPage != nil { - b.currentPage.end = t - b.donePages = append(b.donePages, b.currentPage) - } - - // Reset - b.receiving = true - b.currentPage = newTeletextPage(charsetCode, t) - return -} - -// TODO Add tests -func (b *teletextPageBuffer) parsePacketData(i []byte, packetNumber uint8) { - // Make sure the map is initialized - if _, ok := b.currentPage.data[packetNumber]; !ok { - b.currentPage.data[packetNumber] = make([]byte, 40) - } - - // Loop through input - b.currentPage.rows = append(b.currentPage.rows, int(packetNumber)) - for idx := uint8(0); idx < 40; idx++ { - v, ok := astikit.ByteParity(bits.Reverse8(i[idx])) - if !ok { - v = 0 - } - b.currentPage.data[packetNumber][idx] = v - } -} - -// TODO Add tests -func (b *teletextPageBuffer) parsePacket28And29(i []byte, packetNumber, designationCode uint8) { - // Invalid designation code - if designationCode != 0 && designationCode != 4 { - return - } - - // Triplet 1 - // TODO triplet1 should be the results of hamming 24/18 decoding - triplet1 := uint32(i[2])<<16 | uint32(i[1])<<8 | uint32(i[0]) - - // We only process x/28 format 1 - if packetNumber == 28 && triplet1&0xf > 0 { - return - } - - // Update character decoder - if packetNumber == 28 { - b.cd.setTripletX28(triplet1) - } else { - b.cd.setTripletM29(triplet1) - } -} - -// TODO Add tests -func (b *teletextPageBuffer) parsePacket30(i []byte, designationCode uint8) { - // Switch on designation code to determine format - switch designationCode { - case 0, 1: - b.parsePacket30Format1(i) - case 2, 3: - b.parsePacket30Format2(i) - } -} - -func (b *teletextPageBuffer) parsePacket30Format1(i []byte) { - // TODO Implement - -} - -func (b *teletextPageBuffer) parsePacket30Format2(i []byte) { - // TODO Implement -} - -type teletextCharacterDecoder struct { - c teletextCharset - lastPageCharsetCode *uint8 - tripletM29 *uint32 - tripletX28 *uint32 -} - -func newTeletextCharacterDecoder() *teletextCharacterDecoder { - return &teletextCharacterDecoder{} -} - -// TODO Add tests -func (d *teletextCharacterDecoder) setTripletM29(i uint32) { - if *d.tripletM29 != i { - d.tripletM29 = astikit.UInt32Ptr(i) - d.updateCharset(d.lastPageCharsetCode, true) - } -} - -// TODO Add tests -func (d *teletextCharacterDecoder) setTripletX28(i uint32) { - if *d.tripletX28 != i { - d.tripletX28 = astikit.UInt32Ptr(i) - d.updateCharset(d.lastPageCharsetCode, true) - } -} - -// TODO Add tests -func (d *teletextCharacterDecoder) decode(i byte) []byte { - if i < 0x20 { - return []byte{} - } - return d.c[i-0x20] -} - -// TODO Add tests -func (d *teletextCharacterDecoder) updateCharset(pageCharsetCode *uint8, force bool) { - // Charset is up to date - if d.lastPageCharsetCode != nil && *pageCharsetCode == *d.lastPageCharsetCode && !force { - return - } - d.lastPageCharsetCode = pageCharsetCode - - // Get triplet - var triplet uint32 - if d.tripletX28 != nil { - triplet = *d.tripletX28 - } else if d.tripletM29 != nil { - triplet = *d.tripletM29 - } - - // Get charsets - d.c = *teletextCharsetG0Latin - var nationalOptionSubset *teletextNationalSubset - if v1, ok := teletextCharsets[uint8((triplet&0x3f80)>>10)]; ok { - if v2, ok := v1[*pageCharsetCode]; ok { - d.c = *v2.g0 - nationalOptionSubset = v2.national - } - } - - // Update g0 with national option subset - if nationalOptionSubset != nil { - for k, v := range nationalOptionSubset { - d.c[teletextNationalSubsetCharactersPositionInG0[k]] = v - } - } -} - -type teletextPage struct { - charsetCode uint8 - data map[uint8][]byte - end time.Time - rows []int - start time.Time -} - -func newTeletextPage(charsetCode uint8, start time.Time) *teletextPage { - return &teletextPage{ - charsetCode: charsetCode, - data: make(map[uint8][]byte), - start: start, - } -} - -func (p *teletextPage) parse(s *Subtitles, d *teletextCharacterDecoder, firstTime time.Time) { - // Update charset - d.updateCharset(astikit.UInt8Ptr(p.charsetCode), false) - - // No data - if len(p.data) == 0 { - return - } - - // Order rows - sort.Ints(p.rows) - - // Create item - i := &Item{ - EndAt: p.end.Sub(firstTime), - StartAt: p.start.Sub(firstTime), - } - - // Loop through rows - for _, idxRow := range p.rows { - parseTeletextRow(i, d, nil, p.data[uint8(idxRow)]) - } - - // Append item - s.Items = append(s.Items, i) -} - -type decoder interface { - decode(i byte) []byte -} - -type styler interface { - hasBeenSet() bool - hasChanged(s *StyleAttributes) bool - parseSpacingAttribute(i byte) - propagateStyleAttributes(s *StyleAttributes) - update(sa *StyleAttributes) -} - -func parseTeletextRow(i *Item, d decoder, fs func() styler, row []byte) { - // Loop through columns - var l = Line{} - var li = LineItem{InlineStyle: &StyleAttributes{}} - var started bool - var s styler - for _, v := range row { - // Create specific styler - if fs != nil { - s = fs() - } - - // Get spacing attributes - var color *Color - var doubleHeight, doubleSize, doubleWidth *bool - switch v { - case 0x0: - color = ColorBlack - case 0x1: - color = ColorRed - case 0x2: - color = ColorGreen - case 0x3: - color = ColorYellow - case 0x4: - color = ColorBlue - case 0x5: - color = ColorMagenta - case 0x6: - color = ColorCyan - case 0x7: - color = ColorWhite - case 0xa: - started = false - case 0xb: - started = true - case 0xc: - doubleHeight = astikit.BoolPtr(false) - doubleSize = astikit.BoolPtr(false) - doubleWidth = astikit.BoolPtr(false) - case 0xd: - doubleHeight = astikit.BoolPtr(true) - case 0xe: - doubleWidth = astikit.BoolPtr(true) - case 0xf: - doubleSize = astikit.BoolPtr(true) - default: - if s != nil { - s.parseSpacingAttribute(v) - } - } - - // Style has been set - if color != nil || doubleHeight != nil || doubleSize != nil || doubleWidth != nil || (s != nil && s.hasBeenSet()) { - // Style has changed - if color != li.InlineStyle.TeletextColor || doubleHeight != li.InlineStyle.TeletextDoubleHeight || - doubleSize != li.InlineStyle.TeletextDoubleSize || doubleWidth != li.InlineStyle.TeletextDoubleWidth || - (s != nil && s.hasChanged(li.InlineStyle)) { - // Line has started - if started { - // Append line item - appendTeletextLineItem(&l, li, s) - - // Create new line item - sa := &StyleAttributes{} - *sa = *li.InlineStyle - li = LineItem{InlineStyle: sa} - } - - // Update style attributes - if color != nil && color != li.InlineStyle.TeletextColor { - li.InlineStyle.TeletextColor = color - } - if doubleHeight != nil && doubleHeight != li.InlineStyle.TeletextDoubleHeight { - li.InlineStyle.TeletextDoubleHeight = doubleHeight - } - if doubleSize != nil && doubleSize != li.InlineStyle.TeletextDoubleSize { - li.InlineStyle.TeletextDoubleSize = doubleSize - } - if doubleWidth != nil && doubleWidth != li.InlineStyle.TeletextDoubleWidth { - li.InlineStyle.TeletextDoubleWidth = doubleWidth - } - if s != nil { - s.update(li.InlineStyle) - } - } - } else if started { - // Append text - li.Text += string(d.decode(v)) - } - } - - // Append line item - appendTeletextLineItem(&l, li, s) - - // Append line - if len(l.Items) > 0 { - i.Lines = append(i.Lines, l) - } -} - -func appendTeletextLineItem(l *Line, li LineItem, s styler) { - // There's some text - if len(strings.TrimSpace(li.Text)) > 0 { - // Make sure inline style exists - if li.InlineStyle == nil { - li.InlineStyle = &StyleAttributes{} - } - - // Get number of spaces before - li.InlineStyle.TeletextSpacesBefore = astikit.IntPtr(0) - for _, c := range li.Text { - if c == ' ' { - *li.InlineStyle.TeletextSpacesBefore++ - } else { - break - } - } - - // Get number of spaces after - li.InlineStyle.TeletextSpacesAfter = astikit.IntPtr(0) - for idx := len(li.Text) - 1; idx >= 0; idx-- { - if li.Text[idx] == ' ' { - *li.InlineStyle.TeletextSpacesAfter++ - } else { - break - } - } - - // Propagate style attributes - li.InlineStyle.propagateTeletextAttributes() - if s != nil { - s.propagateStyleAttributes(li.InlineStyle) - } - - // Append line item - li.Text = strings.TrimSpace(li.Text) - l.Items = append(l.Items, li) - } -} diff --git a/vendor/github.com/asticode/go-astisub/ttml.go b/vendor/github.com/asticode/go-astisub/ttml.go deleted file mode 100644 index 2e8046baa31..00000000000 --- a/vendor/github.com/asticode/go-astisub/ttml.go +++ /dev/null @@ -1,686 +0,0 @@ -package astisub - -import ( - "encoding/xml" - "fmt" - "io" - "regexp" - "sort" - "strconv" - "strings" - "time" - - "github.com/asticode/go-astikit" -) - -// https://www.w3.org/TR/ttaf1-dfxp/ -// http://www.skynav.com:8080/ttv/check -// https://www.speechpad.com/captions/ttml - -// TTML languages -const ( - ttmlLanguageChinese = "zh" - ttmlLanguageEnglish = "en" - ttmlLanguageJapanese = "ja" - ttmlLanguageFrench = "fr" - ttmlLanguageNorwegian = "no" -) - -// TTML language mapping -var ttmlLanguageMapping = astikit.NewBiMap(). - Set(ttmlLanguageChinese, LanguageChinese). - Set(ttmlLanguageEnglish, LanguageEnglish). - Set(ttmlLanguageFrench, LanguageFrench). - Set(ttmlLanguageJapanese, LanguageJapanese). - Set(ttmlLanguageNorwegian, LanguageNorwegian) - -// TTML Clock Time Frames and Offset Time -var ( - ttmlRegexpClockTimeFrames = regexp.MustCompile(`\:[\d]+$`) - ttmlRegexpOffsetTime = regexp.MustCompile(`^(\d+(\.\d+)?)(h|m|s|ms|f|t)$`) -) - -// TTMLIn represents an input TTML that must be unmarshaled -// We split it from the output TTML as we can't add strict namespace without breaking retrocompatibility -type TTMLIn struct { - Framerate int `xml:"frameRate,attr"` - Lang string `xml:"lang,attr"` - Metadata TTMLInMetadata `xml:"head>metadata"` - Regions []TTMLInRegion `xml:"head>layout>region"` - Styles []TTMLInStyle `xml:"head>styling>style"` - Subtitles []TTMLInSubtitle `xml:"body>div>p"` - Tickrate int `xml:"tickRate,attr"` - XMLName xml.Name `xml:"tt"` -} - -// metadata returns the Metadata of the TTML -func (t TTMLIn) metadata() (m *Metadata) { - m = &Metadata{ - Framerate: t.Framerate, - Title: t.Metadata.Title, - TTMLCopyright: t.Metadata.Copyright, - } - if v, ok := ttmlLanguageMapping.Get(astikit.StrPad(t.Lang, ' ', 2, astikit.PadCut)); ok { - m.Language = v.(string) - } - return -} - -// TTMLInMetadata represents an input TTML Metadata -type TTMLInMetadata struct { - Copyright string `xml:"copyright"` - Title string `xml:"title"` -} - -// TTMLInStyleAttributes represents input TTML style attributes -type TTMLInStyleAttributes struct { - BackgroundColor *string `xml:"backgroundColor,attr,omitempty"` - Color *string `xml:"color,attr,omitempty"` - Direction *string `xml:"direction,attr,omitempty"` - Display *string `xml:"display,attr,omitempty"` - DisplayAlign *string `xml:"displayAlign,attr,omitempty"` - Extent *string `xml:"extent,attr,omitempty"` - FontFamily *string `xml:"fontFamily,attr,omitempty"` - FontSize *string `xml:"fontSize,attr,omitempty"` - FontStyle *string `xml:"fontStyle,attr,omitempty"` - FontWeight *string `xml:"fontWeight,attr,omitempty"` - LineHeight *string `xml:"lineHeight,attr,omitempty"` - Opacity *string `xml:"opacity,attr,omitempty"` - Origin *string `xml:"origin,attr,omitempty"` - Overflow *string `xml:"overflow,attr,omitempty"` - Padding *string `xml:"padding,attr,omitempty"` - ShowBackground *string `xml:"showBackground,attr,omitempty"` - TextAlign *string `xml:"textAlign,attr,omitempty"` - TextDecoration *string `xml:"textDecoration,attr,omitempty"` - TextOutline *string `xml:"textOutline,attr,omitempty"` - UnicodeBidi *string `xml:"unicodeBidi,attr,omitempty"` - Visibility *string `xml:"visibility,attr,omitempty"` - WrapOption *string `xml:"wrapOption,attr,omitempty"` - WritingMode *string `xml:"writingMode,attr,omitempty"` - ZIndex *int `xml:"zIndex,attr,omitempty"` -} - -// StyleAttributes converts TTMLInStyleAttributes into a StyleAttributes -func (s TTMLInStyleAttributes) styleAttributes() (o *StyleAttributes) { - o = &StyleAttributes{ - TTMLBackgroundColor: s.BackgroundColor, - TTMLColor: s.Color, - TTMLDirection: s.Direction, - TTMLDisplay: s.Display, - TTMLDisplayAlign: s.DisplayAlign, - TTMLExtent: s.Extent, - TTMLFontFamily: s.FontFamily, - TTMLFontSize: s.FontSize, - TTMLFontStyle: s.FontStyle, - TTMLFontWeight: s.FontWeight, - TTMLLineHeight: s.LineHeight, - TTMLOpacity: s.Opacity, - TTMLOrigin: s.Origin, - TTMLOverflow: s.Overflow, - TTMLPadding: s.Padding, - TTMLShowBackground: s.ShowBackground, - TTMLTextAlign: s.TextAlign, - TTMLTextDecoration: s.TextDecoration, - TTMLTextOutline: s.TextOutline, - TTMLUnicodeBidi: s.UnicodeBidi, - TTMLVisibility: s.Visibility, - TTMLWrapOption: s.WrapOption, - TTMLWritingMode: s.WritingMode, - TTMLZIndex: s.ZIndex, - } - o.propagateTTMLAttributes() - return -} - -// TTMLInHeader represents an input TTML header -type TTMLInHeader struct { - ID string `xml:"id,attr,omitempty"` - Style string `xml:"style,attr,omitempty"` - TTMLInStyleAttributes -} - -// TTMLInRegion represents an input TTML region -type TTMLInRegion struct { - TTMLInHeader - XMLName xml.Name `xml:"region"` -} - -// TTMLInStyle represents an input TTML style -type TTMLInStyle struct { - TTMLInHeader - XMLName xml.Name `xml:"style"` -} - -// TTMLInSubtitle represents an input TTML subtitle -type TTMLInSubtitle struct { - Begin *TTMLInDuration `xml:"begin,attr,omitempty"` - End *TTMLInDuration `xml:"end,attr,omitempty"` - ID string `xml:"id,attr,omitempty"` - Items string `xml:",innerxml"` // We must store inner XML here since there's no tag to describe both any tag and chardata - Region string `xml:"region,attr,omitempty"` - Style string `xml:"style,attr,omitempty"` - TTMLInStyleAttributes -} - -// TTMLInItems represents input TTML items -type TTMLInItems []TTMLInItem - -// UnmarshalXML implements the XML unmarshaler interface -func (i *TTMLInItems) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { - // Get next tokens - var t xml.Token - for { - // Get next token - if t, err = d.Token(); err != nil { - if err == io.EOF { - break - } - err = fmt.Errorf("astisub: getting next token failed: %w", err) - return - } - - // Start element - if se, ok := t.(xml.StartElement); ok { - var e = TTMLInItem{} - if err = d.DecodeElement(&e, &se); err != nil { - err = fmt.Errorf("astisub: decoding xml.StartElement failed: %w", err) - return - } - *i = append(*i, e) - } else if b, ok := t.(xml.CharData); ok { - var str = strings.TrimSpace(string(b)) - if len(str) > 0 { - *i = append(*i, TTMLInItem{Text: str}) - } - } - } - return nil -} - -// TTMLInItem represents an input TTML item -type TTMLInItem struct { - Style string `xml:"style,attr,omitempty"` - Text string `xml:",chardata"` - TTMLInStyleAttributes - XMLName xml.Name -} - -// TTMLInDuration represents an input TTML duration -type TTMLInDuration struct { - d time.Duration - frames, framerate int // Framerate is in frame/s - ticks, tickrate int // Tickrate is in ticks/s -} - -// UnmarshalText implements the TextUnmarshaler interface -// Possible formats are: -// - hh:mm:ss.mmm -// - hh:mm:ss:fff (fff being frames) -// - [ticks]t ([ticks] being the tick amount) -func (d *TTMLInDuration) UnmarshalText(i []byte) (err error) { - // Reset duration - d.d = time.Duration(0) - d.frames = 0 - d.ticks = 0 - - // Check offset time - text := string(i) - if matches := ttmlRegexpOffsetTime.FindStringSubmatch(text); matches != nil { - // Parse value - var value float64 - if value, err = strconv.ParseFloat(matches[1], 64); err != nil { - err = fmt.Errorf("astisub: failed to parse value %s", matches[1]) - return - } - - // Parse metric - metric := matches[3] - - // Update duration - if metric == "t" { - d.ticks = int(value) - } else if metric == "f" { - d.frames = int(value) - } else { - // Get timebase - var timebase time.Duration - switch metric { - case "h": - timebase = time.Hour - case "m": - timebase = time.Minute - case "s": - timebase = time.Second - case "ms": - timebase = time.Millisecond - default: - err = fmt.Errorf("astisub: invalid metric %s", metric) - return - } - - // Update duration - d.d = time.Duration(value * float64(timebase.Nanoseconds())) - } - return - } - - // Extract clock time frames - if indexes := ttmlRegexpClockTimeFrames.FindStringIndex(text); indexes != nil { - // Parse frames - var s = text[indexes[0]+1 : indexes[1]] - if d.frames, err = strconv.Atoi(s); err != nil { - err = fmt.Errorf("astisub: atoi %s failed: %w", s, err) - return - } - - // Update text - text = text[:indexes[0]] + ".000" - } - - d.d, err = parseDuration(text, ".", 3) - return -} - -// duration returns the input TTML Duration's time.Duration -func (d TTMLInDuration) duration() (o time.Duration) { - if d.ticks > 0 && d.tickrate > 0 { - return time.Duration(float64(d.ticks) * 1e9 / float64(d.tickrate)) - } - o = d.d - if d.frames > 0 && d.framerate > 0 { - o += time.Duration(float64(d.frames) / float64(d.framerate) * float64(time.Second.Nanoseconds())) - } - return -} - -// ReadFromTTML parses a .ttml content -func ReadFromTTML(i io.Reader) (o *Subtitles, err error) { - // Init - o = NewSubtitles() - - // Unmarshal XML - var ttml TTMLIn - if err = xml.NewDecoder(i).Decode(&ttml); err != nil { - err = fmt.Errorf("astisub: xml decoding failed: %w", err) - return - } - - // Add metadata - o.Metadata = ttml.metadata() - - // Loop through styles - var parentStyles = make(map[string]*Style) - for _, ts := range ttml.Styles { - var s = &Style{ - ID: ts.ID, - InlineStyle: ts.TTMLInStyleAttributes.styleAttributes(), - } - o.Styles[s.ID] = s - if len(ts.Style) > 0 { - parentStyles[ts.Style] = s - } - } - - // Take care of parent styles - for id, s := range parentStyles { - if _, ok := o.Styles[id]; !ok { - err = fmt.Errorf("astisub: Style %s requested by style %s doesn't exist", id, s.ID) - return - } - s.Style = o.Styles[id] - } - - // Loop through regions - for _, tr := range ttml.Regions { - var r = &Region{ - ID: tr.ID, - InlineStyle: tr.TTMLInStyleAttributes.styleAttributes(), - } - if len(tr.Style) > 0 { - if _, ok := o.Styles[tr.Style]; !ok { - err = fmt.Errorf("astisub: Style %s requested by region %s doesn't exist", tr.Style, r.ID) - return - } - r.Style = o.Styles[tr.Style] - } - o.Regions[r.ID] = r - } - - // Loop through subtitles - for _, ts := range ttml.Subtitles { - // Init item - ts.Begin.framerate = ttml.Framerate - ts.Begin.tickrate = ttml.Tickrate - ts.End.framerate = ttml.Framerate - ts.End.tickrate = ttml.Tickrate - - var s = &Item{ - EndAt: ts.End.duration(), - InlineStyle: ts.TTMLInStyleAttributes.styleAttributes(), - StartAt: ts.Begin.duration(), - } - - // Add region - if len(ts.Region) > 0 { - if _, ok := o.Regions[ts.Region]; !ok { - err = fmt.Errorf("astisub: Region %s requested by subtitle between %s and %s doesn't exist", ts.Region, s.StartAt, s.EndAt) - return - } - s.Region = o.Regions[ts.Region] - } - - // Add style - if len(ts.Style) > 0 { - if _, ok := o.Styles[ts.Style]; !ok { - err = fmt.Errorf("astisub: Style %s requested by subtitle between %s and %s doesn't exist", ts.Style, s.StartAt, s.EndAt) - return - } - s.Style = o.Styles[ts.Style] - } - - // Unmarshal items - var items = TTMLInItems{} - if err = xml.Unmarshal([]byte(""+ts.Items+""), &items); err != nil { - err = fmt.Errorf("astisub: unmarshaling items failed: %w", err) - return - } - - // Loop through texts - var l = &Line{} - for _, tt := range items { - // New line specified with the "br" tag - if strings.ToLower(tt.XMLName.Local) == "br" { - s.Lines = append(s.Lines, *l) - l = &Line{} - continue - } - - // New line decoded as a line break. This can happen if there's a "br" tag within the text since - // since the go xml unmarshaler will unmarshal a "br" tag as a line break if the field has the - // chardata xml tag. - for idx, li := range strings.Split(tt.Text, "\n") { - // New line - if idx > 0 { - s.Lines = append(s.Lines, *l) - l = &Line{} - } - - // Init line item - var t = LineItem{ - InlineStyle: tt.TTMLInStyleAttributes.styleAttributes(), - Text: strings.TrimSpace(li), - } - - // Add style - if len(tt.Style) > 0 { - if _, ok := o.Styles[tt.Style]; !ok { - err = fmt.Errorf("astisub: Style %s requested by item with text %s doesn't exist", tt.Style, tt.Text) - return - } - t.Style = o.Styles[tt.Style] - } - - // Append items - l.Items = append(l.Items, t) - } - - } - s.Lines = append(s.Lines, *l) - - // Append subtitle - o.Items = append(o.Items, s) - } - return -} - -// TTMLOut represents an output TTML that must be marshaled -// We split it from the input TTML as this time we'll add strict namespaces -type TTMLOut struct { - Lang string `xml:"xml:lang,attr,omitempty"` - Metadata *TTMLOutMetadata `xml:"head>metadata,omitempty"` - Styles []TTMLOutStyle `xml:"head>styling>style,omitempty"` //!\\ Order is important! Keep Styling above Layout - Regions []TTMLOutRegion `xml:"head>layout>region,omitempty"` - Subtitles []TTMLOutSubtitle `xml:"body>div>p,omitempty"` - XMLName xml.Name `xml:"http://www.w3.org/ns/ttml tt"` - XMLNamespaceTTM string `xml:"xmlns:ttm,attr"` - XMLNamespaceTTS string `xml:"xmlns:tts,attr"` -} - -// TTMLOutMetadata represents an output TTML Metadata -type TTMLOutMetadata struct { - Copyright string `xml:"ttm:copyright,omitempty"` - Title string `xml:"ttm:title,omitempty"` -} - -// TTMLOutStyleAttributes represents output TTML style attributes -type TTMLOutStyleAttributes struct { - BackgroundColor *string `xml:"tts:backgroundColor,attr,omitempty"` - Color *string `xml:"tts:color,attr,omitempty"` - Direction *string `xml:"tts:direction,attr,omitempty"` - Display *string `xml:"tts:display,attr,omitempty"` - DisplayAlign *string `xml:"tts:displayAlign,attr,omitempty"` - Extent *string `xml:"tts:extent,attr,omitempty"` - FontFamily *string `xml:"tts:fontFamily,attr,omitempty"` - FontSize *string `xml:"tts:fontSize,attr,omitempty"` - FontStyle *string `xml:"tts:fontStyle,attr,omitempty"` - FontWeight *string `xml:"tts:fontWeight,attr,omitempty"` - LineHeight *string `xml:"tts:lineHeight,attr,omitempty"` - Opacity *string `xml:"tts:opacity,attr,omitempty"` - Origin *string `xml:"tts:origin,attr,omitempty"` - Overflow *string `xml:"tts:overflow,attr,omitempty"` - Padding *string `xml:"tts:padding,attr,omitempty"` - ShowBackground *string `xml:"tts:showBackground,attr,omitempty"` - TextAlign *string `xml:"tts:textAlign,attr,omitempty"` - TextDecoration *string `xml:"tts:textDecoration,attr,omitempty"` - TextOutline *string `xml:"tts:textOutline,attr,omitempty"` - UnicodeBidi *string `xml:"tts:unicodeBidi,attr,omitempty"` - Visibility *string `xml:"tts:visibility,attr,omitempty"` - WrapOption *string `xml:"tts:wrapOption,attr,omitempty"` - WritingMode *string `xml:"tts:writingMode,attr,omitempty"` - ZIndex *int `xml:"tts:zIndex,attr,omitempty"` -} - -// ttmlOutStyleAttributesFromStyleAttributes converts StyleAttributes into a TTMLOutStyleAttributes -func ttmlOutStyleAttributesFromStyleAttributes(s *StyleAttributes) TTMLOutStyleAttributes { - if s == nil { - return TTMLOutStyleAttributes{} - } - return TTMLOutStyleAttributes{ - BackgroundColor: s.TTMLBackgroundColor, - Color: s.TTMLColor, - Direction: s.TTMLDirection, - Display: s.TTMLDisplay, - DisplayAlign: s.TTMLDisplayAlign, - Extent: s.TTMLExtent, - FontFamily: s.TTMLFontFamily, - FontSize: s.TTMLFontSize, - FontStyle: s.TTMLFontStyle, - FontWeight: s.TTMLFontWeight, - LineHeight: s.TTMLLineHeight, - Opacity: s.TTMLOpacity, - Origin: s.TTMLOrigin, - Overflow: s.TTMLOverflow, - Padding: s.TTMLPadding, - ShowBackground: s.TTMLShowBackground, - TextAlign: s.TTMLTextAlign, - TextDecoration: s.TTMLTextDecoration, - TextOutline: s.TTMLTextOutline, - UnicodeBidi: s.TTMLUnicodeBidi, - Visibility: s.TTMLVisibility, - WrapOption: s.TTMLWrapOption, - WritingMode: s.TTMLWritingMode, - ZIndex: s.TTMLZIndex, - } -} - -// TTMLOutHeader represents an output TTML header -type TTMLOutHeader struct { - ID string `xml:"xml:id,attr,omitempty"` - Style string `xml:"style,attr,omitempty"` - TTMLOutStyleAttributes -} - -// TTMLOutRegion represents an output TTML region -type TTMLOutRegion struct { - TTMLOutHeader - XMLName xml.Name `xml:"region"` -} - -// TTMLOutStyle represents an output TTML style -type TTMLOutStyle struct { - TTMLOutHeader - XMLName xml.Name `xml:"style"` -} - -// TTMLOutSubtitle represents an output TTML subtitle -type TTMLOutSubtitle struct { - Begin TTMLOutDuration `xml:"begin,attr"` - End TTMLOutDuration `xml:"end,attr"` - ID string `xml:"id,attr,omitempty"` - Items []TTMLOutItem - Region string `xml:"region,attr,omitempty"` - Style string `xml:"style,attr,omitempty"` - TTMLOutStyleAttributes -} - -// TTMLOutItem represents an output TTML Item -type TTMLOutItem struct { - Style string `xml:"style,attr,omitempty"` - Text string `xml:",chardata"` - TTMLOutStyleAttributes - XMLName xml.Name -} - -// TTMLOutDuration represents an output TTML duration -type TTMLOutDuration time.Duration - -// MarshalText implements the TextMarshaler interface -func (t TTMLOutDuration) MarshalText() ([]byte, error) { - return []byte(formatDuration(time.Duration(t), ".", 3)), nil -} - -// WriteToTTML writes subtitles in .ttml format -func (s Subtitles) WriteToTTML(o io.Writer) (err error) { - // Do not write anything if no subtitles - if len(s.Items) == 0 { - return ErrNoSubtitlesToWrite - } - - // Init TTML - var ttml = TTMLOut{ - XMLNamespaceTTM: "http://www.w3.org/ns/ttml#metadata", - XMLNamespaceTTS: "http://www.w3.org/ns/ttml#styling", - } - - // Add metadata - if s.Metadata != nil { - if v, ok := ttmlLanguageMapping.GetInverse(s.Metadata.Language); ok { - ttml.Lang = v.(string) - } - if len(s.Metadata.TTMLCopyright) > 0 || len(s.Metadata.Title) > 0 { - ttml.Metadata = &TTMLOutMetadata{ - Copyright: s.Metadata.TTMLCopyright, - Title: s.Metadata.Title, - } - } - } - - // Add regions - var k []string - for _, region := range s.Regions { - k = append(k, region.ID) - } - sort.Strings(k) - for _, id := range k { - var ttmlRegion = TTMLOutRegion{TTMLOutHeader: TTMLOutHeader{ - ID: s.Regions[id].ID, - TTMLOutStyleAttributes: ttmlOutStyleAttributesFromStyleAttributes(s.Regions[id].InlineStyle), - }} - if s.Regions[id].Style != nil { - ttmlRegion.Style = s.Regions[id].Style.ID - } - ttml.Regions = append(ttml.Regions, ttmlRegion) - } - - // Add styles - k = []string{} - for _, style := range s.Styles { - k = append(k, style.ID) - } - sort.Strings(k) - for _, id := range k { - var ttmlStyle = TTMLOutStyle{TTMLOutHeader: TTMLOutHeader{ - ID: s.Styles[id].ID, - TTMLOutStyleAttributes: ttmlOutStyleAttributesFromStyleAttributes(s.Styles[id].InlineStyle), - }} - if s.Styles[id].Style != nil { - ttmlStyle.Style = s.Styles[id].Style.ID - } - ttml.Styles = append(ttml.Styles, ttmlStyle) - } - - // Add items - for _, item := range s.Items { - // Init subtitle - var ttmlSubtitle = TTMLOutSubtitle{ - Begin: TTMLOutDuration(item.StartAt), - End: TTMLOutDuration(item.EndAt), - TTMLOutStyleAttributes: ttmlOutStyleAttributesFromStyleAttributes(item.InlineStyle), - } - - // Add region - if item.Region != nil { - ttmlSubtitle.Region = item.Region.ID - } - - // Add style - if item.Style != nil { - ttmlSubtitle.Style = item.Style.ID - } - - // Add lines - for _, line := range item.Lines { - // Loop through line items - for idx, lineItem := range line.Items { - // Init ttml item - var ttmlItem = TTMLOutItem{ - Text: lineItem.Text, - TTMLOutStyleAttributes: ttmlOutStyleAttributesFromStyleAttributes(lineItem.InlineStyle), - XMLName: xml.Name{Local: "span"}, - } - // condition to avoid adding space as the last character. - if idx < len(line.Items)-1 { - ttmlItem.Text = ttmlItem.Text + " " - } - - // Add style - if lineItem.Style != nil { - ttmlItem.Style = lineItem.Style.ID - } - - // Add ttml item - ttmlSubtitle.Items = append(ttmlSubtitle.Items, ttmlItem) - } - - // Add line break - ttmlSubtitle.Items = append(ttmlSubtitle.Items, TTMLOutItem{XMLName: xml.Name{Local: "br"}}) - } - - // Remove last line break - if len(ttmlSubtitle.Items) > 0 { - ttmlSubtitle.Items = ttmlSubtitle.Items[:len(ttmlSubtitle.Items)-1] - } - - // Append subtitle - ttml.Subtitles = append(ttml.Subtitles, ttmlSubtitle) - } - - // Marshal XML - var e = xml.NewEncoder(o) - e.Indent("", " ") - if err = e.Encode(ttml); err != nil { - err = fmt.Errorf("astisub: xml encoding failed: %w", err) - return - } - return -} diff --git a/vendor/github.com/asticode/go-astisub/webvtt.go b/vendor/github.com/asticode/go-astisub/webvtt.go deleted file mode 100644 index c186d49f773..00000000000 --- a/vendor/github.com/asticode/go-astisub/webvtt.go +++ /dev/null @@ -1,537 +0,0 @@ -package astisub - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "regexp" - "sort" - "strconv" - "strings" - "time" - - "golang.org/x/net/html" -) - -// https://www.w3.org/TR/webvtt1/ - -// Constants -const ( - webvttBlockNameComment = "comment" - webvttBlockNameRegion = "region" - webvttBlockNameStyle = "style" - webvttBlockNameText = "text" - webvttTimeBoundariesSeparator = " --> " - webvttTimestampMap = "X-TIMESTAMP-MAP" -) - -// Vars -var ( - bytesWebVTTItalicEndTag = []byte("") - bytesWebVTTItalicStartTag = []byte("") - bytesWebVTTTimeBoundariesSeparator = []byte(webvttTimeBoundariesSeparator) - webVTTRegexpStartTag = regexp.MustCompile(`()`) -) - -// parseDurationWebVTT parses a .vtt duration -func parseDurationWebVTT(i string) (time.Duration, error) { - return parseDuration(i, ".", 3) -} - -// https://tools.ietf.org/html/rfc8216#section-3.5 -// Eg., `X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000` => 10s -// `X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:180000` => 2s -func parseTimestampMapWebVTT(line string) (timeOffset time.Duration, err error) { - splits := strings.Split(line, "=") - if len(splits) <= 1 { - err = fmt.Errorf("astisub: invalid X-TIMESTAMP-MAP, no '=' found") - return - } - right := splits[1] - - var local time.Duration - var mpegts int64 - for _, split := range strings.Split(right, ",") { - splits := strings.SplitN(split, ":", 2) - if len(splits) <= 1 { - err = fmt.Errorf("astisub: invalid X-TIMESTAMP-MAP, part %q didn't contain ':'", right) - return - } - - switch strings.ToLower(strings.TrimSpace(splits[0])) { - case "local": - local, err = parseDurationWebVTT(splits[1]) - if err != nil { - err = fmt.Errorf("astisub: parsing webvtt duration failed: %w", err) - return - } - case "mpegts": - mpegts, err = strconv.ParseInt(splits[1], 10, 0) - if err != nil { - err = fmt.Errorf("astisub: parsing int %s failed: %w", splits[1], err) - return - } - } - } - - timeOffset = time.Duration(mpegts)*time.Second/90000 - local - return -} - -// ReadFromWebVTT parses a .vtt content -// TODO Tags (u, i, b) -// TODO Class -func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) { - // Init - o = NewSubtitles() - var scanner = bufio.NewScanner(i) - var line string - var lineNum int - - // Skip the header - for scanner.Scan() { - lineNum++ - line = scanner.Text() - line = strings.TrimPrefix(line, string(BytesBOM)) - if fs := strings.Fields(line); len(fs) > 0 && fs[0] == "WEBVTT" { - break - } - } - - // Scan - var item = &Item{} - var blockName string - var comments []string - var index int - var timeOffset time.Duration - - for scanner.Scan() { - // Fetch line - line = strings.TrimSpace(scanner.Text()) - lineNum++ - - switch { - // Comment - case strings.HasPrefix(line, "NOTE "): - blockName = webvttBlockNameComment - comments = append(comments, strings.TrimPrefix(line, "NOTE ")) - // Empty line - case len(line) == 0: - // Reset block name - blockName = "" - // Region - case strings.HasPrefix(line, "Region: "): - // Add region styles - var r = &Region{InlineStyle: &StyleAttributes{}} - for _, part := range strings.Split(strings.TrimPrefix(line, "Region: "), " ") { - // Split on "=" - var split = strings.Split(part, "=") - if len(split) <= 1 { - err = fmt.Errorf("astisub: line %d: Invalid region style %s", lineNum, part) - return - } - - // Switch on key - switch split[0] { - case "id": - r.ID = split[1] - case "lines": - if r.InlineStyle.WebVTTLines, err = strconv.Atoi(split[1]); err != nil { - err = fmt.Errorf("atoi of %s failed: %w", split[1], err) - return - } - case "regionanchor": - r.InlineStyle.WebVTTRegionAnchor = split[1] - case "scroll": - r.InlineStyle.WebVTTScroll = split[1] - case "viewportanchor": - r.InlineStyle.WebVTTViewportAnchor = split[1] - case "width": - r.InlineStyle.WebVTTWidth = split[1] - } - } - r.InlineStyle.propagateWebVTTAttributes() - - // Add region - o.Regions[r.ID] = r - // Style - case strings.HasPrefix(line, "STYLE"): - blockName = webvttBlockNameStyle - // Time boundaries - case strings.Contains(line, webvttTimeBoundariesSeparator): - // Set block name - blockName = webvttBlockNameText - - // Init new item - item = &Item{ - Comments: comments, - Index: index, - InlineStyle: &StyleAttributes{}, - } - - // Reset index - index = 0 - - // Split line on time boundaries - var left = strings.Split(line, webvttTimeBoundariesSeparator) - - // Split line on space to get remaining of time data - var right = strings.Split(left[1], " ") - - // Parse time boundaries - if item.StartAt, err = parseDurationWebVTT(left[0]); err != nil { - err = fmt.Errorf("astisub: line %d: parsing webvtt duration %s failed: %w", lineNum, left[0], err) - return - } - if item.EndAt, err = parseDurationWebVTT(right[0]); err != nil { - err = fmt.Errorf("astisub: line %d: parsing webvtt duration %s failed: %w", lineNum, right[0], err) - return - } - - // Parse style - if len(right) > 1 { - // Add styles - for index := 1; index < len(right); index++ { - // Empty - if right[index] == "" { - continue - } - - // Split line on ":" - var split = strings.Split(right[index], ":") - if len(split) <= 1 { - err = fmt.Errorf("astisub: line %d: Invalid inline style '%s'", lineNum, right[index]) - return - } - - // Switch on key - switch split[0] { - case "align": - item.InlineStyle.WebVTTAlign = split[1] - case "line": - item.InlineStyle.WebVTTLine = split[1] - case "position": - item.InlineStyle.WebVTTPosition = split[1] - case "region": - if _, ok := o.Regions[split[1]]; !ok { - err = fmt.Errorf("astisub: line %d: Unknown region %s", lineNum, split[1]) - return - } - item.Region = o.Regions[split[1]] - case "size": - item.InlineStyle.WebVTTSize = split[1] - case "vertical": - item.InlineStyle.WebVTTVertical = split[1] - } - } - } - item.InlineStyle.propagateWebVTTAttributes() - - // Reset comments - comments = []string{} - - // Append item - o.Items = append(o.Items, item) - - case strings.HasPrefix(line, webvttTimestampMap): - if len(item.Lines) > 0 { - err = errors.New("astisub: found timestamp map after processing subtitle items") - return - } - - timeOffset, err = parseTimestampMapWebVTT(line) - if err != nil { - err = fmt.Errorf("astisub: parsing webvtt timestamp map failed: %w", err) - return - } - - // Text - default: - // Switch on block name - switch blockName { - case webvttBlockNameComment: - comments = append(comments, line) - case webvttBlockNameStyle: - // TODO Do something with the style - case webvttBlockNameText: - // Parse line - if l := parseTextWebVTT(line); len(l.Items) > 0 { - item.Lines = append(item.Lines, l) - } - default: - // This is the ID - index, _ = strconv.Atoi(line) - } - } - } - - if timeOffset > 0 { - o.Add(timeOffset) - } - return -} - -// parseTextWebVTT parses the input line to fill the Line -func parseTextWebVTT(i string) (o Line) { - // Create tokenizer - tr := html.NewTokenizer(strings.NewReader(i)) - - // Loop - italic := false - for { - // Get next tag - t := tr.Next() - - // Process error - if err := tr.Err(); err != nil { - break - } - - switch t { - case html.EndTagToken: - // Parse italic - if bytes.Equal(tr.Raw(), bytesWebVTTItalicEndTag) { - italic = false - continue - } - case html.StartTagToken: - // Parse voice name - if matches := webVTTRegexpStartTag.FindStringSubmatch(string(tr.Raw())); len(matches) > 3 { - if s := strings.TrimSpace(matches[3]); s != "" { - o.VoiceName = s - } - continue - } - - // Parse italic - if bytes.Equal(tr.Raw(), bytesWebVTTItalicStartTag) { - italic = true - continue - } - case html.TextToken: - if s := strings.TrimSpace(string(tr.Raw())); s != "" { - // Get style attribute - var sa *StyleAttributes - if italic { - sa = &StyleAttributes{ - WebVTTItalics: italic, - } - sa.propagateWebVTTAttributes() - } - - // Append item - o.Items = append(o.Items, LineItem{ - InlineStyle: sa, - Text: s, - }) - } - } - } - return -} - -// formatDurationWebVTT formats a .vtt duration -func formatDurationWebVTT(i time.Duration) string { - return formatDuration(i, ".", 3) -} - -// WriteToWebVTT writes subtitles in .vtt format -func (s Subtitles) WriteToWebVTT(o io.Writer) (err error) { - // Do not write anything if no subtitles - if len(s.Items) == 0 { - err = ErrNoSubtitlesToWrite - return - } - - // Add header - var c []byte - c = append(c, []byte("WEBVTT\n\n")...) - - // Add regions - var k []string - for _, region := range s.Regions { - k = append(k, region.ID) - } - sort.Strings(k) - for _, id := range k { - c = append(c, []byte("Region: id="+s.Regions[id].ID)...) - if s.Regions[id].InlineStyle.WebVTTLines != 0 { - c = append(c, bytesSpace...) - c = append(c, []byte("lines="+strconv.Itoa(s.Regions[id].InlineStyle.WebVTTLines))...) - } else if s.Regions[id].Style != nil && s.Regions[id].Style.InlineStyle != nil && s.Regions[id].Style.InlineStyle.WebVTTLines != 0 { - c = append(c, bytesSpace...) - c = append(c, []byte("lines="+strconv.Itoa(s.Regions[id].Style.InlineStyle.WebVTTLines))...) - } - if s.Regions[id].InlineStyle.WebVTTRegionAnchor != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("regionanchor="+s.Regions[id].InlineStyle.WebVTTRegionAnchor)...) - } else if s.Regions[id].Style != nil && s.Regions[id].Style.InlineStyle != nil && s.Regions[id].Style.InlineStyle.WebVTTRegionAnchor != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("regionanchor="+s.Regions[id].Style.InlineStyle.WebVTTRegionAnchor)...) - } - if s.Regions[id].InlineStyle.WebVTTScroll != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("scroll="+s.Regions[id].InlineStyle.WebVTTScroll)...) - } else if s.Regions[id].Style != nil && s.Regions[id].Style.InlineStyle != nil && s.Regions[id].Style.InlineStyle.WebVTTScroll != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("scroll="+s.Regions[id].Style.InlineStyle.WebVTTScroll)...) - } - if s.Regions[id].InlineStyle.WebVTTViewportAnchor != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("viewportanchor="+s.Regions[id].InlineStyle.WebVTTViewportAnchor)...) - } else if s.Regions[id].Style != nil && s.Regions[id].Style.InlineStyle != nil && s.Regions[id].Style.InlineStyle.WebVTTViewportAnchor != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("viewportanchor="+s.Regions[id].Style.InlineStyle.WebVTTViewportAnchor)...) - } - if s.Regions[id].InlineStyle.WebVTTWidth != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("width="+s.Regions[id].InlineStyle.WebVTTWidth)...) - } else if s.Regions[id].Style != nil && s.Regions[id].Style.InlineStyle != nil && s.Regions[id].Style.InlineStyle.WebVTTWidth != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("width="+s.Regions[id].Style.InlineStyle.WebVTTWidth)...) - } - c = append(c, bytesLineSeparator...) - } - if len(s.Regions) > 0 { - c = append(c, bytesLineSeparator...) - } - - // Loop through subtitles - for index, item := range s.Items { - // Add comments - if len(item.Comments) > 0 { - c = append(c, []byte("NOTE ")...) - for _, comment := range item.Comments { - c = append(c, []byte(comment)...) - c = append(c, bytesLineSeparator...) - } - c = append(c, bytesLineSeparator...) - } - - // Add time boundaries - c = append(c, []byte(strconv.Itoa(index+1))...) - c = append(c, bytesLineSeparator...) - c = append(c, []byte(formatDurationWebVTT(item.StartAt))...) - c = append(c, bytesWebVTTTimeBoundariesSeparator...) - c = append(c, []byte(formatDurationWebVTT(item.EndAt))...) - - // Add styles - if item.InlineStyle != nil { - if item.InlineStyle.WebVTTAlign != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("align:"+item.InlineStyle.WebVTTAlign)...) - } else if item.Style != nil && item.Style.InlineStyle != nil && item.Style.InlineStyle.WebVTTAlign != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("align:"+item.Style.InlineStyle.WebVTTAlign)...) - } - if item.InlineStyle.WebVTTLine != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("line:"+item.InlineStyle.WebVTTLine)...) - } else if item.Style != nil && item.Style.InlineStyle != nil && item.Style.InlineStyle.WebVTTLine != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("line:"+item.Style.InlineStyle.WebVTTLine)...) - } - if item.InlineStyle.WebVTTPosition != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("position:"+item.InlineStyle.WebVTTPosition)...) - } else if item.Style != nil && item.Style.InlineStyle != nil && item.Style.InlineStyle.WebVTTPosition != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("position:"+item.Style.InlineStyle.WebVTTPosition)...) - } - if item.Region != nil { - c = append(c, bytesSpace...) - c = append(c, []byte("region:"+item.Region.ID)...) - } - if item.InlineStyle.WebVTTSize != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("size:"+item.InlineStyle.WebVTTSize)...) - } else if item.Style != nil && item.Style.InlineStyle != nil && item.Style.InlineStyle.WebVTTSize != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("size:"+item.Style.InlineStyle.WebVTTSize)...) - } - if item.InlineStyle.WebVTTVertical != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("vertical:"+item.InlineStyle.WebVTTVertical)...) - } else if item.Style != nil && item.Style.InlineStyle != nil && item.Style.InlineStyle.WebVTTVertical != "" { - c = append(c, bytesSpace...) - c = append(c, []byte("vertical:"+item.Style.InlineStyle.WebVTTVertical)...) - } - } - - // Add new line - c = append(c, bytesLineSeparator...) - - // Loop through lines - for _, l := range item.Lines { - c = append(c, l.webVTTBytes()...) - } - - // Add new line - c = append(c, bytesLineSeparator...) - } - - // Remove last new line - c = c[:len(c)-1] - - // Write - if _, err = o.Write(c); err != nil { - err = fmt.Errorf("astisub: writing failed: %w", err) - return - } - return -} - -func (l Line) webVTTBytes() (c []byte) { - if l.VoiceName != "" { - c = append(c, []byte("")...) - } - for idx, li := range l.Items { - c = append(c, li.webVTTBytes()...) - // condition to avoid adding space as the last character. - if idx < len(l.Items)-1 { - c = append(c, []byte(" ")...) - } - } - c = append(c, bytesLineSeparator...) - return -} - -func (li LineItem) webVTTBytes() (c []byte) { - // Get color - var color string - if li.InlineStyle != nil && li.InlineStyle.TTMLColor != nil { - color = cssColor(*li.InlineStyle.TTMLColor) - } - - // Get italics - i := li.InlineStyle != nil && li.InlineStyle.WebVTTItalics - - // Append - if color != "" { - c = append(c, []byte("")...) - } - if i { - c = append(c, []byte("")...) - } - c = append(c, []byte(li.Text)...) - if i { - c = append(c, []byte("")...) - } - if color != "" { - c = append(c, []byte("")...) - } - return -} - -func cssColor(rgb string) string { - colors := map[string]string{ - "#00ffff": "cyan", // narrator, thought - "#ffff00": "yellow", // out of vision - "#ff0000": "red", // noises - "#ff00ff": "magenta", // song - "#00ff00": "lime", // foreign speak - } - return colors[strings.ToLower(rgb)] // returning the empty string is ok -} diff --git a/vendor/github.com/asticode/go-astits/.gitignore b/vendor/github.com/asticode/go-astits/.gitignore deleted file mode 100644 index 5be2b41d1f5..00000000000 --- a/vendor/github.com/asticode/go-astits/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -Thumbs.db -.idea/ -cover* -test diff --git a/vendor/github.com/asticode/go-astits/.travis.yml b/vendor/github.com/asticode/go-astits/.travis.yml deleted file mode 100644 index 93968bfd57c..00000000000 --- a/vendor/github.com/asticode/go-astits/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -go: - - 1.x - - tip -install: - - go get -t ./... - - go get golang.org/x/tools/cmd/cover - - go get github.com/mattn/goveralls -matrix: - allow_failures: - - go: tip -script: - - go test -race -v -coverprofile=coverage.out - - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci \ No newline at end of file diff --git a/vendor/github.com/asticode/go-astits/LICENSE b/vendor/github.com/asticode/go-astits/LICENSE deleted file mode 100644 index d9954a4c7bb..00000000000 --- a/vendor/github.com/asticode/go-astits/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Quentin Renard - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/asticode/go-astits/README.md b/vendor/github.com/asticode/go-astits/README.md deleted file mode 100644 index e5756c6cdfd..00000000000 --- a/vendor/github.com/asticode/go-astits/README.md +++ /dev/null @@ -1,193 +0,0 @@ -[![GoReportCard](http://goreportcard.com/badge/github.com/asticode/go-astits)](http://goreportcard.com/report/github.com/asticode/go-astits) -[![GoDoc](https://godoc.org/github.com/asticode/go-astits?status.svg)](https://godoc.org/github.com/asticode/go-astits) -[![Travis](https://travis-ci.org/asticode/go-astits.svg?branch=master)](https://travis-ci.org/asticode/go-astits#) -[![Coveralls](https://coveralls.io/repos/github/asticode/go-astits/badge.svg?branch=master)](https://coveralls.io/github/asticode/go-astits) - -This is a Golang library to natively demux and mux MPEG Transport Streams (ts) in GO. - -WARNING: this library is not yet production ready. Use at your own risks! - -# Installation - -To install the library use the following: - - go get -u github.com/asticode/go-astits/... - -# Before looking at the code... - -The transport stream is made of packets.
-Each packet has a header, an optional adaptation field and a payload.
-Several payloads can be appended and parsed as a data. - -``` - TRANSPORT STREAM - +--------------------------------------------------------------------------------------------------+ - | | - - PACKET PACKET - +----------------------------------------------+----------------------------------------------+---- - | | | - - +--------+---------------------------+---------+--------+---------------------------+---------+ - | HEADER | OPTIONAL ADAPTATION FIELD | PAYLOAD | HEADER | OPTIONAL ADAPTATION FIELD | PAYLOAD | ... - +--------+---------------------------+---------+--------+---------------------------+---------+ - - | | | | - +---------+ +---------+ - | | - +----------------------------------------------+ - DATA -``` - -# Using the library in your code - -WARNING: the code below doesn't handle errors for readability purposes. However you SHOULD! - -## Demux - -```go -// Create a cancellable context in case you want to stop reading packets/data any time you want -ctx, cancel := context.WithCancel(context.Background()) - -// Handle SIGTERM signal -ch := make(chan os.Signal, 1) -signal.Notify(ch, syscall.SIGTERM) -go func() { - <-ch - cancel() -}() - -// Open your file or initialize any kind of io.Reader -// Buffering using bufio.Reader is recommended for performance -f, _ := os.Open("/path/to/file.ts") -defer f.Close() - -// Create the demuxer -dmx := astits.NewDemuxer(ctx, f) -for { - // Get the next data - d, _ := dmx.NextData() - - // Data is a PMT data - if d.PMT != nil { - // Loop through elementary streams - for _, es := range d.PMT.ElementaryStreams { - fmt.Printf("Stream detected: %d\n", es.ElementaryPID) - } - return - } -} -``` - -## Mux - -```go -// Create a cancellable context in case you want to stop writing packets/data any time you want -ctx, cancel := context.WithCancel(context.Background()) - -// Handle SIGTERM signal -ch := make(chan os.Signal, 1) -signal.Notify(ch, syscall.SIGTERM) -go func() { - <-ch - cancel() -}() - -// Create your file or initialize any kind of io.Writer -// Buffering using bufio.Writer is recommended for performance -f, _ := os.Create("/path/to/file.ts") -defer f.Close() - -// Create the muxer -mx := astits.NewMuxer(ctx, f) - -// Add an elementary stream -mx.AddElementaryStream(astits.PMTElementaryStream{ - ElementaryPID: 1, - StreamType: astits.StreamTypeMetadata, -}) - -// Write tables -// Using that function is not mandatory, WriteData will retransmit tables from time to time -mx.WriteTables() - -// Write data -mx.WriteData(&astits.MuxerData{ - PES: &astits.PESData{ - Data: []byte("test"), - }, - PID: 1, -}) -``` - -## Options - -In order to pass options to the demuxer or the muxer, look for the methods prefixed with `DemuxerOpt` or `MuxerOpt` and add them upon calling `NewDemuxer` or `NewMuxer` : - -```go -// This is your custom packets parser -p := func(ps []*astits.Packet) (ds []*astits.Data, skip bool, err error) { - // This is your logic - skip = true - return -} - -// Now you can create a demuxer with the proper options -dmx := NewDemuxer(ctx, f, DemuxerOptPacketSize(192), DemuxerOptPacketsParser(p)) -``` - -# CLI - -This library provides 2 CLIs that will automatically get installed in `GOPATH/bin` on `go get` execution. - -## astits-probe - -### List streams - - $ astits-probe -i -f - -### List packets - - $ astits-probe packets -i - -### List data - - $ astits-probe data -i -d - -## astits-es-split - -### Split streams into separate .ts files - - $ astits-es-split -o - -# Features and roadmap - -- [x] Add demuxer -- [x] Add muxer -- [x] Demux PES packets -- [x] Mux PES packets -- [x] Demux PAT packets -- [x] Mux PAT packets -- [x] Demux PMT packets -- [x] Mux PMT packets -- [x] Demux EIT packets -- [ ] Mux EIT packets -- [x] Demux NIT packets -- [ ] Mux NIT packets -- [x] Demux SDT packets -- [ ] Mux SDT packets -- [x] Demux TOT packets -- [ ] Mux TOT packets -- [ ] Demux BAT packets -- [ ] Mux BAT packets -- [ ] Demux DIT packets -- [ ] Mux DIT packets -- [ ] Demux RST packets -- [ ] Mux RST packets -- [ ] Demux SIT packets -- [ ] Mux SIT packets -- [ ] Mux ST packets -- [ ] Demux TDT packets -- [ ] Mux TDT packets -- [ ] Demux TSDT packets -- [ ] Mux TSDT packets diff --git a/vendor/github.com/asticode/go-astits/clock_reference.go b/vendor/github.com/asticode/go-astits/clock_reference.go deleted file mode 100644 index 73c147c6f93..00000000000 --- a/vendor/github.com/asticode/go-astits/clock_reference.go +++ /dev/null @@ -1,29 +0,0 @@ -package astits - -import ( - "time" -) - -// ClockReference represents a clock reference -// Base is based on a 90 kHz clock and extension is based on a 27 MHz clock -type ClockReference struct { - Base, Extension int64 -} - -// newClockReference builds a new clock reference -func newClockReference(base, extension int64) *ClockReference { - return &ClockReference{ - Base: base, - Extension: extension, - } -} - -// Duration converts the clock reference into duration -func (p ClockReference) Duration() time.Duration { - return time.Duration(p.Base*1e9/90000) + time.Duration(p.Extension*1e9/27000000) -} - -// Time converts the clock reference into time -func (p ClockReference) Time() time.Time { - return time.Unix(0, p.Duration().Nanoseconds()) -} diff --git a/vendor/github.com/asticode/go-astits/crc32.go b/vendor/github.com/asticode/go-astits/crc32.go deleted file mode 100644 index 5a3f601bcc6..00000000000 --- a/vendor/github.com/asticode/go-astits/crc32.go +++ /dev/null @@ -1,25 +0,0 @@ -package astits - -const ( - crc32Polynomial = uint32(0xffffffff) -) - -// computeCRC32 computes a CRC32 -// https://stackoverflow.com/questions/35034042/how-to-calculate-crc32-in-psi-si-packet -func computeCRC32(bs []byte) uint32 { - return updateCRC32(crc32Polynomial, bs) -} - -func updateCRC32(crc32 uint32, bs []byte) uint32 { - for _, b := range bs { - for i := 0; i < 8; i++ { - if (crc32 >= uint32(0x80000000)) != (b >= uint8(0x80)) { - crc32 = (crc32 << 1) ^ 0x04C11DB7 - } else { - crc32 = crc32 << 1 - } - b <<= 1 - } - } - return crc32 -} diff --git a/vendor/github.com/asticode/go-astits/data.go b/vendor/github.com/asticode/go-astits/data.go deleted file mode 100644 index f06bdab31d2..00000000000 --- a/vendor/github.com/asticode/go-astits/data.go +++ /dev/null @@ -1,117 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -// PIDs -const ( - PIDPAT uint16 = 0x0 // Program Association Table (PAT) contains a directory listing of all Program Map Tables. - PIDCAT uint16 = 0x1 // Conditional Access Table (CAT) contains a directory listing of all ITU-T Rec. H.222 entitlement management message streams used by Program Map Tables. - PIDTSDT uint16 = 0x2 // Transport Stream Description Table (TSDT) contains descriptors related to the overall transport stream - PIDNull uint16 = 0x1fff // Null Packet (used for fixed bandwidth padding) -) - -// DemuxerData represents a data parsed by Demuxer -type DemuxerData struct { - EIT *EITData - FirstPacket *Packet - NIT *NITData - PAT *PATData - PES *PESData - PID uint16 - PMT *PMTData - SDT *SDTData - TOT *TOTData -} - -// MuxerData represents a data to be written by Muxer -type MuxerData struct { - PID uint16 - AdaptationField *PacketAdaptationField - PES *PESData -} - -// parseData parses a payload spanning over multiple packets and returns a set of data -func parseData(ps []*Packet, prs PacketsParser, pm programMap) (ds []*DemuxerData, err error) { - // Use custom parser first - if prs != nil { - var skip bool - if ds, skip, err = prs(ps); err != nil { - err = fmt.Errorf("astits: custom packets parsing failed: %w", err) - return - } else if skip { - return - } - } - - // Get payload length - var l int - for _, p := range ps { - l += len(p.Payload) - } - - // Append payload - var payload = make([]byte, l) - var c int - for _, p := range ps { - c += copy(payload[c:], p.Payload) - } - - // Create reader - i := astikit.NewBytesIterator(payload) - - // Parse PID - pid := ps[0].Header.PID - - // Parse payload - if pid == PIDCAT { - // Information in a CAT payload is private and dependent on the CA system. Use the PacketsParser - // to parse this type of payload - } else if isPSIPayload(pid, pm) { - // Parse PSI data - var psiData *PSIData - if psiData, err = parsePSIData(i); err != nil { - err = fmt.Errorf("astits: parsing PSI data failed: %w", err) - return - } - - // Append data - ds = psiData.toData(ps[0], pid) - } else if isPESPayload(payload) { - // Parse PES data - var pesData *PESData - if pesData, err = parsePESData(i); err != nil { - err = fmt.Errorf("astits: parsing PES data failed: %w", err) - return - } - - // Append data - ds = append(ds, &DemuxerData{ - FirstPacket: ps[0], - PES: pesData, - PID: pid, - }) - } - return -} - -// isPSIPayload checks whether the payload is a PSI one -func isPSIPayload(pid uint16, pm programMap) bool { - return pid == PIDPAT || // PAT - pm.exists(pid) || // PMT - ((pid >= 0x10 && pid <= 0x14) || (pid >= 0x1e && pid <= 0x1f)) //DVB -} - -// isPESPayload checks whether the payload is a PES one -func isPESPayload(i []byte) bool { - // Packet is not big enough - if len(i) < 3 { - return false - } - - // Check prefix - return uint32(i[0])<<16|uint32(i[1])<<8|uint32(i[2]) == 1 -} diff --git a/vendor/github.com/asticode/go-astits/data_eit.go b/vendor/github.com/asticode/go-astits/data_eit.go deleted file mode 100644 index 4dce53a2a1f..00000000000 --- a/vendor/github.com/asticode/go-astits/data_eit.go +++ /dev/null @@ -1,124 +0,0 @@ -package astits - -import ( - "fmt" - "time" - - "github.com/asticode/go-astikit" -) - -// EITData represents an EIT data -// Page: 36 | Chapter: 5.2.4 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf -// (barbashov) the link above can be broken, alternative: https://dvb.org/wp-content/uploads/2019/12/a038_tm1217r37_en300468v1_17_1_-_rev-134_-_si_specification.pdf -type EITData struct { - Events []*EITDataEvent - LastTableID uint8 - OriginalNetworkID uint16 - SegmentLastSectionNumber uint8 - ServiceID uint16 - TransportStreamID uint16 -} - -// EITDataEvent represents an EIT data event -type EITDataEvent struct { - Descriptors []*Descriptor - Duration time.Duration - EventID uint16 - HasFreeCSAMode bool // When true indicates that access to one or more streams may be controlled by a CA system. - RunningStatus uint8 - StartTime time.Time -} - -// parseEITSection parses an EIT section -func parseEITSection(i *astikit.BytesIterator, offsetSectionsEnd int, tableIDExtension uint16) (d *EITData, err error) { - // Create data - d = &EITData{ServiceID: tableIDExtension} - - // Get next 2 bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Transport stream ID - d.TransportStreamID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Get next 2 bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Original network ID - d.OriginalNetworkID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Segment last section number - d.SegmentLastSectionNumber = uint8(b) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Last table ID - d.LastTableID = uint8(b) - - // Loop until end of section data is reached - for i.Offset() < offsetSectionsEnd { - // Get next 2 bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Event ID - var e = &EITDataEvent{} - e.EventID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Start time - if e.StartTime, err = parseDVBTime(i); err != nil { - err = fmt.Errorf("astits: parsing DVB time") - return - } - - // Duration - if e.Duration, err = parseDVBDurationSeconds(i); err != nil { - err = fmt.Errorf("astits: parsing DVB duration seconds failed: %w", err) - return - } - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Running status - e.RunningStatus = uint8(b) >> 5 - - // Free CA mode - e.HasFreeCSAMode = uint8(b&0x10) > 0 - - // We need to rewind since the current byte is used by the descriptor as well - i.Skip(-1) - - // Descriptors - if e.Descriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - - // Add event - d.Events = append(d.Events, e) - } - return -} diff --git a/vendor/github.com/asticode/go-astits/data_nit.go b/vendor/github.com/asticode/go-astits/data_nit.go deleted file mode 100644 index 5191b5d20ba..00000000000 --- a/vendor/github.com/asticode/go-astits/data_nit.go +++ /dev/null @@ -1,80 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -// NITData represents a NIT data -// Page: 29 | Chapter: 5.2.1 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf -// (barbashov) the link above can be broken, alternative: https://dvb.org/wp-content/uploads/2019/12/a038_tm1217r37_en300468v1_17_1_-_rev-134_-_si_specification.pdf -type NITData struct { - NetworkDescriptors []*Descriptor - NetworkID uint16 - TransportStreams []*NITDataTransportStream -} - -// NITDataTransportStream represents a NIT data transport stream -type NITDataTransportStream struct { - OriginalNetworkID uint16 - TransportDescriptors []*Descriptor - TransportStreamID uint16 -} - -// parseNITSection parses a NIT section -func parseNITSection(i *astikit.BytesIterator, tableIDExtension uint16) (d *NITData, err error) { - // Create data - d = &NITData{NetworkID: tableIDExtension} - - // Network descriptors - if d.NetworkDescriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Transport stream loop length - transportStreamLoopLength := int(uint16(bs[0]&0xf)<<8 | uint16(bs[1])) - - // Transport stream loop - offsetEnd := i.Offset() + transportStreamLoopLength - for i.Offset() < offsetEnd { - // Create transport stream - ts := &NITDataTransportStream{} - - // Get next bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Transport stream ID - ts.TransportStreamID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Get next bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Original network ID - ts.OriginalNetworkID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Transport descriptors - if ts.TransportDescriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - - // Append transport stream - d.TransportStreams = append(d.TransportStreams, ts) - } - return -} diff --git a/vendor/github.com/asticode/go-astits/data_pat.go b/vendor/github.com/asticode/go-astits/data_pat.go deleted file mode 100644 index 3b5b5551114..00000000000 --- a/vendor/github.com/asticode/go-astits/data_pat.go +++ /dev/null @@ -1,63 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -const ( - patSectionEntryBytesSize = 4 // 16 bits + 3 reserved + 13 bits = 32 bits -) - -// PATData represents a PAT data -// https://en.wikipedia.org/wiki/Program-specific_information -type PATData struct { - Programs []*PATProgram - TransportStreamID uint16 -} - -// PATProgram represents a PAT program -type PATProgram struct { - ProgramMapID uint16 // The packet identifier that contains the associated PMT - ProgramNumber uint16 // Relates to the Table ID extension in the associated PMT. A value of 0 is reserved for a NIT packet identifier. -} - -// parsePATSection parses a PAT section -func parsePATSection(i *astikit.BytesIterator, offsetSectionsEnd int, tableIDExtension uint16) (d *PATData, err error) { - // Create data - d = &PATData{TransportStreamID: tableIDExtension} - - // Loop until end of section data is reached - for i.Offset() < offsetSectionsEnd { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(4); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Append program - d.Programs = append(d.Programs, &PATProgram{ - ProgramMapID: uint16(bs[2]&0x1f)<<8 | uint16(bs[3]), - ProgramNumber: uint16(bs[0])<<8 | uint16(bs[1]), - }) - } - return -} - -func calcPATSectionLength(d *PATData) uint16 { - return uint16(4 * len(d.Programs)) -} - -func writePATSection(w *astikit.BitsWriter, d *PATData) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - for _, p := range d.Programs { - b.Write(p.ProgramNumber) - b.WriteN(uint8(0xff), 3) - b.WriteN(p.ProgramMapID, 13) - } - - return len(d.Programs) * patSectionEntryBytesSize, b.Err() -} diff --git a/vendor/github.com/asticode/go-astits/data_pes.go b/vendor/github.com/asticode/go-astits/data_pes.go deleted file mode 100644 index 9b3493f4b3e..00000000000 --- a/vendor/github.com/asticode/go-astits/data_pes.go +++ /dev/null @@ -1,747 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -// P-STD buffer scales -const ( - PSTDBufferScale128Bytes = 0 - PSTDBufferScale1024Bytes = 1 -) - -// PTS DTS indicator -const ( - PTSDTSIndicatorBothPresent = 3 - PTSDTSIndicatorIsForbidden = 1 - PTSDTSIndicatorNoPTSOrDTS = 0 - PTSDTSIndicatorOnlyPTS = 2 -) - -// Stream IDs -const ( - StreamIDPrivateStream1 = 189 - StreamIDPaddingStream = 190 - StreamIDPrivateStream2 = 191 -) - -// Trick mode controls -const ( - TrickModeControlFastForward = 0 - TrickModeControlFastReverse = 3 - TrickModeControlFreezeFrame = 2 - TrickModeControlSlowMotion = 1 - TrickModeControlSlowReverse = 4 -) - -const ( - pesHeaderLength = 6 - ptsOrDTSByteLength = 5 - escrLength = 6 - dsmTrickModeLength = 1 -) - -// PESData represents a PES data -// https://en.wikipedia.org/wiki/Packetized_elementary_stream -// http://dvd.sourceforge.net/dvdinfo/pes-hdr.html -// http://happy.emu.id.au/lab/tut/dttb/dtbtut4b.htm -type PESData struct { - Data []byte - Header *PESHeader -} - -// PESHeader represents a packet PES header -type PESHeader struct { - OptionalHeader *PESOptionalHeader - PacketLength uint16 // Specifies the number of bytes remaining in the packet after this field. Can be zero. If the PES packet length is set to zero, the PES packet can be of any length. A value of zero for the PES packet length can be used only when the PES packet payload is a video elementary stream. - StreamID uint8 // Examples: Audio streams (0xC0-0xDF), Video streams (0xE0-0xEF) -} - -// PESOptionalHeader represents a PES optional header -type PESOptionalHeader struct { - AdditionalCopyInfo uint8 - CRC uint16 - DataAlignmentIndicator bool // True indicates that the PES packet header is immediately followed by the video start code or audio syncword - DSMTrickMode *DSMTrickMode - DTS *ClockReference - ESCR *ClockReference - ESRate uint32 - Extension2Data []byte - Extension2Length uint8 - HasAdditionalCopyInfo bool - HasCRC bool - HasDSMTrickMode bool - HasESCR bool - HasESRate bool - HasExtension bool - HasExtension2 bool - HasOptionalFields bool - HasPackHeaderField bool - HasPrivateData bool - HasProgramPacketSequenceCounter bool - HasPSTDBuffer bool - HeaderLength uint8 - IsCopyrighted bool - IsOriginal bool - MarkerBits uint8 - MPEG1OrMPEG2ID uint8 - OriginalStuffingLength uint8 - PacketSequenceCounter uint8 - PackField uint8 - Priority bool - PrivateData []byte - PSTDBufferScale uint8 - PSTDBufferSize uint16 - PTS *ClockReference - PTSDTSIndicator uint8 - ScramblingControl uint8 -} - -// DSMTrickMode represents a DSM trick mode -// https://books.google.fr/books?id=vwUrAwAAQBAJ&pg=PT501&lpg=PT501&dq=dsm+trick+mode+control&source=bl&ots=fI-9IHXMRL&sig=PWnhxrsoMWNQcl1rMCPmJGNO9Ds&hl=fr&sa=X&ved=0ahUKEwjogafD8bjXAhVQ3KQKHeHKD5oQ6AEINDAB#v=onepage&q=dsm%20trick%20mode%20control&f=false -type DSMTrickMode struct { - FieldID uint8 - FrequencyTruncation uint8 - IntraSliceRefresh uint8 - RepeatControl uint8 - TrickModeControl uint8 -} - -func (h *PESHeader) IsVideoStream() bool { - return h.StreamID == 0xe0 || - h.StreamID == 0xfd -} - -// parsePESData parses a PES data -func parsePESData(i *astikit.BytesIterator) (d *PESData, err error) { - // Create data - d = &PESData{} - - // Skip first 3 bytes that are there to identify the PES payload - i.Seek(3) - - // Parse header - var dataStart, dataEnd int - if d.Header, dataStart, dataEnd, err = parsePESHeader(i); err != nil { - err = fmt.Errorf("astits: parsing PES header failed: %w", err) - return - } - - // Seek to data - i.Seek(dataStart) - - // Extract data - if d.Data, err = i.NextBytes(dataEnd - dataStart); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -// hasPESOptionalHeader checks whether the data has a PES optional header -func hasPESOptionalHeader(streamID uint8) bool { - return streamID != StreamIDPaddingStream && streamID != StreamIDPrivateStream2 -} - -// parsePESData parses a PES header -func parsePESHeader(i *astikit.BytesIterator) (h *PESHeader, dataStart, dataEnd int, err error) { - // Create header - h = &PESHeader{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Stream ID - h.StreamID = uint8(b) - - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Length - h.PacketLength = uint16(bs[0])<<8 | uint16(bs[1]) - - // Update data end - if h.PacketLength > 0 { - dataEnd = i.Offset() + int(h.PacketLength) - } else { - dataEnd = i.Len() - } - - // Optional header - if hasPESOptionalHeader(h.StreamID) { - if h.OptionalHeader, dataStart, err = parsePESOptionalHeader(i); err != nil { - err = fmt.Errorf("astits: parsing PES optional header failed: %w", err) - return - } - } else { - dataStart = i.Offset() - } - return -} - -// parsePESOptionalHeader parses a PES optional header -func parsePESOptionalHeader(i *astikit.BytesIterator) (h *PESOptionalHeader, dataStart int, err error) { - // Create header - h = &PESOptionalHeader{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Marker bits - h.MarkerBits = uint8(b) >> 6 - - // Scrambling control - h.ScramblingControl = uint8(b) >> 4 & 0x3 - - // Priority - h.Priority = uint8(b)&0x8 > 0 - - // Data alignment indicator - h.DataAlignmentIndicator = uint8(b)&0x4 > 0 - - // Copyrighted - h.IsCopyrighted = uint(b)&0x2 > 0 - - // Original or copy - h.IsOriginal = uint8(b)&0x1 > 0 - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // PTS DST indicator - h.PTSDTSIndicator = uint8(b) >> 6 & 0x3 - - // Flags - h.HasESCR = uint8(b)&0x20 > 0 - h.HasESRate = uint8(b)&0x10 > 0 - h.HasDSMTrickMode = uint8(b)&0x8 > 0 - h.HasAdditionalCopyInfo = uint8(b)&0x4 > 0 - h.HasCRC = uint8(b)&0x2 > 0 - h.HasExtension = uint8(b)&0x1 > 0 - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Header length - h.HeaderLength = uint8(b) - - // Update data start - dataStart = i.Offset() + int(h.HeaderLength) - - // PTS/DTS - if h.PTSDTSIndicator == PTSDTSIndicatorOnlyPTS { - if h.PTS, err = parsePTSOrDTS(i); err != nil { - err = fmt.Errorf("astits: parsing PTS failed: %w", err) - return - } - } else if h.PTSDTSIndicator == PTSDTSIndicatorBothPresent { - if h.PTS, err = parsePTSOrDTS(i); err != nil { - err = fmt.Errorf("astits: parsing PTS failed: %w", err) - return - } - if h.DTS, err = parsePTSOrDTS(i); err != nil { - err = fmt.Errorf("astits: parsing PTS failed: %w", err) - return - } - } - - // ESCR - if h.HasESCR { - if h.ESCR, err = parseESCR(i); err != nil { - err = fmt.Errorf("astits: parsing ESCR failed: %w", err) - return - } - } - - // ES rate - if h.HasESRate { - var bs []byte - if bs, err = i.NextBytesNoCopy(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - h.ESRate = uint32(bs[0])&0x7f<<15 | uint32(bs[1])<<7 | uint32(bs[2])>>1 - } - - // Trick mode - if h.HasDSMTrickMode { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - h.DSMTrickMode = parseDSMTrickMode(b) - } - - // Additional copy info - if h.HasAdditionalCopyInfo { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - h.AdditionalCopyInfo = b & 0x7f - } - - // CRC - if h.HasCRC { - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - h.CRC = uint16(bs[0])>>8 | uint16(bs[1]) - } - - // Extension - if h.HasExtension { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Flags - h.HasPrivateData = b&0x80 > 0 - h.HasPackHeaderField = b&0x40 > 0 - h.HasProgramPacketSequenceCounter = b&0x20 > 0 - h.HasPSTDBuffer = b&0x10 > 0 - h.HasExtension2 = b&0x1 > 0 - - // Private data - if h.HasPrivateData { - if h.PrivateData, err = i.NextBytes(16); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - - // Pack field length - if h.HasPackHeaderField { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - // TODO it's only a length of pack_header, should read it all. now it's wrong - h.PackField = uint8(b) - } - - // Program packet sequence counter - if h.HasProgramPacketSequenceCounter { - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - h.PacketSequenceCounter = uint8(bs[0]) & 0x7f - h.MPEG1OrMPEG2ID = uint8(bs[1]) >> 6 & 0x1 - h.OriginalStuffingLength = uint8(bs[1]) & 0x3f - } - - // P-STD buffer - if h.HasPSTDBuffer { - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - h.PSTDBufferScale = bs[0] >> 5 & 0x1 - h.PSTDBufferSize = uint16(bs[0])&0x1f<<8 | uint16(bs[1]) - } - - // Extension 2 - if h.HasExtension2 { - // Length - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - h.Extension2Length = uint8(b) & 0x7f - - // Data - if h.Extension2Data, err = i.NextBytes(int(h.Extension2Length)); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - } - return -} - -// parseDSMTrickMode parses a DSM trick mode -func parseDSMTrickMode(i byte) (m *DSMTrickMode) { - m = &DSMTrickMode{} - m.TrickModeControl = i >> 5 - if m.TrickModeControl == TrickModeControlFastForward || m.TrickModeControl == TrickModeControlFastReverse { - m.FieldID = i >> 3 & 0x3 - m.IntraSliceRefresh = i >> 2 & 0x1 - m.FrequencyTruncation = i & 0x3 - } else if m.TrickModeControl == TrickModeControlFreezeFrame { - m.FieldID = i >> 3 & 0x3 - } else if m.TrickModeControl == TrickModeControlSlowMotion || m.TrickModeControl == TrickModeControlSlowReverse { - m.RepeatControl = i & 0x1f - } - return -} - -// parsePTSOrDTS parses a PTS or a DTS -func parsePTSOrDTS(i *astikit.BytesIterator) (cr *ClockReference, err error) { - var bs []byte - if bs, err = i.NextBytesNoCopy(5); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - cr = newClockReference(int64(uint64(bs[0])>>1&0x7<<30|uint64(bs[1])<<22|uint64(bs[2])>>1&0x7f<<15|uint64(bs[3])<<7|uint64(bs[4])>>1&0x7f), 0) - return -} - -// parseESCR parses an ESCR -func parseESCR(i *astikit.BytesIterator) (cr *ClockReference, err error) { - var bs []byte - if bs, err = i.NextBytesNoCopy(6); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - escr := uint64(bs[0])>>3&0x7<<39 | uint64(bs[0])&0x3<<37 | uint64(bs[1])<<29 | uint64(bs[2])>>3<<24 | uint64(bs[2])&0x3<<22 | uint64(bs[3])<<14 | uint64(bs[4])>>3<<9 | uint64(bs[4])&0x3<<7 | uint64(bs[5])>>1 - cr = newClockReference(int64(escr>>9), int64(escr&0x1ff)) - return -} - -// will count how many total bytes and payload bytes will be written when writePESData is called with the same arguments -// should be used by the caller of writePESData to determine AF stuffing size needed to be applied -// since the length of video PES packets are often zero, we can't just stuff it with 0xff-s at the end -func calcPESDataLength(h *PESHeader, payloadLeft []byte, isPayloadStart bool, bytesAvailable int) (totalBytes, payloadBytes int) { - totalBytes += pesHeaderLength - if isPayloadStart { - totalBytes += int(calcPESOptionalHeaderLength(h.OptionalHeader)) - } - bytesAvailable -= totalBytes - - if len(payloadLeft) < bytesAvailable { - payloadBytes = len(payloadLeft) - } else { - payloadBytes = bytesAvailable - } - - return -} - -// first packet will contain PES header with optional PES header and payload, if possible -// all consequential packets will contain just payload -// for the last packet caller must add AF with stuffing, see calcPESDataLength -func writePESData(w *astikit.BitsWriter, h *PESHeader, payloadLeft []byte, isPayloadStart bool, bytesAvailable int) (totalBytesWritten, payloadBytesWritten int, err error) { - if isPayloadStart { - var n int - n, err = writePESHeader(w, h, len(payloadLeft)) - if err != nil { - return - } - totalBytesWritten += n - } - - payloadBytesWritten = bytesAvailable - totalBytesWritten - if payloadBytesWritten > len(payloadLeft) { - payloadBytesWritten = len(payloadLeft) - } - - err = w.Write(payloadLeft[:payloadBytesWritten]) - if err != nil { - return - } - - totalBytesWritten += payloadBytesWritten - return -} - -func writePESHeader(w *astikit.BitsWriter, h *PESHeader, payloadSize int) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(uint32(0x000001), 24) // packet_start_code_prefix - b.Write(h.StreamID) - - pesPacketLength := 0 - - if !h.IsVideoStream() { - pesPacketLength = payloadSize - if hasPESOptionalHeader(h.StreamID) { - pesPacketLength += int(calcPESOptionalHeaderLength(h.OptionalHeader)) - } - if pesPacketLength > 0xffff { - pesPacketLength = 0 - } - } - - b.Write(uint16(pesPacketLength)) - - bytesWritten := pesHeaderLength - - if hasPESOptionalHeader(h.StreamID) { - n, err := writePESOptionalHeader(w, h.OptionalHeader) - if err != nil { - return 0, err - } - bytesWritten += n - } - - return bytesWritten, b.Err() -} - -func calcPESOptionalHeaderLength(h *PESOptionalHeader) uint8 { - if h == nil { - return 0 - } - return 3 + calcPESOptionalHeaderDataLength(h) -} - -func calcPESOptionalHeaderDataLength(h *PESOptionalHeader) (length uint8) { - if h.PTSDTSIndicator == PTSDTSIndicatorOnlyPTS { - length += ptsOrDTSByteLength - } else if h.PTSDTSIndicator == PTSDTSIndicatorBothPresent { - length += 2 * ptsOrDTSByteLength - } - - if h.HasESCR { - length += escrLength - } - - if h.HasESRate { - length += 3 - } - - if h.HasDSMTrickMode { - length += dsmTrickModeLength - } - - if h.HasAdditionalCopyInfo { - length++ - } - - if h.HasCRC { - //length += 4 // TODO - } - - if h.HasExtension { - length++ - - if h.HasPrivateData { - length += 16 - } - - if h.HasPackHeaderField { - // TODO - } - - if h.HasProgramPacketSequenceCounter { - length += 2 - } - - if h.HasPSTDBuffer { - length += 2 - } - - if h.HasExtension2 { - length += 1 + uint8(len(h.Extension2Data)) - } - } - - return -} - -func writePESOptionalHeader(w *astikit.BitsWriter, h *PESOptionalHeader) (int, error) { - if h == nil { - return 0, nil - } - - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(uint8(0b10), 2) // marker bits - b.WriteN(h.ScramblingControl, 2) - b.Write(h.Priority) - b.Write(h.DataAlignmentIndicator) - b.Write(h.IsCopyrighted) - b.Write(h.IsOriginal) - - b.WriteN(h.PTSDTSIndicator, 2) - b.Write(h.HasESCR) - b.Write(h.HasESRate) - b.Write(h.HasDSMTrickMode) - b.Write(h.HasAdditionalCopyInfo) - b.Write(false) // CRC of previous PES packet. not supported yet - //b.Write(h.HasCRC) - b.Write(h.HasExtension) - - pesOptionalHeaderDataLength := calcPESOptionalHeaderDataLength(h) - b.Write(pesOptionalHeaderDataLength) - - bytesWritten := 3 - - if h.PTSDTSIndicator == PTSDTSIndicatorOnlyPTS { - n, err := writePTSOrDTS(w, 0b0010, h.PTS) - if err != nil { - return 0, err - } - bytesWritten += n - } - - if h.PTSDTSIndicator == PTSDTSIndicatorBothPresent { - n, err := writePTSOrDTS(w, 0b0011, h.PTS) - if err != nil { - return 0, err - } - bytesWritten += n - - n, err = writePTSOrDTS(w, 0b0001, h.DTS) - if err != nil { - return 0, err - } - bytesWritten += n - } - - if h.HasESCR { - n, err := writeESCR(w, h.ESCR) - if err != nil { - return 0, err - } - bytesWritten += n - } - - if h.HasESRate { - b.Write(true) - b.WriteN(h.ESRate, 22) - b.Write(true) - bytesWritten += 3 - } - - if h.HasDSMTrickMode { - n, err := writeDSMTrickMode(w, h.DSMTrickMode) - if err != nil { - return 0, err - } - bytesWritten += n - } - - if h.HasAdditionalCopyInfo { - b.Write(true) // marker_bit - b.WriteN(h.AdditionalCopyInfo, 7) - bytesWritten++ - } - - if h.HasCRC { - // TODO, not supported - } - - if h.HasExtension { - // exp 10110001 - // act 10111111 - b.Write(h.HasPrivateData) - b.Write(false) // TODO pack_header_field_flag, not implemented - //b.Write(h.HasPackHeaderField) - b.Write(h.HasProgramPacketSequenceCounter) - b.Write(h.HasPSTDBuffer) - b.WriteN(uint8(0xff), 3) // reserved - b.Write(h.HasExtension2) - bytesWritten++ - - if h.HasPrivateData { - b.WriteBytesN(h.PrivateData, 16, 0) - bytesWritten += 16 - } - - if h.HasPackHeaderField { - // TODO (see parsePESOptionalHeader) - } - - if h.HasProgramPacketSequenceCounter { - b.Write(true) // marker_bit - b.WriteN(h.PacketSequenceCounter, 7) - b.Write(true) // marker_bit - b.WriteN(h.MPEG1OrMPEG2ID, 1) - b.WriteN(h.OriginalStuffingLength, 6) - bytesWritten += 2 - } - - if h.HasPSTDBuffer { - b.WriteN(uint8(0b01), 2) - b.WriteN(h.PSTDBufferScale, 1) - b.WriteN(h.PSTDBufferSize, 13) - bytesWritten += 2 - } - - if h.HasExtension2 { - b.Write(true) // marker_bit - b.WriteN(uint8(len(h.Extension2Data)), 7) - b.Write(h.Extension2Data) - bytesWritten += 1 + len(h.Extension2Data) - } - } - - return bytesWritten, b.Err() -} - -func writeDSMTrickMode(w *astikit.BitsWriter, m *DSMTrickMode) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(m.TrickModeControl, 3) - if m.TrickModeControl == TrickModeControlFastForward || m.TrickModeControl == TrickModeControlFastReverse { - b.WriteN(m.FieldID, 2) - b.Write(m.IntraSliceRefresh == 1) // it should be boolean - b.WriteN(m.FrequencyTruncation, 2) - } else if m.TrickModeControl == TrickModeControlFreezeFrame { - b.WriteN(m.FieldID, 2) - b.WriteN(uint8(0xff), 3) // reserved - } else if m.TrickModeControl == TrickModeControlSlowMotion || m.TrickModeControl == TrickModeControlSlowReverse { - b.WriteN(m.RepeatControl, 5) - } else { - b.WriteN(uint8(0xff), 5) // reserved - } - - return dsmTrickModeLength, b.Err() -} - -func writeESCR(w *astikit.BitsWriter, cr *ClockReference) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(uint8(0xff), 2) - b.WriteN(uint64(cr.Base>>30), 3) - b.Write(true) - b.WriteN(uint64(cr.Base>>15), 15) - b.Write(true) - b.WriteN(uint64(cr.Base), 15) - b.Write(true) - b.WriteN(uint64(cr.Extension), 9) - b.Write(true) - - return escrLength, b.Err() -} - -func writePTSOrDTS(w *astikit.BitsWriter, flag uint8, cr *ClockReference) (bytesWritten int, retErr error) { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(flag, 4) - b.WriteN(uint64(cr.Base>>30), 3) - b.Write(true) - b.WriteN(uint64(cr.Base>>15), 15) - b.Write(true) - b.WriteN(uint64(cr.Base), 15) - b.Write(true) - - return ptsOrDTSByteLength, b.Err() -} diff --git a/vendor/github.com/asticode/go-astits/data_pmt.go b/vendor/github.com/asticode/go-astits/data_pmt.go deleted file mode 100644 index d1ea54fa372..00000000000 --- a/vendor/github.com/asticode/go-astits/data_pmt.go +++ /dev/null @@ -1,256 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -type StreamType uint8 - -// Stream types -const ( - StreamTypeMPEG1Video StreamType = 0x01 - StreamTypeMPEG2Video StreamType = 0x02 - StreamTypeMPEG1Audio StreamType = 0x03 // ISO/IEC 11172-3 - StreamTypeMPEG2HalvedSampleRateAudio StreamType = 0x04 // ISO/IEC 13818-3 - StreamTypeMPEG2Audio StreamType = 0x04 - StreamTypePrivateSection StreamType = 0x05 - StreamTypePrivateData StreamType = 0x06 - StreamTypeMPEG2PacketizedData StreamType = 0x06 // Rec. ITU-T H.222 | ISO/IEC 13818-1 i.e., DVB subtitles/VBI and AC-3 - StreamTypeADTS StreamType = 0x0F // ISO/IEC 13818-7 Audio with ADTS transport syntax - StreamTypeAACAudio StreamType = 0x0f - StreamTypeMPEG4Video StreamType = 0x10 - StreamTypeAACLATMAudio StreamType = 0x11 - StreamTypeMetadata StreamType = 0x15 - StreamTypeH264Video StreamType = 0x1B // Rec. ITU-T H.264 | ISO/IEC 14496-10 - StreamTypeH265Video StreamType = 0x24 // Rec. ITU-T H.265 | ISO/IEC 23008-2 - StreamTypeHEVCVideo StreamType = 0x24 - StreamTypeCAVSVideo StreamType = 0x42 - StreamTypeVC1Video StreamType = 0xea - StreamTypeDIRACVideo StreamType = 0xd1 - StreamTypeAC3Audio StreamType = 0x81 - StreamTypeDTSAudio StreamType = 0x82 - StreamTypeTRUEHDAudio StreamType = 0x83 - StreamTypeEAC3Audio StreamType = 0x87 -) - -// PMTData represents a PMT data -// https://en.wikipedia.org/wiki/Program-specific_information -type PMTData struct { - ElementaryStreams []*PMTElementaryStream - PCRPID uint16 // The packet identifier that contains the program clock reference used to improve the random access accuracy of the stream's timing that is derived from the program timestamp. If this is unused. then it is set to 0x1FFF (all bits on). - ProgramDescriptors []*Descriptor // Program descriptors - ProgramNumber uint16 -} - -// PMTElementaryStream represents a PMT elementary stream -type PMTElementaryStream struct { - ElementaryPID uint16 // The packet identifier that contains the stream type data. - ElementaryStreamDescriptors []*Descriptor // Elementary stream descriptors - StreamType StreamType // This defines the structure of the data contained within the elementary packet identifier. -} - -// parsePMTSection parses a PMT section -func parsePMTSection(i *astikit.BytesIterator, offsetSectionsEnd int, tableIDExtension uint16) (d *PMTData, err error) { - // Create data - d = &PMTData{ProgramNumber: tableIDExtension} - - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // PCR PID - d.PCRPID = uint16(bs[0]&0x1f)<<8 | uint16(bs[1]) - - // Program descriptors - if d.ProgramDescriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - - // Loop until end of section data is reached - for i.Offset() < offsetSectionsEnd { - // Create stream - e := &PMTElementaryStream{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Stream type - e.StreamType = StreamType(b) - - // Get next bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Elementary PID - e.ElementaryPID = uint16(bs[0]&0x1f)<<8 | uint16(bs[1]) - - // Elementary descriptors - if e.ElementaryStreamDescriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - - // Add elementary stream - d.ElementaryStreams = append(d.ElementaryStreams, e) - } - return -} - -func calcPMTProgramInfoLength(d *PMTData) uint16 { - ret := uint16(2) // program_info_length - ret += calcDescriptorsLength(d.ProgramDescriptors) - - for _, es := range d.ElementaryStreams { - ret += 5 // stream_type, elementary_pid, es_info_length - ret += calcDescriptorsLength(es.ElementaryStreamDescriptors) - } - - return ret -} - -func calcPMTSectionLength(d *PMTData) uint16 { - ret := uint16(4) - ret += calcDescriptorsLength(d.ProgramDescriptors) - - for _, es := range d.ElementaryStreams { - ret += 5 - ret += calcDescriptorsLength(es.ElementaryStreamDescriptors) - } - - return ret -} - -func writePMTSection(w *astikit.BitsWriter, d *PMTData) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - // TODO split into sections - - b.WriteN(uint8(0xff), 3) - b.WriteN(d.PCRPID, 13) - bytesWritten := 2 - - n, err := writeDescriptorsWithLength(w, d.ProgramDescriptors) - if err != nil { - return 0, err - } - bytesWritten += n - - for _, es := range d.ElementaryStreams { - b.Write(uint8(es.StreamType)) - b.WriteN(uint8(0xff), 3) - b.WriteN(es.ElementaryPID, 13) - bytesWritten += 3 - - n, err = writeDescriptorsWithLength(w, es.ElementaryStreamDescriptors) - if err != nil { - return 0, err - } - bytesWritten += n - } - - return bytesWritten, b.Err() -} - -func (t StreamType) IsVideo() bool { - switch t { - case StreamTypeMPEG1Video, - StreamTypeMPEG2Video, - StreamTypeMPEG4Video, - StreamTypeH264Video, - StreamTypeH265Video, - StreamTypeCAVSVideo, - StreamTypeVC1Video, - StreamTypeDIRACVideo: - return true - } - return false -} - -func (t StreamType) IsAudio() bool { - switch t { - case StreamTypeMPEG1Audio, - StreamTypeMPEG2Audio, - StreamTypeAACAudio, - StreamTypeAACLATMAudio, - StreamTypeAC3Audio, - StreamTypeDTSAudio, - StreamTypeTRUEHDAudio, - StreamTypeEAC3Audio: - return true - } - return false -} - -func (t StreamType) String() string { - switch t { - case StreamTypeMPEG1Video: - return "MPEG1 Video" - case StreamTypeMPEG2Video: - return "MPEG2 Video" - case StreamTypeMPEG1Audio: - return "MPEG1 Audio" - case StreamTypeMPEG2Audio: - return "MPEG2 Audio" - case StreamTypePrivateSection: - return "Private Section" - case StreamTypePrivateData: - return "Private Data" - case StreamTypeAACAudio: - return "AAC Audio" - case StreamTypeMPEG4Video: - return "MPEG4 Video" - case StreamTypeAACLATMAudio: - return "AAC LATM Audio" - case StreamTypeMetadata: - return "Metadata" - case StreamTypeH264Video: - return "H264 Video" - case StreamTypeH265Video: - return "H265 Video" - case StreamTypeCAVSVideo: - return "CAVS Video" - case StreamTypeVC1Video: - return "VC1 Video" - case StreamTypeDIRACVideo: - return "DIRAC Video" - case StreamTypeAC3Audio: - return "AC3 Audio" - case StreamTypeDTSAudio: - return "DTS Audio" - case StreamTypeTRUEHDAudio: - return "TRUEHD Audio" - case StreamTypeEAC3Audio: - return "EAC3 Audio" - } - return "Unknown" -} - -func (t StreamType) ToPESStreamID() uint8 { - switch t { - case StreamTypeMPEG1Video, StreamTypeMPEG2Video, StreamTypeMPEG4Video, StreamTypeH264Video, - StreamTypeH265Video, StreamTypeCAVSVideo, StreamTypeVC1Video: - return 0xe0 - case StreamTypeDIRACVideo: - return 0xfd - case StreamTypeMPEG2Audio, StreamTypeAACAudio, StreamTypeAACLATMAudio: - return 0xc0 - case StreamTypeAC3Audio, StreamTypeEAC3Audio: // m2ts_mode??? - return 0xfd - case StreamTypePrivateSection, StreamTypePrivateData, StreamTypeMetadata: - return 0xfc - default: - return 0xbd - } -} diff --git a/vendor/github.com/asticode/go-astits/data_psi.go b/vendor/github.com/asticode/go-astits/data_psi.go deleted file mode 100644 index e0c3e780600..00000000000 --- a/vendor/github.com/asticode/go-astits/data_psi.go +++ /dev/null @@ -1,608 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -// PSI table IDs -const ( - PSITableTypeBAT = "BAT" - PSITableTypeDIT = "DIT" - PSITableTypeEIT = "EIT" - PSITableTypeNIT = "NIT" - PSITableTypeNull = "Null" - PSITableTypePAT = "PAT" - PSITableTypePMT = "PMT" - PSITableTypeRST = "RST" - PSITableTypeSDT = "SDT" - PSITableTypeSIT = "SIT" - PSITableTypeST = "ST" - PSITableTypeTDT = "TDT" - PSITableTypeTOT = "TOT" - PSITableTypeUnknown = "Unknown" -) - -type PSITableID uint16 - -const ( - PSITableIDPAT PSITableID = 0x00 - PSITableIDPMT PSITableID = 0x02 - PSITableIDBAT PSITableID = 0x4a - PSITableIDDIT PSITableID = 0x7e - PSITableIDRST PSITableID = 0x71 - PSITableIDSIT PSITableID = 0x7f - PSITableIDST PSITableID = 0x72 - PSITableIDTDT PSITableID = 0x70 - PSITableIDTOT PSITableID = 0x73 - PSITableIDNull PSITableID = 0xff - - PSITableIDEITStart PSITableID = 0x4e - PSITableIDEITEnd PSITableID = 0x6f - PSITableIDSDTVariant1 PSITableID = 0x42 - PSITableIDSDTVariant2 PSITableID = 0x46 - PSITableIDNITVariant1 PSITableID = 0x40 - PSITableIDNITVariant2 PSITableID = 0x41 -) - -// PSIData represents a PSI data -// https://en.wikipedia.org/wiki/Program-specific_information -type PSIData struct { - PointerField int // Present at the start of the TS packet payload signaled by the payload_unit_start_indicator bit in the TS header. Used to set packet alignment bytes or content before the start of tabled payload data. - Sections []*PSISection -} - -// PSISection represents a PSI section -type PSISection struct { - CRC32 uint32 // A checksum of the entire table excluding the pointer field, pointer filler bytes and the trailing CRC32. - Header *PSISectionHeader - Syntax *PSISectionSyntax -} - -// PSISectionHeader represents a PSI section header -type PSISectionHeader struct { - PrivateBit bool // The PAT, PMT, and CAT all set this to 0. Other tables set this to 1. - SectionLength uint16 // The number of bytes that follow for the syntax section (with CRC value) and/or table data. These bytes must not exceed a value of 1021. - SectionSyntaxIndicator bool // A flag that indicates if the syntax section follows the section length. The PAT, PMT, and CAT all set this to 1. - TableID PSITableID // Table Identifier, that defines the structure of the syntax section and other contained data. As an exception, if this is the byte that immediately follow previous table section and is set to 0xFF, then it indicates that the repeat of table section end here and the rest of TS data payload shall be stuffed with 0xFF. Consequently the value 0xFF shall not be used for the Table Identifier. - TableType string -} - -// PSISectionSyntax represents a PSI section syntax -type PSISectionSyntax struct { - Data *PSISectionSyntaxData - Header *PSISectionSyntaxHeader -} - -// PSISectionSyntaxHeader represents a PSI section syntax header -type PSISectionSyntaxHeader struct { - CurrentNextIndicator bool // Indicates if data is current in effect or is for future use. If the bit is flagged on, then the data is to be used at the present moment. - LastSectionNumber uint8 // This indicates which table is the last table in the sequence of tables. - SectionNumber uint8 // This is an index indicating which table this is in a related sequence of tables. The first table starts from 0. - TableIDExtension uint16 // Informational only identifier. The PAT uses this for the transport stream identifier and the PMT uses this for the Program number. - VersionNumber uint8 // Syntax version number. Incremented when data is changed and wrapped around on overflow for values greater than 32. -} - -// PSISectionSyntaxData represents a PSI section syntax data -type PSISectionSyntaxData struct { - EIT *EITData - NIT *NITData - PAT *PATData - PMT *PMTData - SDT *SDTData - TOT *TOTData -} - -// parsePSIData parses a PSI data -func parsePSIData(i *astikit.BytesIterator) (d *PSIData, err error) { - // Init data - d = &PSIData{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Pointer field - d.PointerField = int(b) - - // Pointer filler bytes - i.Skip(d.PointerField) - - // Parse sections - var s *PSISection - var stop bool - for i.HasBytesLeft() && !stop { - if s, stop, err = parsePSISection(i); err != nil { - err = fmt.Errorf("astits: parsing PSI table failed: %w", err) - return - } - d.Sections = append(d.Sections, s) - } - return -} - -// parsePSISection parses a PSI section -func parsePSISection(i *astikit.BytesIterator) (s *PSISection, stop bool, err error) { - // Init section - s = &PSISection{} - - // Parse header - var offsetStart, offsetSectionsEnd, offsetEnd int - if s.Header, offsetStart, _, offsetSectionsEnd, offsetEnd, err = parsePSISectionHeader(i); err != nil { - err = fmt.Errorf("astits: parsing PSI section header failed: %w", err) - return - } - - // Check whether we need to stop the parsing - if shouldStopPSIParsing(s.Header.TableID) { - stop = true - return - } - - // Check whether there's a syntax section - if s.Header.SectionLength > 0 { - // Parse syntax - if s.Syntax, err = parsePSISectionSyntax(i, s.Header, offsetSectionsEnd); err != nil { - err = fmt.Errorf("astits: parsing PSI section syntax failed: %w", err) - return - } - - // Process CRC32 - if s.Header.TableID.hasCRC32() { - // Seek to the end of the sections - i.Seek(offsetSectionsEnd) - - // Parse CRC32 - if s.CRC32, err = parseCRC32(i); err != nil { - err = fmt.Errorf("astits: parsing CRC32 failed: %w", err) - return - } - - // Get CRC32 data - i.Seek(offsetStart) - var crc32Data []byte - if crc32Data, err = i.NextBytesNoCopy(offsetSectionsEnd - offsetStart); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Compute CRC32 - crc32 := computeCRC32(crc32Data) - - // Check CRC32 - if crc32 != s.CRC32 { - err = fmt.Errorf("astits: Table CRC32 %x != computed CRC32 %x", s.CRC32, crc32) - return - } - } - } - - // Seek to the end of the section - i.Seek(offsetEnd) - return -} - -// parseCRC32 parses a CRC32 -func parseCRC32(i *astikit.BytesIterator) (c uint32, err error) { - var bs []byte - if bs, err = i.NextBytesNoCopy(4); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - c = uint32(bs[0])<<24 | uint32(bs[1])<<16 | uint32(bs[2])<<8 | uint32(bs[3]) - return -} - -// shouldStopPSIParsing checks whether the PSI parsing should be stopped -func shouldStopPSIParsing(tableID PSITableID) bool { - return tableID == PSITableIDNull || - tableID.isUnknown() -} - -// parsePSISectionHeader parses a PSI section header -func parsePSISectionHeader(i *astikit.BytesIterator) (h *PSISectionHeader, offsetStart, offsetSectionsStart, offsetSectionsEnd, offsetEnd int, err error) { - // Init - h = &PSISectionHeader{} - offsetStart = i.Offset() - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Table ID - h.TableID = PSITableID(b) - - // Table type - h.TableType = h.TableID.Type() - - // Check whether we need to stop the parsing - if shouldStopPSIParsing(h.TableID) { - return - } - - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Section syntax indicator - h.SectionSyntaxIndicator = bs[0]&0x80 > 0 - - // Private bit - h.PrivateBit = bs[0]&0x40 > 0 - - // Section length - h.SectionLength = uint16(bs[0]&0xf)<<8 | uint16(bs[1]) - - // Offsets - offsetSectionsStart = i.Offset() - offsetEnd = offsetSectionsStart + int(h.SectionLength) - offsetSectionsEnd = offsetEnd - if h.TableID.hasCRC32() { - offsetSectionsEnd -= 4 - } - return -} - -// PSITableID.Type() returns the psi table type based on the table id -// Page: 28 | https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf -// (barbashov) the link above can be broken, alternative: https://dvb.org/wp-content/uploads/2019/12/a038_tm1217r37_en300468v1_17_1_-_rev-134_-_si_specification.pdf -func (t PSITableID) Type() string { - switch { - case t == PSITableIDBAT: - return PSITableTypeBAT - case t >= PSITableIDEITStart && t <= PSITableIDEITEnd: - return PSITableTypeEIT - case t == PSITableIDDIT: - return PSITableTypeDIT - case t == PSITableIDNITVariant1, t == PSITableIDNITVariant2: - return PSITableTypeNIT - case t == PSITableIDNull: - return PSITableTypeNull - case t == PSITableIDPAT: - return PSITableTypePAT - case t == PSITableIDPMT: - return PSITableTypePMT - case t == PSITableIDRST: - return PSITableTypeRST - case t == PSITableIDSDTVariant1, t == PSITableIDSDTVariant2: - return PSITableTypeSDT - case t == PSITableIDSIT: - return PSITableTypeSIT - case t == PSITableIDST: - return PSITableTypeST - case t == PSITableIDTDT: - return PSITableTypeTDT - case t == PSITableIDTOT: - return PSITableTypeTOT - default: - return PSITableTypeUnknown - } -} - -// hasPSISyntaxHeader checks whether the section has a syntax header -func (t PSITableID) hasPSISyntaxHeader() bool { - return t == PSITableIDPAT || - t == PSITableIDPMT || - t == PSITableIDNITVariant1 || t == PSITableIDNITVariant2 || - t == PSITableIDSDTVariant1 || t == PSITableIDSDTVariant2 || - (t >= PSITableIDEITStart && t <= PSITableIDEITEnd) -} - -// hasCRC32 checks whether the table has a CRC32 -func (t PSITableID) hasCRC32() bool { - return t == PSITableIDPAT || - t == PSITableIDPMT || - t == PSITableIDTOT || - t == PSITableIDNITVariant1 || t == PSITableIDNITVariant2 || - t == PSITableIDSDTVariant1 || t == PSITableIDSDTVariant2 || - (t >= PSITableIDEITStart && t <= PSITableIDEITEnd) -} - -func (t PSITableID) isUnknown() bool { - switch t { - case PSITableIDBAT, - PSITableIDDIT, - PSITableIDNITVariant1, PSITableIDNITVariant2, - PSITableIDNull, - PSITableIDPAT, - PSITableIDPMT, - PSITableIDRST, - PSITableIDSDTVariant1, PSITableIDSDTVariant2, - PSITableIDSIT, - PSITableIDST, - PSITableIDTDT, - PSITableIDTOT: - return false - } - if t >= PSITableIDEITStart && t <= PSITableIDEITEnd { - return false - } - return true -} - -// parsePSISectionSyntax parses a PSI section syntax -func parsePSISectionSyntax(i *astikit.BytesIterator, h *PSISectionHeader, offsetSectionsEnd int) (s *PSISectionSyntax, err error) { - // Init - s = &PSISectionSyntax{} - - // Header - if h.TableID.hasPSISyntaxHeader() { - if s.Header, err = parsePSISectionSyntaxHeader(i); err != nil { - err = fmt.Errorf("astits: parsing PSI section syntax header failed: %w", err) - return - } - } - - // Parse data - if s.Data, err = parsePSISectionSyntaxData(i, h, s.Header, offsetSectionsEnd); err != nil { - err = fmt.Errorf("astits: parsing PSI section syntax data failed: %w", err) - return - } - return -} - -// parsePSISectionSyntaxHeader parses a PSI section syntax header -func parsePSISectionSyntaxHeader(i *astikit.BytesIterator) (h *PSISectionSyntaxHeader, err error) { - // Init - h = &PSISectionSyntaxHeader{} - - // Get next 2 bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Table ID extension - h.TableIDExtension = uint16(bs[0])<<8 | uint16(bs[1]) - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Version number - h.VersionNumber = uint8(b&0x3f) >> 1 - - // Current/Next indicator - h.CurrentNextIndicator = b&0x1 > 0 - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Section number - h.SectionNumber = uint8(b) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Last section number - h.LastSectionNumber = uint8(b) - return -} - -// parsePSISectionSyntaxData parses a PSI section data -func parsePSISectionSyntaxData(i *astikit.BytesIterator, h *PSISectionHeader, sh *PSISectionSyntaxHeader, offsetSectionsEnd int) (d *PSISectionSyntaxData, err error) { - // Init - d = &PSISectionSyntaxData{} - - // Switch on table type - switch h.TableID { - case PSITableIDBAT: - // TODO Parse BAT - case PSITableIDDIT: - // TODO Parse DIT - case PSITableIDNITVariant1, PSITableIDNITVariant2: - if d.NIT, err = parseNITSection(i, sh.TableIDExtension); err != nil { - err = fmt.Errorf("astits: parsing NIT section failed: %w", err) - return - } - case PSITableIDPAT: - if d.PAT, err = parsePATSection(i, offsetSectionsEnd, sh.TableIDExtension); err != nil { - err = fmt.Errorf("astits: parsing PAT section failed: %w", err) - return - } - case PSITableIDPMT: - if d.PMT, err = parsePMTSection(i, offsetSectionsEnd, sh.TableIDExtension); err != nil { - err = fmt.Errorf("astits: parsing PMT section failed: %w", err) - return - } - case PSITableIDRST: - // TODO Parse RST - case PSITableIDSDTVariant1, PSITableIDSDTVariant2: - if d.SDT, err = parseSDTSection(i, offsetSectionsEnd, sh.TableIDExtension); err != nil { - err = fmt.Errorf("astits: parsing PMT section failed: %w", err) - return - } - case PSITableIDSIT: - // TODO Parse SIT - case PSITableIDST: - // TODO Parse ST - case PSITableIDTOT: - if d.TOT, err = parseTOTSection(i); err != nil { - err = fmt.Errorf("astits: parsing TOT section failed: %w", err) - return - } - case PSITableIDTDT: - // TODO Parse TDT - } - - if h.TableID >= PSITableIDEITStart && h.TableID <= PSITableIDEITEnd { - if d.EIT, err = parseEITSection(i, offsetSectionsEnd, sh.TableIDExtension); err != nil { - err = fmt.Errorf("astits: parsing EIT section failed: %w", err) - return - } - } - - return -} - -// toData parses the PSI tables and returns a set of DemuxerData -func (d *PSIData) toData(firstPacket *Packet, pid uint16) (ds []*DemuxerData) { - // Loop through sections - for _, s := range d.Sections { - // Switch on table type - switch s.Header.TableID { - case PSITableIDNITVariant1, PSITableIDNITVariant2: - ds = append(ds, &DemuxerData{FirstPacket: firstPacket, NIT: s.Syntax.Data.NIT, PID: pid}) - case PSITableIDPAT: - ds = append(ds, &DemuxerData{FirstPacket: firstPacket, PAT: s.Syntax.Data.PAT, PID: pid}) - case PSITableIDPMT: - ds = append(ds, &DemuxerData{FirstPacket: firstPacket, PID: pid, PMT: s.Syntax.Data.PMT}) - case PSITableIDSDTVariant1, PSITableIDSDTVariant2: - ds = append(ds, &DemuxerData{FirstPacket: firstPacket, PID: pid, SDT: s.Syntax.Data.SDT}) - case PSITableIDTOT: - ds = append(ds, &DemuxerData{FirstPacket: firstPacket, PID: pid, TOT: s.Syntax.Data.TOT}) - } - if s.Header.TableID >= PSITableIDEITStart && s.Header.TableID <= PSITableIDEITEnd { - ds = append(ds, &DemuxerData{EIT: s.Syntax.Data.EIT, FirstPacket: firstPacket, PID: pid}) - } - } - return -} - -func writePSIData(w *astikit.BitsWriter, d *PSIData) (int, error) { - b := astikit.NewBitsWriterBatch(w) - b.Write(uint8(d.PointerField)) - for i := 0; i < d.PointerField; i++ { - b.Write(uint8(0x00)) - } - - bytesWritten := 1 + d.PointerField - - if err := b.Err(); err != nil { - return 0, err - } - - for _, s := range d.Sections { - n, err := writePSISection(w, s) - if err != nil { - return 0, err - } - bytesWritten += n - } - - return bytesWritten, nil -} - -func calcPSISectionLength(s *PSISection) uint16 { - ret := uint16(0) - if s.Header.TableID.hasPSISyntaxHeader() { - ret += 5 // PSI syntax header length - } - - switch s.Header.TableID { - case PSITableIDPAT: - ret += calcPATSectionLength(s.Syntax.Data.PAT) - case PSITableIDPMT: - ret += calcPMTSectionLength(s.Syntax.Data.PMT) - } - - if s.Header.TableID.hasCRC32() { - ret += 4 - } - - return ret -} - -func writePSISection(w *astikit.BitsWriter, s *PSISection) (int, error) { - if s.Header.TableID != PSITableIDPAT && s.Header.TableID != PSITableIDPMT { - return 0, fmt.Errorf("writePSISection: table %s is not implemented", s.Header.TableID.Type()) - } - - b := astikit.NewBitsWriterBatch(w) - - sectionLength := calcPSISectionLength(s) - sectionCRC32 := crc32Polynomial - - if s.Header.TableID.hasCRC32() { - w.SetWriteCallback(func(bs []byte) { - sectionCRC32 = updateCRC32(sectionCRC32, bs) - }) - defer w.SetWriteCallback(nil) - } - - b.Write(uint8(s.Header.TableID)) - b.Write(s.Header.SectionSyntaxIndicator) - b.Write(s.Header.PrivateBit) - b.WriteN(uint8(0xff), 2) - b.WriteN(sectionLength, 12) - bytesWritten := 3 - - if s.Header.SectionLength > 0 { - n, err := writePSISectionSyntax(w, s) - if err != nil { - return 0, err - } - bytesWritten += n - - if s.Header.TableID.hasCRC32() { - b.Write(sectionCRC32) - bytesWritten += 4 - } - } - - return bytesWritten, b.Err() -} - -func writePSISectionSyntax(w *astikit.BitsWriter, s *PSISection) (int, error) { - bytesWritten := 0 - if s.Header.TableID.hasPSISyntaxHeader() { - n, err := writePSISectionSyntaxHeader(w, s.Syntax.Header) - if err != nil { - return 0, err - } - bytesWritten += n - } - - n, err := writePSISectionSyntaxData(w, s.Syntax.Data, s.Header.TableID) - if err != nil { - return 0, err - } - bytesWritten += n - - return bytesWritten, nil -} - -func writePSISectionSyntaxHeader(w *astikit.BitsWriter, h *PSISectionSyntaxHeader) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - b.Write(h.TableIDExtension) - b.WriteN(uint8(0xff), 2) - b.WriteN(h.VersionNumber, 5) - b.Write(h.CurrentNextIndicator) - b.Write(h.SectionNumber) - b.Write(h.LastSectionNumber) - - return 5, b.Err() -} - -func writePSISectionSyntaxData(w *astikit.BitsWriter, d *PSISectionSyntaxData, tableID PSITableID) (int, error) { - switch tableID { - // TODO write other table types - case PSITableIDPAT: - return writePATSection(w, d.PAT) - case PSITableIDPMT: - return writePMTSection(w, d.PMT) - } - - return 0, nil -} diff --git a/vendor/github.com/asticode/go-astits/data_sdt.go b/vendor/github.com/asticode/go-astits/data_sdt.go deleted file mode 100644 index f060f26786d..00000000000 --- a/vendor/github.com/asticode/go-astits/data_sdt.go +++ /dev/null @@ -1,108 +0,0 @@ -package astits - -import ( - "fmt" - - "github.com/asticode/go-astikit" -) - -// Running statuses -const ( - RunningStatusNotRunning = 1 - RunningStatusPausing = 3 - RunningStatusRunning = 4 - RunningStatusServiceOffAir = 5 - RunningStatusStartsInAFewSeconds = 2 - RunningStatusUndefined = 0 -) - -// SDTData represents an SDT data -// Page: 33 | Chapter: 5.2.3 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf -// (barbashov) the link above can be broken, alternative: https://dvb.org/wp-content/uploads/2019/12/a038_tm1217r37_en300468v1_17_1_-_rev-134_-_si_specification.pdf -type SDTData struct { - OriginalNetworkID uint16 - Services []*SDTDataService - TransportStreamID uint16 -} - -// SDTDataService represents an SDT data service -type SDTDataService struct { - Descriptors []*Descriptor - HasEITPresentFollowing bool // When true indicates that EIT present/following information for the service is present in the current TS - HasEITSchedule bool // When true indicates that EIT schedule information for the service is present in the current TS - HasFreeCSAMode bool // When true indicates that access to one or more streams may be controlled by a CA system. - RunningStatus uint8 - ServiceID uint16 -} - -// parseSDTSection parses an SDT section -func parseSDTSection(i *astikit.BytesIterator, offsetSectionsEnd int, tableIDExtension uint16) (d *SDTData, err error) { - // Create data - d = &SDTData{TransportStreamID: tableIDExtension} - - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Original network ID - d.OriginalNetworkID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Reserved for future use - i.Skip(1) - - // Loop until end of section data is reached - for i.Offset() < offsetSectionsEnd { - // Create service - s := &SDTDataService{} - - // Get next bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Service ID - s.ServiceID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // EIT schedule flag - s.HasEITSchedule = uint8(b&0x2) > 0 - - // EIT present/following flag - s.HasEITPresentFollowing = uint8(b&0x1) > 0 - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Running status - s.RunningStatus = uint8(b) >> 5 - - // Free CA mode - s.HasFreeCSAMode = uint8(b&0x10) > 0 - - // We need to rewind since the current byte is used by the descriptor as well - i.Skip(-1) - - // Descriptors - if s.Descriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - - // Append service - d.Services = append(d.Services, s) - } - return -} diff --git a/vendor/github.com/asticode/go-astits/data_tot.go b/vendor/github.com/asticode/go-astits/data_tot.go deleted file mode 100644 index 0bd64d2dbe2..00000000000 --- a/vendor/github.com/asticode/go-astits/data_tot.go +++ /dev/null @@ -1,35 +0,0 @@ -package astits - -import ( - "fmt" - "time" - - "github.com/asticode/go-astikit" -) - -// TOTData represents a TOT data -// Page: 39 | Chapter: 5.2.6 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf -// (barbashov) the link above can be broken, alternative: https://dvb.org/wp-content/uploads/2019/12/a038_tm1217r37_en300468v1_17_1_-_rev-134_-_si_specification.pdf -type TOTData struct { - Descriptors []*Descriptor - UTCTime time.Time -} - -// parseTOTSection parses a TOT section -func parseTOTSection(i *astikit.BytesIterator) (d *TOTData, err error) { - // Create data - d = &TOTData{} - - // UTC time - if d.UTCTime, err = parseDVBTime(i); err != nil { - err = fmt.Errorf("astits: parsing DVB time failed: %w", err) - return - } - - // Descriptors - if d.Descriptors, err = parseDescriptors(i); err != nil { - err = fmt.Errorf("astits: parsing descriptors failed: %w", err) - return - } - return -} diff --git a/vendor/github.com/asticode/go-astits/demuxer.go b/vendor/github.com/asticode/go-astits/demuxer.go deleted file mode 100644 index b17e82f1cf7..00000000000 --- a/vendor/github.com/asticode/go-astits/demuxer.go +++ /dev/null @@ -1,189 +0,0 @@ -package astits - -import ( - "context" - "errors" - "fmt" - "io" -) - -// Sync byte -const syncByte = '\x47' - -// Errors -var ( - ErrNoMorePackets = errors.New("astits: no more packets") - ErrPacketMustStartWithASyncByte = errors.New("astits: packet must start with a sync byte") -) - -// Demuxer represents a demuxer -// https://en.wikipedia.org/wiki/MPEG_transport_stream -// http://seidl.cs.vsb.cz/download/dvb/DVB_Poster.pdf -// http://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.13.01_40/en_300468v011301o.pdf -type Demuxer struct { - ctx context.Context - dataBuffer []*DemuxerData - optPacketSize int - optPacketsParser PacketsParser - packetBuffer *packetBuffer - packetPool *packetPool - programMap programMap - r io.Reader -} - -// PacketsParser represents an object capable of parsing a set of packets containing a unique payload spanning over those packets -// Use the skip returned argument to indicate whether the default process should still be executed on the set of packets -type PacketsParser func(ps []*Packet) (ds []*DemuxerData, skip bool, err error) - -// NewDemuxer creates a new transport stream based on a reader -func NewDemuxer(ctx context.Context, r io.Reader, opts ...func(*Demuxer)) (d *Demuxer) { - // Init - d = &Demuxer{ - ctx: ctx, - packetPool: newPacketPool(), - programMap: newProgramMap(), - r: r, - } - - // Apply options - for _, opt := range opts { - opt(d) - } - - return -} - -// DemuxerOptPacketSize returns the option to set the packet size -func DemuxerOptPacketSize(packetSize int) func(*Demuxer) { - return func(d *Demuxer) { - d.optPacketSize = packetSize - } -} - -// DemuxerOptPacketsParser returns the option to set the packets parser -func DemuxerOptPacketsParser(p PacketsParser) func(*Demuxer) { - return func(d *Demuxer) { - d.optPacketsParser = p - } -} - -// NextPacket retrieves the next packet -func (dmx *Demuxer) NextPacket() (p *Packet, err error) { - // Check ctx error - // TODO Handle ctx error another way since if the read blocks, everything blocks - // Maybe execute everything in a goroutine and listen the ctx channel in the same for loop - if err = dmx.ctx.Err(); err != nil { - return - } - - // Create packet buffer if not exists - if dmx.packetBuffer == nil { - if dmx.packetBuffer, err = newPacketBuffer(dmx.r, dmx.optPacketSize); err != nil { - err = fmt.Errorf("astits: creating packet buffer failed: %w", err) - return - } - } - - // Fetch next packet from buffer - if p, err = dmx.packetBuffer.next(); err != nil { - if err != ErrNoMorePackets { - err = fmt.Errorf("astits: fetching next packet from buffer failed: %w", err) - } - return - } - return -} - -// NextData retrieves the next data -func (dmx *Demuxer) NextData() (d *DemuxerData, err error) { - // Check data buffer - if len(dmx.dataBuffer) > 0 { - d = dmx.dataBuffer[0] - dmx.dataBuffer = dmx.dataBuffer[1:] - return - } - - // Loop through packets - var p *Packet - var ps []*Packet - var ds []*DemuxerData - for { - // Get next packet - if p, err = dmx.NextPacket(); err != nil { - // If the end of the stream has been reached, we dump the packet pool - if err == ErrNoMorePackets { - for { - // Dump packet pool - if ps = dmx.packetPool.dump(); len(ps) == 0 { - break - } - - // Parse data - if ds, err = parseData(ps, dmx.optPacketsParser, dmx.programMap); err != nil { - // We need to silence this error as there may be some incomplete data here - // We still want to try to parse all packets, in case final data is complete - continue - } - - // Update data - if d = dmx.updateData(ds); d != nil { - return - } - } - return - } - err = fmt.Errorf("astits: fetching next packet failed: %w", err) - return - } - - // Add packet to the pool - if ps = dmx.packetPool.add(p); len(ps) == 0 { - continue - } - - // Parse data - if ds, err = parseData(ps, dmx.optPacketsParser, dmx.programMap); err != nil { - err = fmt.Errorf("astits: building new data failed: %w", err) - return - } - - // Update data - if d = dmx.updateData(ds); d != nil { - return - } - } -} - -func (dmx *Demuxer) updateData(ds []*DemuxerData) (d *DemuxerData) { - // Check whether there is data to be processed - if len(ds) > 0 { - // Process data - d = ds[0] - dmx.dataBuffer = append(dmx.dataBuffer, ds[1:]...) - - // Update program map - for _, v := range ds { - if v.PAT != nil { - for _, pgm := range v.PAT.Programs { - // Program number 0 is reserved to NIT - if pgm.ProgramNumber > 0 { - dmx.programMap.set(pgm.ProgramMapID, pgm.ProgramNumber) - } - } - } - } - } - return -} - -// Rewind rewinds the demuxer reader -func (dmx *Demuxer) Rewind() (n int64, err error) { - dmx.dataBuffer = []*DemuxerData{} - dmx.packetBuffer = nil - dmx.packetPool = newPacketPool() - if n, err = rewind(dmx.r); err != nil { - err = fmt.Errorf("astits: rewinding reader failed: %w", err) - return - } - return -} diff --git a/vendor/github.com/asticode/go-astits/descriptor.go b/vendor/github.com/asticode/go-astits/descriptor.go deleted file mode 100644 index 943604a4682..00000000000 --- a/vendor/github.com/asticode/go-astits/descriptor.go +++ /dev/null @@ -1,2162 +0,0 @@ -package astits - -import ( - "fmt" - "time" - - "github.com/asticode/go-astikit" -) - -// Audio types -// Page: 683 | https://books.google.fr/books?id=6dgWB3-rChYC&printsec=frontcover&hl=fr -const ( - AudioTypeCleanEffects = 0x1 - AudioTypeHearingImpaired = 0x2 - AudioTypeVisualImpairedCommentary = 0x3 -) - -// Data stream alignments -// Page: 85 | Chapter:2.6.11 | Link: http://ecee.colorado.edu/~ecen5653/ecen5653/papers/iso13818-1.pdf -const ( - DataStreamAligmentAudioSyncWord = 0x1 - DataStreamAligmentVideoSliceOrAccessUnit = 0x1 - DataStreamAligmentVideoAccessUnit = 0x2 - DataStreamAligmentVideoGOPOrSEQ = 0x3 - DataStreamAligmentVideoSEQ = 0x4 -) - -// Descriptor tags -// Chapter: 6.1 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -const ( - DescriptorTagAC3 = 0x6a - DescriptorTagAVCVideo = 0x28 - DescriptorTagComponent = 0x50 - DescriptorTagContent = 0x54 - DescriptorTagDataStreamAlignment = 0x6 - DescriptorTagEnhancedAC3 = 0x7a - DescriptorTagExtendedEvent = 0x4e - DescriptorTagExtension = 0x7f - DescriptorTagISO639LanguageAndAudioType = 0xa - DescriptorTagLocalTimeOffset = 0x58 - DescriptorTagMaximumBitrate = 0xe - DescriptorTagNetworkName = 0x40 - DescriptorTagParentalRating = 0x55 - DescriptorTagPrivateDataIndicator = 0xf - DescriptorTagPrivateDataSpecifier = 0x5f - DescriptorTagRegistration = 0x5 - DescriptorTagService = 0x48 - DescriptorTagShortEvent = 0x4d - DescriptorTagStreamIdentifier = 0x52 - DescriptorTagSubtitling = 0x59 - DescriptorTagTeletext = 0x56 - DescriptorTagVBIData = 0x45 - DescriptorTagVBITeletext = 0x46 -) - -// Descriptor extension tags -// Chapter: 6.3 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -const ( - DescriptorTagExtensionSupplementaryAudio = 0x6 -) - -// Service types -// Chapter: 6.2.33 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -const ( - ServiceTypeDigitalTelevisionService = 0x1 -) - -// Teletext types -// Chapter: 6.2.43 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -const ( - TeletextTypeAdditionalInformationPage = 0x3 - TeletextTypeInitialTeletextPage = 0x1 - TeletextTypeProgramSchedulePage = 0x4 - TeletextTypeTeletextSubtitlePage = 0x2 - TeletextTypeTeletextSubtitlePageForHearingImpairedPeople = 0x5 -) - -// VBI data service id -// Chapter: 6.2.47 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -const ( - VBIDataServiceIDClosedCaptioning = 0x6 - VBIDataServiceIDEBUTeletext = 0x1 - VBIDataServiceIDInvertedTeletext = 0x2 - VBIDataServiceIDMonochrome442Samples = 0x7 - VBIDataServiceIDVPS = 0x4 - VBIDataServiceIDWSS = 0x5 -) - -// Descriptor represents a descriptor -// TODO Handle UTF8 -type Descriptor struct { - AC3 *DescriptorAC3 - AVCVideo *DescriptorAVCVideo - Component *DescriptorComponent - Content *DescriptorContent - DataStreamAlignment *DescriptorDataStreamAlignment - EnhancedAC3 *DescriptorEnhancedAC3 - ExtendedEvent *DescriptorExtendedEvent - Extension *DescriptorExtension - ISO639LanguageAndAudioType *DescriptorISO639LanguageAndAudioType - Length uint8 - LocalTimeOffset *DescriptorLocalTimeOffset - MaximumBitrate *DescriptorMaximumBitrate - NetworkName *DescriptorNetworkName - ParentalRating *DescriptorParentalRating - PrivateDataIndicator *DescriptorPrivateDataIndicator - PrivateDataSpecifier *DescriptorPrivateDataSpecifier - Registration *DescriptorRegistration - Service *DescriptorService - ShortEvent *DescriptorShortEvent - StreamIdentifier *DescriptorStreamIdentifier - Subtitling *DescriptorSubtitling - Tag uint8 // the tag defines the structure of the contained data following the descriptor length. - Teletext *DescriptorTeletext - Unknown *DescriptorUnknown - UserDefined []byte - VBIData *DescriptorVBIData - VBITeletext *DescriptorTeletext -} - -// DescriptorAC3 represents an AC3 descriptor -// Chapter: Annex D | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorAC3 struct { - AdditionalInfo []byte - ASVC uint8 - BSID uint8 - ComponentType uint8 - HasASVC bool - HasBSID bool - HasComponentType bool - HasMainID bool - MainID uint8 -} - -func newDescriptorAC3(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorAC3, err error) { - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorAC3{ - HasASVC: uint8(b&0x10) > 0, - HasBSID: uint8(b&0x40) > 0, - HasComponentType: uint8(b&0x80) > 0, - HasMainID: uint8(b&0x20) > 0, - } - - // Component type - if d.HasComponentType { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.ComponentType = uint8(b) - } - - // BSID - if d.HasBSID { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.BSID = uint8(b) - } - - // Main ID - if d.HasMainID { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.MainID = uint8(b) - } - - // ASVC - if d.HasASVC { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.ASVC = uint8(b) - } - - // Additional info - if i.Offset() < offsetEnd { - if d.AdditionalInfo, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - return -} - -// DescriptorAVCVideo represents an AVC video descriptor -// No doc found unfortunately, basing the implementation on https://github.com/gfto/bitstream/blob/master/mpeg/psi/desc_28.h -type DescriptorAVCVideo struct { - AVC24HourPictureFlag bool - AVCStillPresent bool - CompatibleFlags uint8 - ConstraintSet0Flag bool - ConstraintSet1Flag bool - ConstraintSet2Flag bool - LevelIDC uint8 - ProfileIDC uint8 -} - -func newDescriptorAVCVideo(i *astikit.BytesIterator) (d *DescriptorAVCVideo, err error) { - // Init - d = &DescriptorAVCVideo{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Profile idc - d.ProfileIDC = uint8(b) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Flags - d.ConstraintSet0Flag = b&0x80 > 0 - d.ConstraintSet1Flag = b&0x40 > 0 - d.ConstraintSet2Flag = b&0x20 > 0 - d.CompatibleFlags = b & 0x1f - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Level idc - d.LevelIDC = uint8(b) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // AVC still present - d.AVCStillPresent = b&0x80 > 0 - - // AVC 24 hour picture flag - d.AVC24HourPictureFlag = b&0x40 > 0 - return -} - -// DescriptorComponent represents a component descriptor -// Chapter: 6.2.8 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorComponent struct { - ComponentTag uint8 - ComponentType uint8 - ISO639LanguageCode []byte - StreamContent uint8 - StreamContentExt uint8 - Text []byte -} - -func newDescriptorComponent(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorComponent, err error) { - // Init - d = &DescriptorComponent{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Stream content ext - d.StreamContentExt = uint8(b >> 4) - - // Stream content - d.StreamContent = uint8(b & 0xf) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Component type - d.ComponentType = uint8(b) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Component tag - d.ComponentTag = uint8(b) - - // ISO639 language code - if d.ISO639LanguageCode, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Text - if i.Offset() < offsetEnd { - if d.Text, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - return -} - -// DescriptorContent represents a content descriptor -// Chapter: 6.2.9 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorContent struct { - Items []*DescriptorContentItem -} - -// DescriptorContentItem represents a content item descriptor -// Chapter: 6.2.9 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorContentItem struct { - ContentNibbleLevel1 uint8 - ContentNibbleLevel2 uint8 - UserByte uint8 -} - -func newDescriptorContent(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorContent, err error) { - // Init - d = &DescriptorContent{} - - // Add items - for i.Offset() < offsetEnd { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Append item - d.Items = append(d.Items, &DescriptorContentItem{ - ContentNibbleLevel1: uint8(bs[0] >> 4), - ContentNibbleLevel2: uint8(bs[0] & 0xf), - UserByte: uint8(bs[1]), - }) - } - return -} - -// DescriptorDataStreamAlignment represents a data stream alignment descriptor -type DescriptorDataStreamAlignment struct { - Type uint8 -} - -func newDescriptorDataStreamAlignment(i *astikit.BytesIterator) (d *DescriptorDataStreamAlignment, err error) { - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d = &DescriptorDataStreamAlignment{Type: uint8(b)} - return -} - -// DescriptorEnhancedAC3 represents an enhanced AC3 descriptor -// Chapter: Annex D | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorEnhancedAC3 struct { - AdditionalInfo []byte - ASVC uint8 - BSID uint8 - ComponentType uint8 - HasASVC bool - HasBSID bool - HasComponentType bool - HasMainID bool - HasSubStream1 bool - HasSubStream2 bool - HasSubStream3 bool - MainID uint8 - MixInfoExists bool - SubStream1 uint8 - SubStream2 uint8 - SubStream3 uint8 -} - -func newDescriptorEnhancedAC3(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorEnhancedAC3, err error) { - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorEnhancedAC3{ - HasASVC: uint8(b&0x10) > 0, - HasBSID: uint8(b&0x40) > 0, - HasComponentType: uint8(b&0x80) > 0, - HasMainID: uint8(b&0x20) > 0, - HasSubStream1: uint8(b&0x4) > 0, - HasSubStream2: uint8(b&0x2) > 0, - HasSubStream3: uint8(b&0x1) > 0, - MixInfoExists: uint8(b&0x8) > 0, - } - - // Component type - if d.HasComponentType { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.ComponentType = uint8(b) - } - - // BSID - if d.HasBSID { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.BSID = uint8(b) - } - - // Main ID - if d.HasMainID { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.MainID = uint8(b) - } - - // ASVC - if d.HasASVC { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.ASVC = uint8(b) - } - - // Substream 1 - if d.HasSubStream1 { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.SubStream1 = uint8(b) - } - - // Substream 2 - if d.HasSubStream2 { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.SubStream2 = uint8(b) - } - - // Substream 3 - if d.HasSubStream3 { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d.SubStream3 = uint8(b) - } - - // Additional info - if i.Offset() < offsetEnd { - if d.AdditionalInfo, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - return -} - -// DescriptorExtendedEvent represents an extended event descriptor -// Chapter: 6.2.15 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorExtendedEvent struct { - ISO639LanguageCode []byte - Items []*DescriptorExtendedEventItem - LastDescriptorNumber uint8 - Number uint8 - Text []byte -} - -// DescriptorExtendedEventItem represents an extended event item descriptor -// Chapter: 6.2.15 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorExtendedEventItem struct { - Content []byte - Description []byte -} - -func newDescriptorExtendedEvent(i *astikit.BytesIterator) (d *DescriptorExtendedEvent, err error) { - // Init - d = &DescriptorExtendedEvent{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Number - d.Number = uint8(b >> 4) - - // Last descriptor number - d.LastDescriptorNumber = uint8(b & 0xf) - - // ISO639 language code - if d.ISO639LanguageCode, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Items length - itemsLength := int(b) - - // Items - offsetEnd := i.Offset() + itemsLength - for i.Offset() < offsetEnd { - // Create item - var item *DescriptorExtendedEventItem - if item, err = newDescriptorExtendedEventItem(i); err != nil { - err = fmt.Errorf("astits: creating extended event item failed: %w", err) - return - } - - // Append item - d.Items = append(d.Items, item) - } - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Text length - textLength := int(b) - - // Text - if d.Text, err = i.NextBytes(textLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -func newDescriptorExtendedEventItem(i *astikit.BytesIterator) (d *DescriptorExtendedEventItem, err error) { - // Init - d = &DescriptorExtendedEventItem{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Description length - descriptionLength := int(b) - - // Description - if d.Description, err = i.NextBytes(descriptionLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Content length - contentLength := int(b) - - // Content - if d.Content, err = i.NextBytes(contentLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -// DescriptorExtension represents an extension descriptor -// Chapter: 6.2.16 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorExtension struct { - SupplementaryAudio *DescriptorExtensionSupplementaryAudio - Tag uint8 - Unknown *[]byte -} - -func newDescriptorExtension(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorExtension, err error) { - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorExtension{Tag: uint8(b)} - - // Switch on tag - switch d.Tag { - case DescriptorTagExtensionSupplementaryAudio: - if d.SupplementaryAudio, err = newDescriptorExtensionSupplementaryAudio(i, offsetEnd); err != nil { - err = fmt.Errorf("astits: parsing extension supplementary audio descriptor failed: %w", err) - return - } - default: - // Get next bytes - var b []byte - if b, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Update unknown - d.Unknown = &b - } - return -} - -// DescriptorExtensionSupplementaryAudio represents a supplementary audio extension descriptor -// Chapter: 6.4.10 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorExtensionSupplementaryAudio struct { - EditorialClassification uint8 - HasLanguageCode bool - LanguageCode []byte - MixType bool - PrivateData []byte -} - -func newDescriptorExtensionSupplementaryAudio(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorExtensionSupplementaryAudio, err error) { - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Init - d = &DescriptorExtensionSupplementaryAudio{ - EditorialClassification: uint8(b >> 2 & 0x1f), - HasLanguageCode: b&0x1 > 0, - MixType: b&0x80 > 0, - } - - // Language code - if d.HasLanguageCode { - if d.LanguageCode, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - - // Private data - if i.Offset() < offsetEnd { - if d.PrivateData, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - return -} - -// DescriptorISO639LanguageAndAudioType represents an ISO639 language descriptor -// https://github.com/gfto/bitstream/blob/master/mpeg/psi/desc_0a.h -// FIXME (barbashov) according to Chapter 2.6.18 ISO/IEC 13818-1:2015 there could be not one, but multiple such descriptors -type DescriptorISO639LanguageAndAudioType struct { - Language []byte - Type uint8 -} - -// In some actual cases, the length is 3 and the language is described in only 2 bytes -func newDescriptorISO639LanguageAndAudioType(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorISO639LanguageAndAudioType, err error) { - // Get next bytes - var bs []byte - if bs, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorISO639LanguageAndAudioType{ - Language: bs[0 : len(bs)-1], - Type: uint8(bs[len(bs)-1]), - } - return -} - -// DescriptorLocalTimeOffset represents a local time offset descriptor -// Chapter: 6.2.20 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorLocalTimeOffset struct { - Items []*DescriptorLocalTimeOffsetItem -} - -// DescriptorLocalTimeOffsetItem represents a local time offset item descriptor -// Chapter: 6.2.20 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorLocalTimeOffsetItem struct { - CountryCode []byte - CountryRegionID uint8 - LocalTimeOffset time.Duration - LocalTimeOffsetPolarity bool - NextTimeOffset time.Duration - TimeOfChange time.Time -} - -func newDescriptorLocalTimeOffset(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorLocalTimeOffset, err error) { - // Init - d = &DescriptorLocalTimeOffset{} - - // Add items - for i.Offset() < offsetEnd { - // Create item - itm := &DescriptorLocalTimeOffsetItem{} - - // Country code - if itm.CountryCode, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Country region ID - itm.CountryRegionID = uint8(b >> 2) - - // Local time offset polarity - itm.LocalTimeOffsetPolarity = b&0x1 > 0 - - // Local time offset - if itm.LocalTimeOffset, err = parseDVBDurationMinutes(i); err != nil { - err = fmt.Errorf("astits: parsing DVB durationminutes failed: %w", err) - return - } - - // Time of change - if itm.TimeOfChange, err = parseDVBTime(i); err != nil { - err = fmt.Errorf("astits: parsing DVB time failed: %w", err) - return - } - - // Next time offset - if itm.NextTimeOffset, err = parseDVBDurationMinutes(i); err != nil { - err = fmt.Errorf("astits: parsing DVB duration minutes failed: %w", err) - return - } - - // Append item - d.Items = append(d.Items, itm) - } - return -} - -// DescriptorMaximumBitrate represents a maximum bitrate descriptor -type DescriptorMaximumBitrate struct { - Bitrate uint32 // In bytes/second -} - -func newDescriptorMaximumBitrate(i *astikit.BytesIterator) (d *DescriptorMaximumBitrate, err error) { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorMaximumBitrate{Bitrate: (uint32(bs[0]&0x3f)<<16 | uint32(bs[1])<<8 | uint32(bs[2])) * 50} - return -} - -// DescriptorNetworkName represents a network name descriptor -// Chapter: 6.2.27 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorNetworkName struct { - Name []byte -} - -func newDescriptorNetworkName(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorNetworkName, err error) { - // Create descriptor - d = &DescriptorNetworkName{} - - // Name - if d.Name, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -// DescriptorParentalRating represents a parental rating descriptor -// Chapter: 6.2.28 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorParentalRating struct { - Items []*DescriptorParentalRatingItem -} - -// DescriptorParentalRatingItem represents a parental rating item descriptor -// Chapter: 6.2.28 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorParentalRatingItem struct { - CountryCode []byte - Rating uint8 -} - -// MinimumAge returns the minimum age for the parental rating -func (d DescriptorParentalRatingItem) MinimumAge() int { - // Undefined or user defined ratings - if d.Rating == 0 || d.Rating > 0x10 { - return 0 - } - return int(d.Rating) + 3 -} - -func newDescriptorParentalRating(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorParentalRating, err error) { - // Create descriptor - d = &DescriptorParentalRating{} - - // Add items - for i.Offset() < offsetEnd { - // Get next bytes - var bs []byte - if bs, err = i.NextBytes(4); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Append item - d.Items = append(d.Items, &DescriptorParentalRatingItem{ - CountryCode: bs[:3], - Rating: uint8(bs[3]), - }) - } - return -} - -// DescriptorPrivateDataIndicator represents a private data Indicator descriptor -type DescriptorPrivateDataIndicator struct { - Indicator uint32 -} - -func newDescriptorPrivateDataIndicator(i *astikit.BytesIterator) (d *DescriptorPrivateDataIndicator, err error) { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(4); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorPrivateDataIndicator{Indicator: uint32(bs[0])<<24 | uint32(bs[1])<<16 | uint32(bs[2])<<8 | uint32(bs[3])} - return -} - -// DescriptorPrivateDataSpecifier represents a private data specifier descriptor -type DescriptorPrivateDataSpecifier struct { - Specifier uint32 -} - -func newDescriptorPrivateDataSpecifier(i *astikit.BytesIterator) (d *DescriptorPrivateDataSpecifier, err error) { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(4); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorPrivateDataSpecifier{Specifier: uint32(bs[0])<<24 | uint32(bs[1])<<16 | uint32(bs[2])<<8 | uint32(bs[3])} - return -} - -// DescriptorRegistration represents a registration descriptor -// Page: 84 | http://ecee.colorado.edu/~ecen5653/ecen5653/papers/iso13818-1.pdf -type DescriptorRegistration struct { - AdditionalIdentificationInfo []byte - FormatIdentifier uint32 -} - -func newDescriptorRegistration(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorRegistration, err error) { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(4); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorRegistration{FormatIdentifier: uint32(bs[0])<<24 | uint32(bs[1])<<16 | uint32(bs[2])<<8 | uint32(bs[3])} - - // Additional identification info - if i.Offset() < offsetEnd { - if d.AdditionalIdentificationInfo, err = i.NextBytes(offsetEnd - i.Offset()); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - return -} - -// DescriptorService represents a service descriptor -// Chapter: 6.2.33 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorService struct { - Name []byte - Provider []byte - Type uint8 -} - -func newDescriptorService(i *astikit.BytesIterator) (d *DescriptorService, err error) { - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Create descriptor - d = &DescriptorService{Type: uint8(b)} - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Provider length - providerLength := int(b) - - // Provider - if d.Provider, err = i.NextBytes(providerLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Name length - nameLength := int(b) - - // Name - if d.Name, err = i.NextBytes(nameLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -// DescriptorShortEvent represents a short event descriptor -// Chapter: 6.2.37 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorShortEvent struct { - EventName []byte - Language []byte - Text []byte -} - -func newDescriptorShortEvent(i *astikit.BytesIterator) (d *DescriptorShortEvent, err error) { - // Create descriptor - d = &DescriptorShortEvent{} - - // Language - if d.Language, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Event length - eventLength := int(b) - - // Event name - if d.EventName, err = i.NextBytes(eventLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Text length - textLength := int(b) - - // Text - if d.Text, err = i.NextBytes(textLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -// DescriptorStreamIdentifier represents a stream identifier descriptor -// Chapter: 6.2.39 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorStreamIdentifier struct { - ComponentTag uint8 -} - -func newDescriptorStreamIdentifier(i *astikit.BytesIterator) (d *DescriptorStreamIdentifier, err error) { - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - d = &DescriptorStreamIdentifier{ComponentTag: uint8(b)} - return -} - -// DescriptorSubtitling represents a subtitling descriptor -// Chapter: 6.2.41 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorSubtitling struct { - Items []*DescriptorSubtitlingItem -} - -// DescriptorSubtitlingItem represents subtitling descriptor item -// Chapter: 6.2.41 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorSubtitlingItem struct { - AncillaryPageID uint16 - CompositionPageID uint16 - Language []byte - Type uint8 -} - -func newDescriptorSubtitling(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorSubtitling, err error) { - // Create descriptor - d = &DescriptorSubtitling{} - - // Loop - for i.Offset() < offsetEnd { - // Create item - itm := &DescriptorSubtitlingItem{} - - // Language - if itm.Language, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Type - itm.Type = uint8(b) - - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Composition page ID - itm.CompositionPageID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Get next bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Ancillary page ID - itm.AncillaryPageID = uint16(bs[0])<<8 | uint16(bs[1]) - - // Append item - d.Items = append(d.Items, itm) - } - return -} - -// DescriptorTeletext represents a teletext descriptor -// Chapter: 6.2.43 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorTeletext struct { - Items []*DescriptorTeletextItem -} - -// DescriptorTeletextItem represents a teletext descriptor item -// Chapter: 6.2.43 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorTeletextItem struct { - Language []byte - Magazine uint8 - Page uint8 - Type uint8 -} - -func newDescriptorTeletext(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorTeletext, err error) { - // Create descriptor - d = &DescriptorTeletext{} - - // Loop - for i.Offset() < offsetEnd { - // Create item - itm := &DescriptorTeletextItem{} - - // Language - if itm.Language, err = i.NextBytes(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Type - itm.Type = uint8(b) >> 3 - - // Magazine - itm.Magazine = uint8(b & 0x7) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Page - itm.Page = uint8(b)>>4*10 + uint8(b&0xf) - - // Append item - d.Items = append(d.Items, itm) - } - return -} - -type DescriptorUnknown struct { - Content []byte - Tag uint8 -} - -func newDescriptorUnknown(i *astikit.BytesIterator, tag, length uint8) (d *DescriptorUnknown, err error) { - // Create descriptor - d = &DescriptorUnknown{Tag: tag} - - // Get next bytes - if d.Content, err = i.NextBytes(int(length)); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - return -} - -// DescriptorVBIData represents a VBI data descriptor -// Chapter: 6.2.47 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorVBIData struct { - Services []*DescriptorVBIDataService -} - -// DescriptorVBIDataService represents a vbi data service descriptor -// Chapter: 6.2.47 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorVBIDataService struct { - DataServiceID uint8 - Descriptors []*DescriptorVBIDataDescriptor -} - -// DescriptorVBIDataItem represents a vbi data descriptor item -// Chapter: 6.2.47 | Link: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf -type DescriptorVBIDataDescriptor struct { - FieldParity bool - LineOffset uint8 -} - -func newDescriptorVBIData(i *astikit.BytesIterator, offsetEnd int) (d *DescriptorVBIData, err error) { - // Create descriptor - d = &DescriptorVBIData{} - - // Loop - for i.Offset() < offsetEnd { - // Create service - srv := &DescriptorVBIDataService{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Data service ID - srv.DataServiceID = uint8(b) - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Data service descriptor length - dataServiceDescriptorLength := int(b) - - // Data service descriptor - offsetDataEnd := i.Offset() + dataServiceDescriptorLength - for i.Offset() < offsetDataEnd { - if srv.DataServiceID == VBIDataServiceIDClosedCaptioning || - srv.DataServiceID == VBIDataServiceIDEBUTeletext || - srv.DataServiceID == VBIDataServiceIDInvertedTeletext || - srv.DataServiceID == VBIDataServiceIDMonochrome442Samples || - srv.DataServiceID == VBIDataServiceIDVPS || - srv.DataServiceID == VBIDataServiceIDWSS { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Append data - srv.Descriptors = append(srv.Descriptors, &DescriptorVBIDataDescriptor{ - FieldParity: b&0x20 > 0, - LineOffset: uint8(b & 0x1f), - }) - } - } - - // Append service - d.Services = append(d.Services, srv) - } - return -} - -// parseDescriptors parses descriptors -func parseDescriptors(i *astikit.BytesIterator) (o []*Descriptor, err error) { - // Get next 2 bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Get length - length := int(uint16(bs[0]&0xf)<<8 | uint16(bs[1])) - - // Loop - if length > 0 { - offsetEnd := i.Offset() + length - for i.Offset() < offsetEnd { - // Get next 2 bytes - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create descriptor - d := &Descriptor{ - Length: uint8(bs[1]), - Tag: uint8(bs[0]), - } - - // Parse data - if d.Length > 0 { - // Unfortunately there's no way to be sure the real descriptor length is the same as the one indicated - // previously therefore we must fetch bytes in descriptor functions and seek at the end - offsetDescriptorEnd := i.Offset() + int(d.Length) - - // User defined - if d.Tag >= 0x80 && d.Tag <= 0xfe { - // Get next bytes - if d.UserDefined, err = i.NextBytes(int(d.Length)); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } else { - // Switch on tag - switch d.Tag { - case DescriptorTagAC3: - if d.AC3, err = newDescriptorAC3(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing AC3 descriptor failed: %w", err) - return - } - case DescriptorTagAVCVideo: - if d.AVCVideo, err = newDescriptorAVCVideo(i); err != nil { - err = fmt.Errorf("astits: parsing AVC Video descriptor failed: %w", err) - return - } - case DescriptorTagComponent: - if d.Component, err = newDescriptorComponent(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Component descriptor failed: %w", err) - return - } - case DescriptorTagContent: - if d.Content, err = newDescriptorContent(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Content descriptor failed: %w", err) - return - } - case DescriptorTagDataStreamAlignment: - if d.DataStreamAlignment, err = newDescriptorDataStreamAlignment(i); err != nil { - err = fmt.Errorf("astits: parsing Data Stream Alignment descriptor failed: %w", err) - return - } - case DescriptorTagEnhancedAC3: - if d.EnhancedAC3, err = newDescriptorEnhancedAC3(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Enhanced AC3 descriptor failed: %w", err) - return - } - case DescriptorTagExtendedEvent: - if d.ExtendedEvent, err = newDescriptorExtendedEvent(i); err != nil { - err = fmt.Errorf("astits: parsing Extended event descriptor failed: %w", err) - return - } - case DescriptorTagExtension: - if d.Extension, err = newDescriptorExtension(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Extension descriptor failed: %w", err) - return - } - case DescriptorTagISO639LanguageAndAudioType: - if d.ISO639LanguageAndAudioType, err = newDescriptorISO639LanguageAndAudioType(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing ISO639 Language and Audio Type descriptor failed: %w", err) - return - } - case DescriptorTagLocalTimeOffset: - if d.LocalTimeOffset, err = newDescriptorLocalTimeOffset(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Local Time Offset descriptor failed: %w", err) - return - } - case DescriptorTagMaximumBitrate: - if d.MaximumBitrate, err = newDescriptorMaximumBitrate(i); err != nil { - err = fmt.Errorf("astits: parsing Maximum Bitrate descriptor failed: %w", err) - return - } - case DescriptorTagNetworkName: - if d.NetworkName, err = newDescriptorNetworkName(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Network Name descriptor failed: %w", err) - return - } - case DescriptorTagParentalRating: - if d.ParentalRating, err = newDescriptorParentalRating(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Parental Rating descriptor failed: %w", err) - return - } - case DescriptorTagPrivateDataIndicator: - if d.PrivateDataIndicator, err = newDescriptorPrivateDataIndicator(i); err != nil { - err = fmt.Errorf("astits: parsing Private Data Indicator descriptor failed: %w", err) - return - } - case DescriptorTagPrivateDataSpecifier: - if d.PrivateDataSpecifier, err = newDescriptorPrivateDataSpecifier(i); err != nil { - err = fmt.Errorf("astits: parsing Private Data Specifier descriptor failed: %w", err) - return - } - case DescriptorTagRegistration: - if d.Registration, err = newDescriptorRegistration(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Registration descriptor failed: %w", err) - return - } - case DescriptorTagService: - if d.Service, err = newDescriptorService(i); err != nil { - err = fmt.Errorf("astits: parsing Service descriptor failed: %w", err) - return - } - case DescriptorTagShortEvent: - if d.ShortEvent, err = newDescriptorShortEvent(i); err != nil { - err = fmt.Errorf("astits: parsing Short Event descriptor failed: %w", err) - return - } - case DescriptorTagStreamIdentifier: - if d.StreamIdentifier, err = newDescriptorStreamIdentifier(i); err != nil { - err = fmt.Errorf("astits: parsing Stream Identifier descriptor failed: %w", err) - return - } - case DescriptorTagSubtitling: - if d.Subtitling, err = newDescriptorSubtitling(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Subtitling descriptor failed: %w", err) - return - } - case DescriptorTagTeletext: - if d.Teletext, err = newDescriptorTeletext(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing Teletext descriptor failed: %w", err) - return - } - case DescriptorTagVBIData: - if d.VBIData, err = newDescriptorVBIData(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing VBI Date descriptor failed: %w", err) - return - } - case DescriptorTagVBITeletext: - if d.VBITeletext, err = newDescriptorTeletext(i, offsetDescriptorEnd); err != nil { - err = fmt.Errorf("astits: parsing VBI Teletext descriptor failed: %w", err) - return - } - default: - if d.Unknown, err = newDescriptorUnknown(i, d.Tag, d.Length); err != nil { - err = fmt.Errorf("astits: parsing unknown descriptor failed: %w", err) - return - } - } - } - - // Seek in iterator to make sure we move to the end of the descriptor since its content may be - // corrupted - i.Seek(offsetDescriptorEnd) - } - o = append(o, d) - } - } - return -} - -func calcDescriptorUserDefinedLength(d []byte) uint8 { - return uint8(len(d)) -} - -func writeDescriptorUserDefined(w *astikit.BitsWriter, d []byte) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d) - - return b.Err() -} - -func calcDescriptorAC3Length(d *DescriptorAC3) uint8 { - ret := 1 // flags - - if d.HasComponentType { - ret++ - } - if d.HasBSID { - ret++ - } - if d.HasMainID { - ret++ - } - if d.HasASVC { - ret++ - } - - ret += len(d.AdditionalInfo) - - return uint8(ret) -} - -func writeDescriptorAC3(w *astikit.BitsWriter, d *DescriptorAC3) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.HasComponentType) - b.Write(d.HasBSID) - b.Write(d.HasMainID) - b.Write(d.HasASVC) - b.WriteN(uint8(0xff), 4) - - if d.HasComponentType { - b.Write(d.ComponentType) - } - if d.HasBSID { - b.Write(d.BSID) - } - if d.HasMainID { - b.Write(d.MainID) - } - if d.HasASVC { - b.Write(d.ASVC) - } - b.Write(d.AdditionalInfo) - - return b.Err() -} - -func calcDescriptorAVCVideoLength(d *DescriptorAVCVideo) uint8 { - return 4 -} - -func writeDescriptorAVCVideo(w *astikit.BitsWriter, d *DescriptorAVCVideo) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.ProfileIDC) - - b.Write(d.ConstraintSet0Flag) - b.Write(d.ConstraintSet1Flag) - b.Write(d.ConstraintSet2Flag) - b.WriteN(d.CompatibleFlags, 5) - - b.Write(d.LevelIDC) - - b.Write(d.AVCStillPresent) - b.Write(d.AVC24HourPictureFlag) - b.WriteN(uint8(0xff), 6) - - return b.Err() -} - -func calcDescriptorComponentLength(d *DescriptorComponent) uint8 { - return uint8(6 + len(d.Text)) -} - -func writeDescriptorComponent(w *astikit.BitsWriter, d *DescriptorComponent) error { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(d.StreamContentExt, 4) - b.WriteN(d.StreamContent, 4) - - b.Write(d.ComponentType) - b.Write(d.ComponentTag) - - b.WriteBytesN(d.ISO639LanguageCode, 3, 0) - - b.Write(d.Text) - - return b.Err() -} - -func calcDescriptorContentLength(d *DescriptorContent) uint8 { - return uint8(2 * len(d.Items)) -} - -func writeDescriptorContent(w *astikit.BitsWriter, d *DescriptorContent) error { - b := astikit.NewBitsWriterBatch(w) - - for _, item := range d.Items { - b.WriteN(item.ContentNibbleLevel1, 4) - b.WriteN(item.ContentNibbleLevel2, 4) - b.Write(item.UserByte) - } - - return b.Err() -} - -func calcDescriptorDataStreamAlignmentLength(d *DescriptorDataStreamAlignment) uint8 { - return 1 -} - -func writeDescriptorDataStreamAlignment(w *astikit.BitsWriter, d *DescriptorDataStreamAlignment) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Type) - - return b.Err() -} - -func calcDescriptorEnhancedAC3Length(d *DescriptorEnhancedAC3) uint8 { - ret := 1 // flags - - if d.HasComponentType { - ret++ - } - if d.HasBSID { - ret++ - } - if d.HasMainID { - ret++ - } - if d.HasASVC { - ret++ - } - if d.HasSubStream1 { - ret++ - } - if d.HasSubStream2 { - ret++ - } - if d.HasSubStream3 { - ret++ - } - - ret += len(d.AdditionalInfo) - - return uint8(ret) -} - -func writeDescriptorEnhancedAC3(w *astikit.BitsWriter, d *DescriptorEnhancedAC3) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.HasComponentType) - b.Write(d.HasBSID) - b.Write(d.HasMainID) - b.Write(d.HasASVC) - b.Write(d.MixInfoExists) - b.Write(d.HasSubStream1) - b.Write(d.HasSubStream2) - b.Write(d.HasSubStream3) - - if d.HasComponentType { - b.Write(d.ComponentType) - } - if d.HasBSID { - b.Write(d.BSID) - } - if d.HasMainID { - b.Write(d.MainID) - } - if d.HasASVC { - b.Write(d.ASVC) - } - if d.HasSubStream1 { - b.Write(d.SubStream1) - } - if d.HasSubStream2 { - b.Write(d.SubStream2) - } - if d.HasSubStream3 { - b.Write(d.SubStream3) - } - - b.Write(d.AdditionalInfo) - - return b.Err() -} - -func calcDescriptorExtendedEventLength(d *DescriptorExtendedEvent) (descriptorLength, lengthOfItems uint8) { - ret := 1 + 3 + 1 // numbers, language and items length - - itemsRet := 0 - for _, item := range d.Items { - itemsRet += 1 // description length - itemsRet += len(item.Description) - itemsRet += 1 // content length - itemsRet += len(item.Content) - } - - ret += itemsRet - - ret += 1 // text length - ret += len(d.Text) - - return uint8(ret), uint8(itemsRet) -} - -func writeDescriptorExtendedEvent(w *astikit.BitsWriter, d *DescriptorExtendedEvent) error { - b := astikit.NewBitsWriterBatch(w) - - var lengthOfItems uint8 - - _, lengthOfItems = calcDescriptorExtendedEventLength(d) - - b.WriteN(d.Number, 4) - b.WriteN(d.LastDescriptorNumber, 4) - - b.WriteBytesN(d.ISO639LanguageCode, 3, 0) - - b.Write(lengthOfItems) - for _, item := range d.Items { - b.Write(uint8(len(item.Description))) - b.Write(item.Description) - b.Write(uint8(len(item.Content))) - b.Write(item.Content) - } - - b.Write(uint8(len(d.Text))) - b.Write(d.Text) - - return b.Err() -} - -func calcDescriptorExtensionSupplementaryAudioLength(d *DescriptorExtensionSupplementaryAudio) int { - ret := 1 - if d.HasLanguageCode { - ret += 3 - } - ret += len(d.PrivateData) - return ret -} - -func calcDescriptorExtensionLength(d *DescriptorExtension) uint8 { - ret := 1 // tag - - switch d.Tag { - case DescriptorTagExtensionSupplementaryAudio: - ret += calcDescriptorExtensionSupplementaryAudioLength(d.SupplementaryAudio) - default: - if d.Unknown != nil { - ret += len(*d.Unknown) - } - } - - return uint8(ret) -} - -func writeDescriptorExtensionSupplementaryAudio(w *astikit.BitsWriter, d *DescriptorExtensionSupplementaryAudio) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.MixType) - b.WriteN(d.EditorialClassification, 5) - b.Write(true) // reserved - b.Write(d.HasLanguageCode) - - if d.HasLanguageCode { - b.WriteBytesN(d.LanguageCode, 3, 0) - } - - b.Write(d.PrivateData) - - return b.Err() -} - -func writeDescriptorExtension(w *astikit.BitsWriter, d *DescriptorExtension) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Tag) - - switch d.Tag { - case DescriptorTagExtensionSupplementaryAudio: - err := writeDescriptorExtensionSupplementaryAudio(w, d.SupplementaryAudio) - if err != nil { - return err - } - default: - if d.Unknown != nil { - b.Write(*d.Unknown) - } - } - - return b.Err() -} - -func calcDescriptorISO639LanguageAndAudioTypeLength(d *DescriptorISO639LanguageAndAudioType) uint8 { - return 3 + 1 // language code + type -} - -func writeDescriptorISO639LanguageAndAudioType(w *astikit.BitsWriter, d *DescriptorISO639LanguageAndAudioType) error { - b := astikit.NewBitsWriterBatch(w) - - b.WriteBytesN(d.Language, 3, 0) - b.Write(d.Type) - - return b.Err() -} - -func calcDescriptorLocalTimeOffsetLength(d *DescriptorLocalTimeOffset) uint8 { - return uint8(13 * len(d.Items)) -} - -func writeDescriptorLocalTimeOffset(w *astikit.BitsWriter, d *DescriptorLocalTimeOffset) error { - b := astikit.NewBitsWriterBatch(w) - - for _, item := range d.Items { - b.WriteBytesN(item.CountryCode, 3, 0) - - b.WriteN(item.CountryRegionID, 6) - b.WriteN(uint8(0xff), 1) - b.Write(item.LocalTimeOffsetPolarity) - - if _, err := writeDVBDurationMinutes(w, item.LocalTimeOffset); err != nil { - return err - } - if _, err := writeDVBTime(w, item.TimeOfChange); err != nil { - return err - } - if _, err := writeDVBDurationMinutes(w, item.NextTimeOffset); err != nil { - return err - } - } - - return b.Err() -} - -func calcDescriptorMaximumBitrateLength(d *DescriptorMaximumBitrate) uint8 { - return 3 -} - -func writeDescriptorMaximumBitrate(w *astikit.BitsWriter, d *DescriptorMaximumBitrate) error { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(uint8(0xff), 2) - b.WriteN(uint32(d.Bitrate/50), 22) - - return b.Err() -} - -func calcDescriptorNetworkNameLength(d *DescriptorNetworkName) uint8 { - return uint8(len(d.Name)) -} - -func writeDescriptorNetworkName(w *astikit.BitsWriter, d *DescriptorNetworkName) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Name) - - return b.Err() -} - -func calcDescriptorParentalRatingLength(d *DescriptorParentalRating) uint8 { - return uint8(4 * len(d.Items)) -} - -func writeDescriptorParentalRating(w *astikit.BitsWriter, d *DescriptorParentalRating) error { - b := astikit.NewBitsWriterBatch(w) - - for _, item := range d.Items { - b.WriteBytesN(item.CountryCode, 3, 0) - b.Write(item.Rating) - } - - return b.Err() -} - -func calcDescriptorPrivateDataIndicatorLength(d *DescriptorPrivateDataIndicator) uint8 { - return 4 -} - -func writeDescriptorPrivateDataIndicator(w *astikit.BitsWriter, d *DescriptorPrivateDataIndicator) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Indicator) - - return b.Err() -} - -func calcDescriptorPrivateDataSpecifierLength(d *DescriptorPrivateDataSpecifier) uint8 { - return 4 -} - -func writeDescriptorPrivateDataSpecifier(w *astikit.BitsWriter, d *DescriptorPrivateDataSpecifier) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Specifier) - - return b.Err() -} - -func calcDescriptorRegistrationLength(d *DescriptorRegistration) uint8 { - return uint8(4 + len(d.AdditionalIdentificationInfo)) -} - -func writeDescriptorRegistration(w *astikit.BitsWriter, d *DescriptorRegistration) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.FormatIdentifier) - b.Write(d.AdditionalIdentificationInfo) - - return b.Err() -} - -func calcDescriptorServiceLength(d *DescriptorService) uint8 { - ret := 3 // type and lengths - ret += len(d.Name) - ret += len(d.Provider) - return uint8(ret) -} - -func writeDescriptorService(w *astikit.BitsWriter, d *DescriptorService) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Type) - b.Write(uint8(len(d.Provider))) - b.Write(d.Provider) - b.Write(uint8(len(d.Name))) - b.Write(d.Name) - - return b.Err() -} - -func calcDescriptorShortEventLength(d *DescriptorShortEvent) uint8 { - ret := 3 + 1 + 1 // language code and lengths - ret += len(d.EventName) - ret += len(d.Text) - return uint8(ret) -} - -func writeDescriptorShortEvent(w *astikit.BitsWriter, d *DescriptorShortEvent) error { - b := astikit.NewBitsWriterBatch(w) - - b.WriteBytesN(d.Language, 3, 0) - - b.Write(uint8(len(d.EventName))) - b.Write(d.EventName) - - b.Write(uint8(len(d.Text))) - b.Write(d.Text) - - return b.Err() -} - -func calcDescriptorStreamIdentifierLength(d *DescriptorStreamIdentifier) uint8 { - return 1 -} - -func writeDescriptorStreamIdentifier(w *astikit.BitsWriter, d *DescriptorStreamIdentifier) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.ComponentTag) - - return b.Err() -} - -func calcDescriptorSubtitlingLength(d *DescriptorSubtitling) uint8 { - return uint8(8 * len(d.Items)) -} - -func writeDescriptorSubtitling(w *astikit.BitsWriter, d *DescriptorSubtitling) error { - b := astikit.NewBitsWriterBatch(w) - - for _, item := range d.Items { - b.WriteBytesN(item.Language, 3, 0) - b.Write(item.Type) - b.Write(item.CompositionPageID) - b.Write(item.AncillaryPageID) - } - - return b.Err() -} - -func calcDescriptorTeletextLength(d *DescriptorTeletext) uint8 { - return uint8(5 * len(d.Items)) -} - -func writeDescriptorTeletext(w *astikit.BitsWriter, d *DescriptorTeletext) error { - b := astikit.NewBitsWriterBatch(w) - - for _, item := range d.Items { - b.WriteBytesN(item.Language, 3, 0) - b.WriteN(item.Type, 5) - b.WriteN(item.Magazine, 3) - b.WriteN(item.Page/10, 4) - b.WriteN(item.Page%10, 4) - } - - return b.Err() -} - -func calcDescriptorVBIDataLength(d *DescriptorVBIData) uint8 { - return uint8(3 * len(d.Services)) -} - -func writeDescriptorVBIData(w *astikit.BitsWriter, d *DescriptorVBIData) error { - b := astikit.NewBitsWriterBatch(w) - - for _, item := range d.Services { - b.Write(item.DataServiceID) - - if item.DataServiceID == VBIDataServiceIDClosedCaptioning || - item.DataServiceID == VBIDataServiceIDEBUTeletext || - item.DataServiceID == VBIDataServiceIDInvertedTeletext || - item.DataServiceID == VBIDataServiceIDMonochrome442Samples || - item.DataServiceID == VBIDataServiceIDVPS || - item.DataServiceID == VBIDataServiceIDWSS { - - b.Write(uint8(len(item.Descriptors))) // each descriptor is 1 byte - for _, desc := range item.Descriptors { - b.WriteN(uint8(0xff), 2) - b.Write(desc.FieldParity) - b.WriteN(desc.LineOffset, 5) - } - } else { - // let's put one reserved byte - b.Write(uint8(1)) - b.Write(uint8(0xff)) - } - } - - return b.Err() -} - -func calcDescriptorUnknownLength(d *DescriptorUnknown) uint8 { - return uint8(len(d.Content)) -} - -func writeDescriptorUnknown(w *astikit.BitsWriter, d *DescriptorUnknown) error { - b := astikit.NewBitsWriterBatch(w) - - b.Write(d.Content) - - return b.Err() -} - -func calcDescriptorLength(d *Descriptor) uint8 { - if d.Tag >= 0x80 && d.Tag <= 0xfe { - return calcDescriptorUserDefinedLength(d.UserDefined) - } - - switch d.Tag { - case DescriptorTagAC3: - return calcDescriptorAC3Length(d.AC3) - case DescriptorTagAVCVideo: - return calcDescriptorAVCVideoLength(d.AVCVideo) - case DescriptorTagComponent: - return calcDescriptorComponentLength(d.Component) - case DescriptorTagContent: - return calcDescriptorContentLength(d.Content) - case DescriptorTagDataStreamAlignment: - return calcDescriptorDataStreamAlignmentLength(d.DataStreamAlignment) - case DescriptorTagEnhancedAC3: - return calcDescriptorEnhancedAC3Length(d.EnhancedAC3) - case DescriptorTagExtendedEvent: - ret, _ := calcDescriptorExtendedEventLength(d.ExtendedEvent) - return ret - case DescriptorTagExtension: - return calcDescriptorExtensionLength(d.Extension) - case DescriptorTagISO639LanguageAndAudioType: - return calcDescriptorISO639LanguageAndAudioTypeLength(d.ISO639LanguageAndAudioType) - case DescriptorTagLocalTimeOffset: - return calcDescriptorLocalTimeOffsetLength(d.LocalTimeOffset) - case DescriptorTagMaximumBitrate: - return calcDescriptorMaximumBitrateLength(d.MaximumBitrate) - case DescriptorTagNetworkName: - return calcDescriptorNetworkNameLength(d.NetworkName) - case DescriptorTagParentalRating: - return calcDescriptorParentalRatingLength(d.ParentalRating) - case DescriptorTagPrivateDataIndicator: - return calcDescriptorPrivateDataIndicatorLength(d.PrivateDataIndicator) - case DescriptorTagPrivateDataSpecifier: - return calcDescriptorPrivateDataSpecifierLength(d.PrivateDataSpecifier) - case DescriptorTagRegistration: - return calcDescriptorRegistrationLength(d.Registration) - case DescriptorTagService: - return calcDescriptorServiceLength(d.Service) - case DescriptorTagShortEvent: - return calcDescriptorShortEventLength(d.ShortEvent) - case DescriptorTagStreamIdentifier: - return calcDescriptorStreamIdentifierLength(d.StreamIdentifier) - case DescriptorTagSubtitling: - return calcDescriptorSubtitlingLength(d.Subtitling) - case DescriptorTagTeletext: - return calcDescriptorTeletextLength(d.Teletext) - case DescriptorTagVBIData: - return calcDescriptorVBIDataLength(d.VBIData) - case DescriptorTagVBITeletext: - return calcDescriptorTeletextLength(d.VBITeletext) - } - - return calcDescriptorUnknownLength(d.Unknown) -} - -func writeDescriptor(w *astikit.BitsWriter, d *Descriptor) (int, error) { - b := astikit.NewBitsWriterBatch(w) - length := calcDescriptorLength(d) - - b.Write(d.Tag) - b.Write(length) - - if err := b.Err(); err != nil { - return 0, err - } - - written := int(length) + 2 - - if d.Tag >= 0x80 && d.Tag <= 0xfe { - return written, writeDescriptorUserDefined(w, d.UserDefined) - } - - switch d.Tag { - case DescriptorTagAC3: - return written, writeDescriptorAC3(w, d.AC3) - case DescriptorTagAVCVideo: - return written, writeDescriptorAVCVideo(w, d.AVCVideo) - case DescriptorTagComponent: - return written, writeDescriptorComponent(w, d.Component) - case DescriptorTagContent: - return written, writeDescriptorContent(w, d.Content) - case DescriptorTagDataStreamAlignment: - return written, writeDescriptorDataStreamAlignment(w, d.DataStreamAlignment) - case DescriptorTagEnhancedAC3: - return written, writeDescriptorEnhancedAC3(w, d.EnhancedAC3) - case DescriptorTagExtendedEvent: - return written, writeDescriptorExtendedEvent(w, d.ExtendedEvent) - case DescriptorTagExtension: - return written, writeDescriptorExtension(w, d.Extension) - case DescriptorTagISO639LanguageAndAudioType: - return written, writeDescriptorISO639LanguageAndAudioType(w, d.ISO639LanguageAndAudioType) - case DescriptorTagLocalTimeOffset: - return written, writeDescriptorLocalTimeOffset(w, d.LocalTimeOffset) - case DescriptorTagMaximumBitrate: - return written, writeDescriptorMaximumBitrate(w, d.MaximumBitrate) - case DescriptorTagNetworkName: - return written, writeDescriptorNetworkName(w, d.NetworkName) - case DescriptorTagParentalRating: - return written, writeDescriptorParentalRating(w, d.ParentalRating) - case DescriptorTagPrivateDataIndicator: - return written, writeDescriptorPrivateDataIndicator(w, d.PrivateDataIndicator) - case DescriptorTagPrivateDataSpecifier: - return written, writeDescriptorPrivateDataSpecifier(w, d.PrivateDataSpecifier) - case DescriptorTagRegistration: - return written, writeDescriptorRegistration(w, d.Registration) - case DescriptorTagService: - return written, writeDescriptorService(w, d.Service) - case DescriptorTagShortEvent: - return written, writeDescriptorShortEvent(w, d.ShortEvent) - case DescriptorTagStreamIdentifier: - return written, writeDescriptorStreamIdentifier(w, d.StreamIdentifier) - case DescriptorTagSubtitling: - return written, writeDescriptorSubtitling(w, d.Subtitling) - case DescriptorTagTeletext: - return written, writeDescriptorTeletext(w, d.Teletext) - case DescriptorTagVBIData: - return written, writeDescriptorVBIData(w, d.VBIData) - case DescriptorTagVBITeletext: - return written, writeDescriptorTeletext(w, d.VBITeletext) - } - - return written, writeDescriptorUnknown(w, d.Unknown) -} - -func calcDescriptorsLength(ds []*Descriptor) uint16 { - length := uint16(0) - for _, d := range ds { - length += 2 // tag and length - length += uint16(calcDescriptorLength(d)) - } - return length -} - -func writeDescriptors(w *astikit.BitsWriter, ds []*Descriptor) (int, error) { - written := 0 - - for _, d := range ds { - n, err := writeDescriptor(w, d) - if err != nil { - return 0, err - } - written += n - } - - return written, nil -} - -func writeDescriptorsWithLength(w *astikit.BitsWriter, ds []*Descriptor) (int, error) { - length := calcDescriptorsLength(ds) - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(uint8(0xff), 4) // reserved - b.WriteN(length, 12) // program_info_length - - if err := b.Err(); err != nil { - return 0, err - } - - written, err := writeDescriptors(w, ds) - return written + 2, err // 2 for length -} diff --git a/vendor/github.com/asticode/go-astits/dvb.go b/vendor/github.com/asticode/go-astits/dvb.go deleted file mode 100644 index 711a984c001..00000000000 --- a/vendor/github.com/asticode/go-astits/dvb.go +++ /dev/null @@ -1,130 +0,0 @@ -package astits - -import ( - "fmt" - "time" - - "github.com/asticode/go-astikit" -) - -// parseDVBTime parses a DVB time -// This field is coded as 16 bits giving the 16 LSBs of MJD followed by 24 bits coded as 6 digits in 4 - bit Binary -// Coded Decimal (BCD). If the start time is undefined (e.g. for an event in a NVOD reference service) all bits of the -// field are set to "1". -// I apologize for the computation which is really messy but details are given in the documentation -// Page: 160 | Annex C | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf -// (barbashov) the link above can be broken, alternative: https://dvb.org/wp-content/uploads/2019/12/a038_tm1217r37_en300468v1_17_1_-_rev-134_-_si_specification.pdf -func parseDVBTime(i *astikit.BytesIterator) (t time.Time, err error) { - // Get next 2 bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Date - var mjd = uint16(bs[0])<<8 | uint16(bs[1]) - var yt = int((float64(mjd) - 15078.2) / 365.25) - var mt = int((float64(mjd) - 14956.1 - float64(int(float64(yt)*365.25))) / 30.6001) - var d = int(float64(mjd) - 14956 - float64(int(float64(yt)*365.25)) - float64(int(float64(mt)*30.6001))) - var k int - if mt == 14 || mt == 15 { - k = 1 - } - var y = yt + k - var m = mt - 1 - k*12 - t, _ = time.Parse("06-01-02", fmt.Sprintf("%d-%d-%d", y, m, d)) - - // Time - var s time.Duration - if s, err = parseDVBDurationSeconds(i); err != nil { - err = fmt.Errorf("astits: parsing DVB duration seconds failed: %w", err) - return - } - t = t.Add(s) - return -} - -// parseDVBDurationMinutes parses a minutes duration -// 16 bit field containing the duration of the event in hours, minutes. format: 4 digits, 4 - bit BCD = 18 bit -func parseDVBDurationMinutes(i *astikit.BytesIterator) (d time.Duration, err error) { - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - d = parseDVBDurationByte(bs[0])*time.Hour + parseDVBDurationByte(bs[1])*time.Minute - return -} - -// parseDVBDurationSeconds parses a seconds duration -// 24 bit field containing the duration of the event in hours, minutes, seconds. format: 6 digits, 4 - bit BCD = 24 bit -func parseDVBDurationSeconds(i *astikit.BytesIterator) (d time.Duration, err error) { - var bs []byte - if bs, err = i.NextBytesNoCopy(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - d = parseDVBDurationByte(bs[0])*time.Hour + parseDVBDurationByte(bs[1])*time.Minute + parseDVBDurationByte(bs[2])*time.Second - return -} - -// parseDVBDurationByte parses a duration byte -func parseDVBDurationByte(i byte) time.Duration { - return time.Duration(uint8(i)>>4*10 + uint8(i)&0xf) -} - -func writeDVBTime(w *astikit.BitsWriter, t time.Time) (int, error) { - year := t.Year() - 1900 - month := t.Month() - day := t.Day() - - l := 0 - if month <= time.February { - l = 1 - } - - mjd := 14956 + day + int(float64(year-l)*365.25) + int(float64(int(month)+1+l*12)*30.6001) - - d := t.Sub(t.Truncate(24 * time.Hour)) - - b := astikit.NewBitsWriterBatch(w) - - b.Write(uint16(mjd)) - bytesWritten, err := writeDVBDurationSeconds(w, d) - if err != nil { - return 2, err - } - - return bytesWritten + 2, b.Err() -} - -func writeDVBDurationMinutes(w *astikit.BitsWriter, d time.Duration) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - hours := uint8(d.Hours()) - minutes := uint8(int(d.Minutes()) % 60) - - b.Write(dvbDurationByteRepresentation(hours)) - b.Write(dvbDurationByteRepresentation(minutes)) - - return 2, b.Err() -} - -func writeDVBDurationSeconds(w *astikit.BitsWriter, d time.Duration) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - hours := uint8(d.Hours()) - minutes := uint8(int(d.Minutes()) % 60) - seconds := uint8(int(d.Seconds()) % 60) - - b.Write(dvbDurationByteRepresentation(hours)) - b.Write(dvbDurationByteRepresentation(minutes)) - b.Write(dvbDurationByteRepresentation(seconds)) - - return 3, b.Err() -} - -func dvbDurationByteRepresentation(n uint8) uint8 { - return (n/10)<<4 | n%10 -} diff --git a/vendor/github.com/asticode/go-astits/muxer.go b/vendor/github.com/asticode/go-astits/muxer.go deleted file mode 100644 index 0312169e90c..00000000000 --- a/vendor/github.com/asticode/go-astits/muxer.go +++ /dev/null @@ -1,422 +0,0 @@ -package astits - -import ( - "bytes" - "context" - "errors" - "github.com/asticode/go-astikit" - "io" -) - -const ( - startPID uint16 = 0x0100 - pmtStartPID uint16 = 0x1000 - programNumberStart uint16 = 1 -) - -var ( - ErrPIDNotFound = errors.New("astits: PID not found") - ErrPIDAlreadyExists = errors.New("astits: PID already exists") - ErrPCRPIDInvalid = errors.New("astits: PCR PID invalid") -) - -type Muxer struct { - ctx context.Context - w io.Writer - bitsWriter *astikit.BitsWriter - - packetSize int - tablesRetransmitPeriod int // period in PES packets - - pm programMap // pid -> programNumber - pmt PMTData - nextPID uint16 - patVersion wrappingCounter - pmtVersion wrappingCounter - - patBytes bytes.Buffer - pmtBytes bytes.Buffer - - buf bytes.Buffer - bufWriter *astikit.BitsWriter - - esContexts map[uint16]*esContext - tablesRetransmitCounter int -} - -type esContext struct { - es *PMTElementaryStream - cc wrappingCounter -} - -func newEsContext(es *PMTElementaryStream) *esContext { - return &esContext{ - es: es, - cc: newWrappingCounter(0b1111), // CC is 4 bits - } -} - -func MuxerOptTablesRetransmitPeriod(newPeriod int) func(*Muxer) { - return func(m *Muxer) { - m.tablesRetransmitPeriod = newPeriod - } -} - -// TODO MuxerOptAutodetectPCRPID selecting first video PID for each PMT, falling back to first audio, falling back to any other - -func NewMuxer(ctx context.Context, w io.Writer, opts ...func(*Muxer)) *Muxer { - m := &Muxer{ - ctx: ctx, - w: w, - - packetSize: MpegTsPacketSize, // no 192-byte packet support yet - tablesRetransmitPeriod: 40, - - pm: newProgramMap(), - pmt: PMTData{ - ElementaryStreams: []*PMTElementaryStream{}, - ProgramNumber: programNumberStart, - }, - - // table version is 5-bit field - patVersion: newWrappingCounter(0b11111), - pmtVersion: newWrappingCounter(0b11111), - - esContexts: map[uint16]*esContext{}, - } - - m.bufWriter = astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &m.buf}) - m.bitsWriter = astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: m.w}) - - // TODO multiple programs support - m.pm.set(pmtStartPID, programNumberStart) - - for _, opt := range opts { - opt(m) - } - - // to output tables at the very start - m.tablesRetransmitCounter = m.tablesRetransmitPeriod - - return m -} - -// if es.ElementaryPID is zero, it will be generated automatically -func (m *Muxer) AddElementaryStream(es PMTElementaryStream) error { - if es.ElementaryPID != 0 { - for _, oes := range m.pmt.ElementaryStreams { - if oes.ElementaryPID == es.ElementaryPID { - return ErrPIDAlreadyExists - } - } - } else { - es.ElementaryPID = m.nextPID - m.nextPID++ - } - - m.pmt.ElementaryStreams = append(m.pmt.ElementaryStreams, &es) - - m.esContexts[es.ElementaryPID] = newEsContext(&es) - // invalidate pmt cache - m.pmtBytes.Reset() - return nil -} - -func (m *Muxer) RemoveElementaryStream(pid uint16) error { - foundIdx := -1 - for i, oes := range m.pmt.ElementaryStreams { - if oes.ElementaryPID == pid { - foundIdx = i - break - } - } - - if foundIdx == -1 { - return ErrPIDNotFound - } - - m.pmt.ElementaryStreams = append(m.pmt.ElementaryStreams[:foundIdx], m.pmt.ElementaryStreams[foundIdx+1:]...) - delete(m.esContexts, pid) - m.pmtBytes.Reset() - return nil -} - -// SetPCRPID marks pid as one to look PCRs in -func (m *Muxer) SetPCRPID(pid uint16) { - m.pmt.PCRPID = pid -} - -// WriteData writes MuxerData to TS stream -// Currently only PES packets are supported -// Be aware that after successful call WriteData will set d.AdaptationField.StuffingLength value to zero -func (m *Muxer) WriteData(d *MuxerData) (int, error) { - ctx, ok := m.esContexts[d.PID] - if !ok { - return 0, ErrPIDNotFound - } - - bytesWritten := 0 - - forceTables := d.AdaptationField != nil && - d.AdaptationField.RandomAccessIndicator && - d.PID == m.pmt.PCRPID - - n, err := m.retransmitTables(forceTables) - if err != nil { - return n, err - } - - bytesWritten += n - - payloadStart := true - writeAf := d.AdaptationField != nil - payloadBytesWritten := 0 - for payloadBytesWritten < len(d.PES.Data) { - pktLen := 1 + mpegTsPacketHeaderSize // sync byte + header - pkt := Packet{ - Header: &PacketHeader{ - ContinuityCounter: uint8(ctx.cc.get()), - HasAdaptationField: writeAf, - HasPayload: false, - PayloadUnitStartIndicator: false, - PID: d.PID, - }, - } - - if writeAf { - pkt.AdaptationField = d.AdaptationField - // one byte for adaptation field length field - pktLen += 1 + int(calcPacketAdaptationFieldLength(d.AdaptationField)) - writeAf = false - } - - bytesAvailable := m.packetSize - pktLen - if payloadStart { - pesHeaderLengthCurrent := pesHeaderLength + int(calcPESOptionalHeaderLength(d.PES.Header.OptionalHeader)) - // d.AdaptationField with pes header are too big, we don't have space to write pes header - if bytesAvailable < pesHeaderLengthCurrent { - pkt.Header.HasAdaptationField = true - if pkt.AdaptationField == nil { - pkt.AdaptationField = newStuffingAdaptationField(bytesAvailable) - } else { - pkt.AdaptationField.StuffingLength = bytesAvailable - } - } else { - pkt.Header.HasPayload = true - pkt.Header.PayloadUnitStartIndicator = true - } - } else { - pkt.Header.HasPayload = true - } - - if pkt.Header.HasPayload { - m.buf.Reset() - if d.PES.Header.StreamID == 0 { - d.PES.Header.StreamID = ctx.es.StreamType.ToPESStreamID() - } - - ntot, npayload, err := writePESData( - m.bufWriter, - d.PES.Header, - d.PES.Data[payloadBytesWritten:], - payloadStart, - bytesAvailable, - ) - if err != nil { - return bytesWritten, err - } - - payloadBytesWritten += npayload - - pkt.Payload = m.buf.Bytes() - - bytesAvailable -= ntot - // if we still have some space in packet, we should stuff it with adaptation field stuffing - // we can't stuff packets with 0xff at the end of a packet since it's not uncommon for PES payloads to have length unspecified - if bytesAvailable > 0 { - pkt.Header.HasAdaptationField = true - if pkt.AdaptationField == nil { - pkt.AdaptationField = newStuffingAdaptationField(bytesAvailable) - } else { - pkt.AdaptationField.StuffingLength = bytesAvailable - } - } - - n, err = writePacket(m.bitsWriter, &pkt, m.packetSize) - if err != nil { - return bytesWritten, err - } - - bytesWritten += n - - payloadStart = false - } - } - - if d.AdaptationField != nil { - d.AdaptationField.StuffingLength = 0 - } - - return bytesWritten, nil -} - -// Writes given packet to MPEG-TS stream -// Stuffs with 0xffs if packet turns out to be shorter than target packet length -func (m *Muxer) WritePacket(p *Packet) (int, error) { - return writePacket(m.bitsWriter, p, m.packetSize) -} - -func (m *Muxer) retransmitTables(force bool) (int, error) { - m.tablesRetransmitCounter++ - if !force && m.tablesRetransmitCounter < m.tablesRetransmitPeriod { - return 0, nil - } - - n, err := m.WriteTables() - if err != nil { - return n, err - } - - m.tablesRetransmitCounter = 0 - return n, nil -} - -func (m *Muxer) WriteTables() (int, error) { - bytesWritten := 0 - - if m.patBytes.Len() != m.packetSize { - if err := m.generatePAT(); err != nil { - return bytesWritten, err - } - } - - if m.pmtBytes.Len() != m.packetSize { - if err := m.generatePMT(); err != nil { - return bytesWritten, err - } - } - - n, err := m.w.Write(m.patBytes.Bytes()) - if err != nil { - return bytesWritten, err - } - bytesWritten += n - - n, err = m.w.Write(m.pmtBytes.Bytes()) - if err != nil { - return bytesWritten, err - } - bytesWritten += n - - return bytesWritten, nil -} - -func (m *Muxer) generatePAT() error { - d := m.pm.toPATData() - syntax := &PSISectionSyntax{ - Data: &PSISectionSyntaxData{PAT: d}, - Header: &PSISectionSyntaxHeader{ - CurrentNextIndicator: true, - // TODO support for PAT tables longer than 1 TS packet - //LastSectionNumber: 0, - //SectionNumber: 0, - TableIDExtension: d.TransportStreamID, - VersionNumber: uint8(m.patVersion.get()), - }, - } - section := PSISection{ - Header: &PSISectionHeader{ - SectionLength: calcPATSectionLength(d), - SectionSyntaxIndicator: true, - TableID: PSITableID(d.TransportStreamID), - }, - Syntax: syntax, - } - psiData := PSIData{ - Sections: []*PSISection{§ion}, - } - - m.buf.Reset() - w := astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &m.buf}) - if _, err := writePSIData(w, &psiData); err != nil { - return err - } - - m.patBytes.Reset() - wPacket := astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &m.patBytes}) - - pkt := Packet{ - Header: &PacketHeader{ - HasPayload: true, - PayloadUnitStartIndicator: true, - PID: PIDPAT, - }, - Payload: m.buf.Bytes(), - } - if _, err := writePacket(wPacket, &pkt, m.packetSize); err != nil { - // FIXME save old PAT and rollback to it here maybe? - return err - } - - return nil -} - -func (m *Muxer) generatePMT() error { - hasPCRPID := false - for _, es := range m.pmt.ElementaryStreams { - if es.ElementaryPID == m.pmt.PCRPID { - hasPCRPID = true - break - } - } - if !hasPCRPID { - return ErrPCRPIDInvalid - } - - syntax := &PSISectionSyntax{ - Data: &PSISectionSyntaxData{PMT: &m.pmt}, - Header: &PSISectionSyntaxHeader{ - CurrentNextIndicator: true, - // TODO support for PMT tables longer than 1 TS packet - //LastSectionNumber: 0, - //SectionNumber: 0, - TableIDExtension: m.pmt.ProgramNumber, - VersionNumber: uint8(m.pmtVersion.get()), - }, - } - section := PSISection{ - Header: &PSISectionHeader{ - SectionLength: calcPMTSectionLength(&m.pmt), - SectionSyntaxIndicator: true, - TableID: PSITableIDPMT, - }, - Syntax: syntax, - } - psiData := PSIData{ - Sections: []*PSISection{§ion}, - } - - m.buf.Reset() - w := astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &m.buf}) - if _, err := writePSIData(w, &psiData); err != nil { - return err - } - - m.pmtBytes.Reset() - wPacket := astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &m.pmtBytes}) - - pkt := Packet{ - Header: &PacketHeader{ - HasPayload: true, - PayloadUnitStartIndicator: true, - PID: pmtStartPID, // FIXME multiple programs support - }, - Payload: m.buf.Bytes(), - } - if _, err := writePacket(wPacket, &pkt, m.packetSize); err != nil { - // FIXME save old PMT and rollback to it here maybe? - return err - } - - return nil -} diff --git a/vendor/github.com/asticode/go-astits/packet.go b/vendor/github.com/asticode/go-astits/packet.go deleted file mode 100644 index c1261209f93..00000000000 --- a/vendor/github.com/asticode/go-astits/packet.go +++ /dev/null @@ -1,543 +0,0 @@ -package astits - -import ( - "fmt" - "github.com/asticode/go-astikit" -) - -// Scrambling Controls -const ( - ScramblingControlNotScrambled = 0 - ScramblingControlReservedForFutureUse = 1 - ScramblingControlScrambledWithEvenKey = 2 - ScramblingControlScrambledWithOddKey = 3 -) - -const ( - MpegTsPacketSize = 188 - mpegTsPacketHeaderSize = 3 - pcrBytesSize = 6 -) - -// Packet represents a packet -// https://en.wikipedia.org/wiki/MPEG_transport_stream -type Packet struct { - AdaptationField *PacketAdaptationField - Header *PacketHeader - Payload []byte // This is only the payload content -} - -// PacketHeader represents a packet header -type PacketHeader struct { - ContinuityCounter uint8 // Sequence number of payload packets (0x00 to 0x0F) within each stream (except PID 8191) - HasAdaptationField bool - HasPayload bool - PayloadUnitStartIndicator bool // Set when a PES, PSI, or DVB-MIP packet begins immediately following the header. - PID uint16 // Packet Identifier, describing the payload data. - TransportErrorIndicator bool // Set when a demodulator can't correct errors from FEC data; indicating the packet is corrupt. - TransportPriority bool // Set when the current packet has a higher priority than other packets with the same PID. - TransportScramblingControl uint8 -} - -// PacketAdaptationField represents a packet adaptation field -type PacketAdaptationField struct { - AdaptationExtensionField *PacketAdaptationExtensionField - DiscontinuityIndicator bool // Set if current TS packet is in a discontinuity state with respect to either the continuity counter or the program clock reference - ElementaryStreamPriorityIndicator bool // Set when this stream should be considered "high priority" - HasAdaptationExtensionField bool - HasOPCR bool - HasPCR bool - HasTransportPrivateData bool - HasSplicingCountdown bool - Length int - IsOneByteStuffing bool // Only used for one byte stuffing - if true, adaptation field will be written as one uint8(0). Not part of TS format - StuffingLength int // Only used in writePacketAdaptationField to request stuffing - OPCR *ClockReference // Original Program clock reference. Helps when one TS is copied into another - PCR *ClockReference // Program clock reference - RandomAccessIndicator bool // Set when the stream may be decoded without errors from this point - SpliceCountdown int // Indicates how many TS packets from this one a splicing point occurs (Two's complement signed; may be negative) - TransportPrivateDataLength int - TransportPrivateData []byte -} - -// PacketAdaptationExtensionField represents a packet adaptation extension field -type PacketAdaptationExtensionField struct { - DTSNextAccessUnit *ClockReference // The PES DTS of the splice point. Split up as 3 bits, 1 marker bit (0x1), 15 bits, 1 marker bit, 15 bits, and 1 marker bit, for 33 data bits total. - HasLegalTimeWindow bool - HasPiecewiseRate bool - HasSeamlessSplice bool - LegalTimeWindowIsValid bool - LegalTimeWindowOffset uint16 // Extra information for rebroadcasters to determine the state of buffers when packets may be missing. - Length int - PiecewiseRate uint32 // The rate of the stream, measured in 188-byte packets, to define the end-time of the LTW. - SpliceType uint8 // Indicates the parameters of the H.262 splice. -} - -// parsePacket parses a packet -func parsePacket(i *astikit.BytesIterator) (p *Packet, err error) { - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: getting next byte failed: %w", err) - return - } - - // Packet must start with a sync byte - if b != syncByte { - err = ErrPacketMustStartWithASyncByte - return - } - - // Create packet - p = &Packet{} - - // In case packet size is bigger than 188 bytes, we don't care for the first bytes - i.Seek(i.Len() - MpegTsPacketSize + 1) - offsetStart := i.Offset() - - // Parse header - if p.Header, err = parsePacketHeader(i); err != nil { - err = fmt.Errorf("astits: parsing packet header failed: %w", err) - return - } - - // Parse adaptation field - if p.Header.HasAdaptationField { - if p.AdaptationField, err = parsePacketAdaptationField(i); err != nil { - err = fmt.Errorf("astits: parsing packet adaptation field failed: %w", err) - return - } - } - - // Build payload - if p.Header.HasPayload { - i.Seek(payloadOffset(offsetStart, p.Header, p.AdaptationField)) - p.Payload = i.Dump() - } - return -} - -// payloadOffset returns the payload offset -func payloadOffset(offsetStart int, h *PacketHeader, a *PacketAdaptationField) (offset int) { - offset = offsetStart + 3 - if h.HasAdaptationField { - offset += 1 + a.Length - } - return -} - -// parsePacketHeader parses the packet header -func parsePacketHeader(i *astikit.BytesIterator) (h *PacketHeader, err error) { - // Get next bytes - var bs []byte - if bs, err = i.NextBytesNoCopy(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - - // Create header - h = &PacketHeader{ - ContinuityCounter: uint8(bs[2] & 0xf), - HasAdaptationField: bs[2]&0x20 > 0, - HasPayload: bs[2]&0x10 > 0, - PayloadUnitStartIndicator: bs[0]&0x40 > 0, - PID: uint16(bs[0]&0x1f)<<8 | uint16(bs[1]), - TransportErrorIndicator: bs[0]&0x80 > 0, - TransportPriority: bs[0]&0x20 > 0, - TransportScramblingControl: uint8(bs[2]) >> 6 & 0x3, - } - return -} - -// parsePacketAdaptationField parses the packet adaptation field -func parsePacketAdaptationField(i *astikit.BytesIterator) (a *PacketAdaptationField, err error) { - // Create adaptation field - a = &PacketAdaptationField{} - - // Get next byte - var b byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Length - a.Length = int(b) - - afStartOffset := i.Offset() - - // Valid length - if a.Length > 0 { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Flags - a.DiscontinuityIndicator = b&0x80 > 0 - a.RandomAccessIndicator = b&0x40 > 0 - a.ElementaryStreamPriorityIndicator = b&0x20 > 0 - a.HasPCR = b&0x10 > 0 - a.HasOPCR = b&0x08 > 0 - a.HasSplicingCountdown = b&0x04 > 0 - a.HasTransportPrivateData = b&0x02 > 0 - a.HasAdaptationExtensionField = b&0x01 > 0 - - // PCR - if a.HasPCR { - if a.PCR, err = parsePCR(i); err != nil { - err = fmt.Errorf("astits: parsing PCR failed: %w", err) - return - } - } - - // OPCR - if a.HasOPCR { - if a.OPCR, err = parsePCR(i); err != nil { - err = fmt.Errorf("astits: parsing PCR failed: %w", err) - return - } - } - - // Splicing countdown - if a.HasSplicingCountdown { - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - a.SpliceCountdown = int(b) - } - - // Transport private data - if a.HasTransportPrivateData { - // Length - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - a.TransportPrivateDataLength = int(b) - - // Data - if a.TransportPrivateDataLength > 0 { - if a.TransportPrivateData, err = i.NextBytes(a.TransportPrivateDataLength); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - } - } - - // Adaptation extension - if a.HasAdaptationExtensionField { - // Create extension field - a.AdaptationExtensionField = &PacketAdaptationExtensionField{} - - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Length - a.AdaptationExtensionField.Length = int(b) - if a.AdaptationExtensionField.Length > 0 { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Basic - a.AdaptationExtensionField.HasLegalTimeWindow = b&0x80 > 0 - a.AdaptationExtensionField.HasPiecewiseRate = b&0x40 > 0 - a.AdaptationExtensionField.HasSeamlessSplice = b&0x20 > 0 - - // Legal time window - if a.AdaptationExtensionField.HasLegalTimeWindow { - var bs []byte - if bs, err = i.NextBytesNoCopy(2); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - a.AdaptationExtensionField.LegalTimeWindowIsValid = bs[0]&0x80 > 0 - a.AdaptationExtensionField.LegalTimeWindowOffset = uint16(bs[0]&0x7f)<<8 | uint16(bs[1]) - } - - // Piecewise rate - if a.AdaptationExtensionField.HasPiecewiseRate { - var bs []byte - if bs, err = i.NextBytesNoCopy(3); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - a.AdaptationExtensionField.PiecewiseRate = uint32(bs[0]&0x3f)<<16 | uint32(bs[1])<<8 | uint32(bs[2]) - } - - // Seamless splice - if a.AdaptationExtensionField.HasSeamlessSplice { - // Get next byte - if b, err = i.NextByte(); err != nil { - err = fmt.Errorf("astits: fetching next byte failed: %w", err) - return - } - - // Splice type - a.AdaptationExtensionField.SpliceType = uint8(b&0xf0) >> 4 - - // We need to rewind since the current byte is used by the DTS next access unit as well - i.Skip(-1) - - // DTS Next access unit - if a.AdaptationExtensionField.DTSNextAccessUnit, err = parsePTSOrDTS(i); err != nil { - err = fmt.Errorf("astits: parsing DTS failed: %w", err) - return - } - } - } - } - } - - a.StuffingLength = a.Length - (i.Offset() - afStartOffset) - - return -} - -// parsePCR parses a Program Clock Reference -// Program clock reference, stored as 33 bits base, 6 bits reserved, 9 bits extension. -func parsePCR(i *astikit.BytesIterator) (cr *ClockReference, err error) { - var bs []byte - if bs, err = i.NextBytesNoCopy(6); err != nil { - err = fmt.Errorf("astits: fetching next bytes failed: %w", err) - return - } - pcr := uint64(bs[0])<<40 | uint64(bs[1])<<32 | uint64(bs[2])<<24 | uint64(bs[3])<<16 | uint64(bs[4])<<8 | uint64(bs[5]) - cr = newClockReference(int64(pcr>>15), int64(pcr&0x1ff)) - return -} - -func writePacket(w *astikit.BitsWriter, p *Packet, targetPacketSize int) (written int, retErr error) { - if retErr = w.Write(uint8(syncByte)); retErr != nil { - return - } - written += 1 - - n, retErr := writePacketHeader(w, p.Header) - if retErr != nil { - return - } - written += n - - if p.Header.HasAdaptationField { - n, retErr = writePacketAdaptationField(w, p.AdaptationField) - if retErr != nil { - return - } - written += n - } - - if targetPacketSize-written < len(p.Payload) { - return 0, fmt.Errorf( - "writePacket: can't write %d bytes of payload: only %d is available", - len(p.Payload), - targetPacketSize-written, - ) - } - - if p.Header.HasPayload { - retErr = w.Write(p.Payload) - if retErr != nil { - return - } - written += len(p.Payload) - } - - for written < targetPacketSize { - if retErr = w.Write(uint8(0xff)); retErr != nil { - return - } - written++ - } - - return written, nil -} - -func writePacketHeader(w *astikit.BitsWriter, h *PacketHeader) (written int, retErr error) { - b := astikit.NewBitsWriterBatch(w) - - b.Write(h.TransportErrorIndicator) - b.Write(h.PayloadUnitStartIndicator) - b.Write(h.TransportPriority) - b.WriteN(h.PID, 13) - b.WriteN(h.TransportScramblingControl, 2) - b.Write(h.HasAdaptationField) // adaptation_field_control higher bit - b.Write(h.HasPayload) // adaptation_field_control lower bit - b.WriteN(h.ContinuityCounter, 4) - - return mpegTsPacketHeaderSize, b.Err() -} - -func writePCR(w *astikit.BitsWriter, cr *ClockReference) (int, error) { - b := astikit.NewBitsWriterBatch(w) - - b.WriteN(uint64(cr.Base), 33) - b.WriteN(uint8(0xff), 6) - b.WriteN(uint64(cr.Extension), 9) - return pcrBytesSize, b.Err() -} - -func calcPacketAdaptationFieldLength(af *PacketAdaptationField) (length uint8) { - length++ - if af.HasPCR { - length += pcrBytesSize - } - if af.HasOPCR { - length += pcrBytesSize - } - if af.HasSplicingCountdown { - length++ - } - if af.HasTransportPrivateData { - length += 1 + uint8(len(af.TransportPrivateData)) - } - if af.HasAdaptationExtensionField { - length += 1 + calcPacketAdaptationFieldExtensionLength(af.AdaptationExtensionField) - } - length += uint8(af.StuffingLength) - return -} - -func writePacketAdaptationField(w *astikit.BitsWriter, af *PacketAdaptationField) (bytesWritten int, retErr error) { - b := astikit.NewBitsWriterBatch(w) - - if af.IsOneByteStuffing { - b.Write(uint8(0)) - return 1, nil - } - - length := calcPacketAdaptationFieldLength(af) - b.Write(length) - bytesWritten++ - - b.Write(af.DiscontinuityIndicator) - b.Write(af.RandomAccessIndicator) - b.Write(af.ElementaryStreamPriorityIndicator) - b.Write(af.HasPCR) - b.Write(af.HasOPCR) - b.Write(af.HasSplicingCountdown) - b.Write(af.HasTransportPrivateData) - b.Write(af.HasAdaptationExtensionField) - - bytesWritten++ - - if af.HasPCR { - n, err := writePCR(w, af.PCR) - if err != nil { - return 0, err - } - bytesWritten += n - } - - if af.HasOPCR { - n, err := writePCR(w, af.OPCR) - if err != nil { - return 0, err - } - bytesWritten += n - } - - if af.HasSplicingCountdown { - b.Write(uint8(af.SpliceCountdown)) - bytesWritten++ - } - - if af.HasTransportPrivateData { - // we can get length from TransportPrivateData itself, why do we need separate field? - b.Write(uint8(af.TransportPrivateDataLength)) - bytesWritten++ - if af.TransportPrivateDataLength > 0 { - b.Write(af.TransportPrivateData) - } - bytesWritten += len(af.TransportPrivateData) - } - - if af.HasAdaptationExtensionField { - n, err := writePacketAdaptationFieldExtension(w, af.AdaptationExtensionField) - if err != nil { - return 0, err - } - bytesWritten += n - } - - // stuffing - for i := 0; i < af.StuffingLength; i++ { - b.Write(uint8(0xff)) - bytesWritten++ - } - - retErr = b.Err() - return -} - -func calcPacketAdaptationFieldExtensionLength(afe *PacketAdaptationExtensionField) (length uint8) { - length++ - if afe.HasLegalTimeWindow { - length += 2 - } - if afe.HasPiecewiseRate { - length += 3 - } - if afe.HasSeamlessSplice { - length += ptsOrDTSByteLength - } - return length -} - -func writePacketAdaptationFieldExtension(w *astikit.BitsWriter, afe *PacketAdaptationExtensionField) (bytesWritten int, retErr error) { - b := astikit.NewBitsWriterBatch(w) - - length := calcPacketAdaptationFieldExtensionLength(afe) - b.Write(length) - bytesWritten++ - - b.Write(afe.HasLegalTimeWindow) - b.Write(afe.HasPiecewiseRate) - b.Write(afe.HasSeamlessSplice) - b.WriteN(uint8(0xff), 5) // reserved - bytesWritten++ - - if afe.HasLegalTimeWindow { - b.Write(afe.LegalTimeWindowIsValid) - b.WriteN(afe.LegalTimeWindowOffset, 15) - bytesWritten += 2 - } - - if afe.HasPiecewiseRate { - b.WriteN(uint8(0xff), 2) - b.WriteN(afe.PiecewiseRate, 22) - bytesWritten += 3 - } - - if afe.HasSeamlessSplice { - n, err := writePTSOrDTS(w, afe.SpliceType, afe.DTSNextAccessUnit) - if err != nil { - return 0, err - } - bytesWritten += n - } - - retErr = b.Err() - return -} - -func newStuffingAdaptationField(bytesToStuff int) *PacketAdaptationField { - if bytesToStuff == 1 { - return &PacketAdaptationField{ - IsOneByteStuffing: true, - } - } - - return &PacketAdaptationField{ - // one byte for length and one for flags - StuffingLength: bytesToStuff - 2, - } -} diff --git a/vendor/github.com/asticode/go-astits/packet_buffer.go b/vendor/github.com/asticode/go-astits/packet_buffer.go deleted file mode 100644 index db3cf3ade0c..00000000000 --- a/vendor/github.com/asticode/go-astits/packet_buffer.go +++ /dev/null @@ -1,139 +0,0 @@ -package astits - -import ( - "bufio" - "fmt" - "io" - - "github.com/asticode/go-astikit" -) - -// packetBuffer represents a packet buffer -type packetBuffer struct { - packetSize int - r io.Reader - packetReadBuffer []byte -} - -// newPacketBuffer creates a new packet buffer -func newPacketBuffer(r io.Reader, packetSize int) (pb *packetBuffer, err error) { - // Init - pb = &packetBuffer{ - packetSize: packetSize, - r: r, - } - - // Packet size is not set - if pb.packetSize == 0 { - // Auto detect packet size - if pb.packetSize, err = autoDetectPacketSize(r); err != nil { - err = fmt.Errorf("astits: auto detecting packet size failed: %w", err) - return - } - } - return -} - -// autoDetectPacketSize updates the packet size based on the first bytes -// Minimum packet size is 188 and is bounded by 2 sync bytes -// Assumption is made that the first byte of the reader is a sync byte -func autoDetectPacketSize(r io.Reader) (packetSize int, err error) { - // Read first bytes - const l = 193 - var b = make([]byte, l) - shouldRewind, rerr := peek(r, b) - if rerr != nil { - err = fmt.Errorf("astits: reading first %d bytes failed: %w", l, rerr) - return - } - - // Packet must start with a sync byte - if b[0] != syncByte { - err = ErrPacketMustStartWithASyncByte - return - } - - // Look for sync bytes - for idx, b := range b { - if b == syncByte && idx >= MpegTsPacketSize { - // Update packet size - packetSize = idx - - if !shouldRewind { - return - } - - // Rewind or sync reader - var n int64 - if n, err = rewind(r); err != nil { - err = fmt.Errorf("astits: rewinding failed: %w", err) - return - } else if n == -1 { - var ls = packetSize - (l - packetSize) - if _, err = r.Read(make([]byte, ls)); err != nil { - err = fmt.Errorf("astits: reading %d bytes to sync reader failed: %w", ls, err) - return - } - } - return - } - } - err = fmt.Errorf("astits: only one sync byte detected in first %d bytes", l) - return -} - -// bufio.Reader can't be rewinded, which leads to packet loss on packet size autodetection -// but it has handy Peek() method -// so what we do here is peeking bytes for bufio.Reader and falling back to rewinding/syncing for all other readers -func peek(r io.Reader, b []byte) (shouldRewind bool, err error) { - if br, ok := r.(*bufio.Reader); ok { - var bs []byte - bs, err = br.Peek(len(b)) - if err != nil { - return - } - copy(b, bs) - return false, nil - } - - _, err = r.Read(b) - shouldRewind = true - return -} - -// rewind rewinds the reader if possible, otherwise n = -1 -func rewind(r io.Reader) (n int64, err error) { - if s, ok := r.(io.Seeker); ok { - if n, err = s.Seek(0, 0); err != nil { - err = fmt.Errorf("astits: seeking to 0 failed: %w", err) - return - } - return - } - n = -1 - return -} - -// next fetches the next packet from the buffer -func (pb *packetBuffer) next() (p *Packet, err error) { - // Read - if pb.packetReadBuffer == nil || len(pb.packetReadBuffer) != pb.packetSize { - pb.packetReadBuffer = make([]byte, pb.packetSize) - } - - if _, err = io.ReadFull(pb.r, pb.packetReadBuffer); err != nil { - if err == io.EOF || err == io.ErrUnexpectedEOF { - err = ErrNoMorePackets - } else { - err = fmt.Errorf("astits: reading %d bytes failed: %w", pb.packetSize, err) - } - return - } - - // Parse packet - if p, err = parsePacket(astikit.NewBytesIterator(pb.packetReadBuffer)); err != nil { - err = fmt.Errorf("astits: building packet failed: %w", err) - return - } - return -} diff --git a/vendor/github.com/asticode/go-astits/packet_pool.go b/vendor/github.com/asticode/go-astits/packet_pool.go deleted file mode 100644 index d38750ad7b7..00000000000 --- a/vendor/github.com/asticode/go-astits/packet_pool.go +++ /dev/null @@ -1,101 +0,0 @@ -package astits - -import ( - "sort" - "sync" -) - -// packetPool represents a pool of packets -type packetPool struct { - b map[uint16][]*Packet // Indexed by PID - m *sync.Mutex -} - -// newPacketPool creates a new packet pool -func newPacketPool() *packetPool { - return &packetPool{ - b: make(map[uint16][]*Packet), - m: &sync.Mutex{}, - } -} - -// add adds a new packet to the pool -func (b *packetPool) add(p *Packet) (ps []*Packet) { - // Throw away packet if error indicator - if p.Header.TransportErrorIndicator { - return - } - - // Throw away packets that don't have a payload until we figure out what we're going to do with them - // TODO figure out what we're going to do with them :D - if !p.Header.HasPayload { - return - } - - // Lock - b.m.Lock() - defer b.m.Unlock() - - // Init buffer - var mps []*Packet - var ok bool - if mps, ok = b.b[p.Header.PID]; !ok { - mps = []*Packet{} - } - - // Empty buffer if we detect a discontinuity - if hasDiscontinuity(mps, p) { - mps = []*Packet{} - } - - // Throw away packet if it's the same as the previous one - if isSameAsPrevious(mps, p) { - return - } - - // Add packet - if len(mps) > 0 || (len(mps) == 0 && p.Header.PayloadUnitStartIndicator) { - mps = append(mps, p) - } - - // Check payload unit start indicator - if p.Header.PayloadUnitStartIndicator && len(mps) > 1 { - ps = mps[:len(mps)-1] - mps = []*Packet{p} - } - - // Assign - b.b[p.Header.PID] = mps - return -} - -// dump dumps the packet pool by looking for the first item with packets inside -func (b *packetPool) dump() (ps []*Packet) { - b.m.Lock() - defer b.m.Unlock() - var keys []int - for k := range b.b { - keys = append(keys, int(k)) - } - sort.Ints(keys) - for _, k := range keys { - ps = b.b[uint16(k)] - delete(b.b, uint16(k)) - if len(ps) > 0 { - return - } - } - return -} - -// hasDiscontinuity checks whether a packet is discontinuous with a set of packets -func hasDiscontinuity(ps []*Packet, p *Packet) bool { - return (p.Header.HasAdaptationField && p.AdaptationField.DiscontinuityIndicator) || - (len(ps) > 0 && p.Header.HasPayload && p.Header.ContinuityCounter != (ps[len(ps)-1].Header.ContinuityCounter+1)%16) || - (len(ps) > 0 && !p.Header.HasPayload && p.Header.ContinuityCounter != ps[len(ps)-1].Header.ContinuityCounter) -} - -// isSameAsPrevious checks whether a packet is the same as the last packet of a set of packets -func isSameAsPrevious(ps []*Packet, p *Packet) bool { - return len(ps) > 0 && p.Header.HasPayload && p.Header.ContinuityCounter == ps[len(ps)-1].Header.ContinuityCounter -} diff --git a/vendor/github.com/asticode/go-astits/program_map.go b/vendor/github.com/asticode/go-astits/program_map.go deleted file mode 100644 index 855f2d70fa7..00000000000 --- a/vendor/github.com/asticode/go-astits/program_map.go +++ /dev/null @@ -1,57 +0,0 @@ -package astits - -import "sync" - -// programMap represents a program ids map -type programMap struct { - m *sync.Mutex - p map[uint16]uint16 // map[ProgramMapID]ProgramNumber -} - -// newProgramMap creates a new program ids map -func newProgramMap() programMap { - return programMap{ - m: &sync.Mutex{}, - p: make(map[uint16]uint16), - } -} - -// exists checks whether the program with this pid exists -func (m programMap) exists(pid uint16) (ok bool) { - m.m.Lock() - defer m.m.Unlock() - _, ok = m.p[pid] - return -} - -// set sets a new program id -func (m programMap) set(pid, number uint16) { - m.m.Lock() - defer m.m.Unlock() - m.p[pid] = number -} - -func (m programMap) unset(pid uint16) { - m.m.Lock() - defer m.m.Unlock() - delete(m.p, pid) -} - -func (m programMap) toPATData() *PATData { - m.m.Lock() - defer m.m.Unlock() - - d := &PATData{ - Programs: []*PATProgram{}, - TransportStreamID: uint16(PSITableIDPAT), - } - - for pid, pnr := range m.p { - d.Programs = append(d.Programs, &PATProgram{ - ProgramMapID: pid, - ProgramNumber: pnr, - }) - } - - return d -} diff --git a/vendor/github.com/asticode/go-astits/wrapping_counter.go b/vendor/github.com/asticode/go-astits/wrapping_counter.go deleted file mode 100644 index 025bc4ffab4..00000000000 --- a/vendor/github.com/asticode/go-astits/wrapping_counter.go +++ /dev/null @@ -1,22 +0,0 @@ -package astits - -type wrappingCounter struct { - wrapAt int - value int -} - -func newWrappingCounter(wrapAt int) wrappingCounter { - return wrappingCounter{ - wrapAt: wrapAt, - } -} - -// returns current counter state and increments internal value -func (c *wrappingCounter) get() int { - ret := c.value - c.value++ - if c.value > c.wrapAt { - c.value = 0 - } - return ret -} diff --git a/vendor/github.com/chromedp/cdproto/.gitignore b/vendor/github.com/chromedp/cdproto/.gitignore deleted file mode 100644 index c456f53275d..00000000000 --- a/vendor/github.com/chromedp/cdproto/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.json -*.pdl diff --git a/vendor/github.com/chromedp/cdproto/LICENSE b/vendor/github.com/chromedp/cdproto/LICENSE deleted file mode 100644 index 323e87a9315..00000000000 --- a/vendor/github.com/chromedp/cdproto/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2021 Kenneth Shaw - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/chromedp/cdproto/README.md b/vendor/github.com/chromedp/cdproto/README.md deleted file mode 100644 index a21f77cac6e..00000000000 --- a/vendor/github.com/chromedp/cdproto/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# About cdproto - -Package `cdproto` contains the generated commands, types, and events for the -[Chrome DevTools Protocol domains][devtools-protocol]. - -[![Unit Tests][cdproto-ci-status]][cdproto-ci] -[![Go Reference][goref-cdproto-status]][goref-cdproto] - -This package is generated by the [`cdproto-gen`][cdproto-gen] command. Please -refer to that project and to the main [`chromedp`][chromedp] project for -information on using the commands, types, and events available here. - -## API - -Please see the [Go Reference][goref-cdproto]. - -## Contributing - -If you would like to submit a change to the code in this package, please submit -your Pull Request to the [`cdproto-gen`][cdproto-gen] project. Any Issues and -Pull Requests submitted to this project will be closed without being reviewed. - -[cdproto-ci]: https://github.com/chromedp/cdproto/actions/workflows/build.yml (Build CI) -[cdproto-ci-status]: https://github.com/chromedp/cdproto/actions/workflows/build.yml/badge.svg (Build CI) -[cdproto-gen]: https://github.com/chromedp/cdproto-gen -[chromedp]: https://github.com/chromedp/chromedp -[devtools-protocol]: https://chromedevtools.github.io/devtools-protocol/ -[goref-cdproto]: https://pkg.go.dev/github.com/chromedp/cdproto -[goref-cdproto-status]: https://pkg.go.dev/badge/github.com/chromedp/chromedp.svg diff --git a/vendor/github.com/chromedp/cdproto/accessibility/accessibility.go b/vendor/github.com/chromedp/cdproto/accessibility/accessibility.go deleted file mode 100644 index 7ac2eea0ec9..00000000000 --- a/vendor/github.com/chromedp/cdproto/accessibility/accessibility.go +++ /dev/null @@ -1,287 +0,0 @@ -// Package accessibility provides the Chrome DevTools Protocol -// commands, types, and events for the Accessibility domain. -// -// Generated by the cdproto-gen command. -package accessibility - -// Code generated by cdproto-gen. DO NOT EDIT. - -import ( - "context" - - "github.com/chromedp/cdproto/cdp" - "github.com/chromedp/cdproto/runtime" -) - -// DisableParams disables the accessibility domain. -type DisableParams struct{} - -// Disable disables the accessibility domain. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-disable -func Disable() *DisableParams { - return &DisableParams{} -} - -// Do executes Accessibility.disable against the provided context. -func (p *DisableParams) Do(ctx context.Context) (err error) { - return cdp.Execute(ctx, CommandDisable, nil, nil) -} - -// EnableParams enables the accessibility domain which causes AXNodeIds to -// remain consistent between method calls. This turns on accessibility for the -// page, which can impact performance until accessibility is disabled. -type EnableParams struct{} - -// Enable enables the accessibility domain which causes AXNodeIds to remain -// consistent between method calls. This turns on accessibility for the page, -// which can impact performance until accessibility is disabled. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-enable -func Enable() *EnableParams { - return &EnableParams{} -} - -// Do executes Accessibility.enable against the provided context. -func (p *EnableParams) Do(ctx context.Context) (err error) { - return cdp.Execute(ctx, CommandEnable, nil, nil) -} - -// GetPartialAXTreeParams fetches the accessibility node and partial -// accessibility tree for this DOM node, if it exists. -type GetPartialAXTreeParams struct { - NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node to get the partial accessibility tree for. - BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node to get the partial accessibility tree for. - ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper to get the partial accessibility tree for. - FetchRelatives bool `json:"fetchRelatives,omitempty"` // Whether to fetch this nodes ancestors, siblings and children. Defaults to true. -} - -// GetPartialAXTree fetches the accessibility node and partial accessibility -// tree for this DOM node, if it exists. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getPartialAXTree -// -// parameters: -func GetPartialAXTree() *GetPartialAXTreeParams { - return &GetPartialAXTreeParams{} -} - -// WithNodeID identifier of the node to get the partial accessibility tree -// for. -func (p GetPartialAXTreeParams) WithNodeID(nodeID cdp.NodeID) *GetPartialAXTreeParams { - p.NodeID = nodeID - return &p -} - -// WithBackendNodeID identifier of the backend node to get the partial -// accessibility tree for. -func (p GetPartialAXTreeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetPartialAXTreeParams { - p.BackendNodeID = backendNodeID - return &p -} - -// WithObjectID JavaScript object id of the node wrapper to get the partial -// accessibility tree for. -func (p GetPartialAXTreeParams) WithObjectID(objectID runtime.RemoteObjectID) *GetPartialAXTreeParams { - p.ObjectID = objectID - return &p -} - -// WithFetchRelatives whether to fetch this nodes ancestors, siblings and -// children. Defaults to true. -func (p GetPartialAXTreeParams) WithFetchRelatives(fetchRelatives bool) *GetPartialAXTreeParams { - p.FetchRelatives = fetchRelatives - return &p -} - -// GetPartialAXTreeReturns return values. -type GetPartialAXTreeReturns struct { - Nodes []*Node `json:"nodes,omitempty"` // The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested. -} - -// Do executes Accessibility.getPartialAXTree against the provided context. -// -// returns: -// nodes - The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested. -func (p *GetPartialAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) { - // execute - var res GetPartialAXTreeReturns - err = cdp.Execute(ctx, CommandGetPartialAXTree, p, &res) - if err != nil { - return nil, err - } - - return res.Nodes, nil -} - -// GetFullAXTreeParams fetches the entire accessibility tree for the root -// Document. -type GetFullAXTreeParams struct { - MaxDepth int64 `json:"max_depth,omitempty"` // The maximum depth at which descendants of the root node should be retrieved. If omitted, the full tree is returned. -} - -// GetFullAXTree fetches the entire accessibility tree for the root Document. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getFullAXTree -// -// parameters: -func GetFullAXTree() *GetFullAXTreeParams { - return &GetFullAXTreeParams{} -} - -// WithMaxDepth the maximum depth at which descendants of the root node -// should be retrieved. If omitted, the full tree is returned. -func (p GetFullAXTreeParams) WithMaxDepth(maxDepth int64) *GetFullAXTreeParams { - p.MaxDepth = maxDepth - return &p -} - -// GetFullAXTreeReturns return values. -type GetFullAXTreeReturns struct { - Nodes []*Node `json:"nodes,omitempty"` -} - -// Do executes Accessibility.getFullAXTree against the provided context. -// -// returns: -// nodes -func (p *GetFullAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) { - // execute - var res GetFullAXTreeReturns - err = cdp.Execute(ctx, CommandGetFullAXTree, p, &res) - if err != nil { - return nil, err - } - - return res.Nodes, nil -} - -// GetChildAXNodesParams fetches a particular accessibility node by AXNodeId. -// Requires enable() to have been called previously. -type GetChildAXNodesParams struct { - ID NodeID `json:"id"` -} - -// GetChildAXNodes fetches a particular accessibility node by AXNodeId. -// Requires enable() to have been called previously. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getChildAXNodes -// -// parameters: -// id -func GetChildAXNodes(id NodeID) *GetChildAXNodesParams { - return &GetChildAXNodesParams{ - ID: id, - } -} - -// GetChildAXNodesReturns return values. -type GetChildAXNodesReturns struct { - Nodes []*Node `json:"nodes,omitempty"` -} - -// Do executes Accessibility.getChildAXNodes against the provided context. -// -// returns: -// nodes -func (p *GetChildAXNodesParams) Do(ctx context.Context) (nodes []*Node, err error) { - // execute - var res GetChildAXNodesReturns - err = cdp.Execute(ctx, CommandGetChildAXNodes, p, &res) - if err != nil { - return nil, err - } - - return res.Nodes, nil -} - -// QueryAXTreeParams query a DOM node's accessibility subtree for accessible -// name and role. This command computes the name and role for all nodes in the -// subtree, including those that are ignored for accessibility, and returns -// those that mactch the specified name and role. If no DOM node is specified, -// or the DOM node does not exist, the command returns an error. If neither -// accessibleName or role is specified, it returns all the accessibility nodes -// in the subtree. -type QueryAXTreeParams struct { - NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node for the root to query. - BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node for the root to query. - ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper for the root to query. - AccessibleName string `json:"accessibleName,omitempty"` // Find nodes with this computed name. - Role string `json:"role,omitempty"` // Find nodes with this computed role. -} - -// QueryAXTree query a DOM node's accessibility subtree for accessible name -// and role. This command computes the name and role for all nodes in the -// subtree, including those that are ignored for accessibility, and returns -// those that mactch the specified name and role. If no DOM node is specified, -// or the DOM node does not exist, the command returns an error. If neither -// accessibleName or role is specified, it returns all the accessibility nodes -// in the subtree. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-queryAXTree -// -// parameters: -func QueryAXTree() *QueryAXTreeParams { - return &QueryAXTreeParams{} -} - -// WithNodeID identifier of the node for the root to query. -func (p QueryAXTreeParams) WithNodeID(nodeID cdp.NodeID) *QueryAXTreeParams { - p.NodeID = nodeID - return &p -} - -// WithBackendNodeID identifier of the backend node for the root to query. -func (p QueryAXTreeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *QueryAXTreeParams { - p.BackendNodeID = backendNodeID - return &p -} - -// WithObjectID JavaScript object id of the node wrapper for the root to -// query. -func (p QueryAXTreeParams) WithObjectID(objectID runtime.RemoteObjectID) *QueryAXTreeParams { - p.ObjectID = objectID - return &p -} - -// WithAccessibleName find nodes with this computed name. -func (p QueryAXTreeParams) WithAccessibleName(accessibleName string) *QueryAXTreeParams { - p.AccessibleName = accessibleName - return &p -} - -// WithRole find nodes with this computed role. -func (p QueryAXTreeParams) WithRole(role string) *QueryAXTreeParams { - p.Role = role - return &p -} - -// QueryAXTreeReturns return values. -type QueryAXTreeReturns struct { - Nodes []*Node `json:"nodes,omitempty"` // A list of Accessibility.AXNode matching the specified attributes, including nodes that are ignored for accessibility. -} - -// Do executes Accessibility.queryAXTree against the provided context. -// -// returns: -// nodes - A list of Accessibility.AXNode matching the specified attributes, including nodes that are ignored for accessibility. -func (p *QueryAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) { - // execute - var res QueryAXTreeReturns - err = cdp.Execute(ctx, CommandQueryAXTree, p, &res) - if err != nil { - return nil, err - } - - return res.Nodes, nil -} - -// Command names. -const ( - CommandDisable = "Accessibility.disable" - CommandEnable = "Accessibility.enable" - CommandGetPartialAXTree = "Accessibility.getPartialAXTree" - CommandGetFullAXTree = "Accessibility.getFullAXTree" - CommandGetChildAXNodes = "Accessibility.getChildAXNodes" - CommandQueryAXTree = "Accessibility.queryAXTree" -) diff --git a/vendor/github.com/chromedp/cdproto/accessibility/easyjson.go b/vendor/github.com/chromedp/cdproto/accessibility/easyjson.go deleted file mode 100644 index cf868d2873a..00000000000 --- a/vendor/github.com/chromedp/cdproto/accessibility/easyjson.go +++ /dev/null @@ -1,1682 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package accessibility - -import ( - json "encoding/json" - runtime "github.com/chromedp/cdproto/runtime" - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility(in *jlexer.Lexer, out *ValueSource) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "type": - (out.Type).UnmarshalEasyJSON(in) - case "value": - if in.IsNull() { - in.Skip() - out.Value = nil - } else { - if out.Value == nil { - out.Value = new(Value) - } - (*out.Value).UnmarshalEasyJSON(in) - } - case "attribute": - out.Attribute = string(in.String()) - case "attributeValue": - if in.IsNull() { - in.Skip() - out.AttributeValue = nil - } else { - if out.AttributeValue == nil { - out.AttributeValue = new(Value) - } - (*out.AttributeValue).UnmarshalEasyJSON(in) - } - case "superseded": - out.Superseded = bool(in.Bool()) - case "nativeSource": - (out.NativeSource).UnmarshalEasyJSON(in) - case "nativeSourceValue": - if in.IsNull() { - in.Skip() - out.NativeSourceValue = nil - } else { - if out.NativeSourceValue == nil { - out.NativeSourceValue = new(Value) - } - (*out.NativeSourceValue).UnmarshalEasyJSON(in) - } - case "invalid": - out.Invalid = bool(in.Bool()) - case "invalidReason": - out.InvalidReason = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility(out *jwriter.Writer, in ValueSource) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"type\":" - out.RawString(prefix[1:]) - (in.Type).MarshalEasyJSON(out) - } - if in.Value != nil { - const prefix string = ",\"value\":" - out.RawString(prefix) - (*in.Value).MarshalEasyJSON(out) - } - if in.Attribute != "" { - const prefix string = ",\"attribute\":" - out.RawString(prefix) - out.String(string(in.Attribute)) - } - if in.AttributeValue != nil { - const prefix string = ",\"attributeValue\":" - out.RawString(prefix) - (*in.AttributeValue).MarshalEasyJSON(out) - } - if in.Superseded { - const prefix string = ",\"superseded\":" - out.RawString(prefix) - out.Bool(bool(in.Superseded)) - } - if in.NativeSource != "" { - const prefix string = ",\"nativeSource\":" - out.RawString(prefix) - (in.NativeSource).MarshalEasyJSON(out) - } - if in.NativeSourceValue != nil { - const prefix string = ",\"nativeSourceValue\":" - out.RawString(prefix) - (*in.NativeSourceValue).MarshalEasyJSON(out) - } - if in.Invalid { - const prefix string = ",\"invalid\":" - out.RawString(prefix) - out.Bool(bool(in.Invalid)) - } - if in.InvalidReason != "" { - const prefix string = ",\"invalidReason\":" - out.RawString(prefix) - out.String(string(in.InvalidReason)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v ValueSource) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v ValueSource) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *ValueSource) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *ValueSource) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility1(in *jlexer.Lexer, out *Value) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "type": - (out.Type).UnmarshalEasyJSON(in) - case "value": - (out.Value).UnmarshalEasyJSON(in) - case "relatedNodes": - if in.IsNull() { - in.Skip() - out.RelatedNodes = nil - } else { - in.Delim('[') - if out.RelatedNodes == nil { - if !in.IsDelim(']') { - out.RelatedNodes = make([]*RelatedNode, 0, 8) - } else { - out.RelatedNodes = []*RelatedNode{} - } - } else { - out.RelatedNodes = (out.RelatedNodes)[:0] - } - for !in.IsDelim(']') { - var v1 *RelatedNode - if in.IsNull() { - in.Skip() - v1 = nil - } else { - if v1 == nil { - v1 = new(RelatedNode) - } - (*v1).UnmarshalEasyJSON(in) - } - out.RelatedNodes = append(out.RelatedNodes, v1) - in.WantComma() - } - in.Delim(']') - } - case "sources": - if in.IsNull() { - in.Skip() - out.Sources = nil - } else { - in.Delim('[') - if out.Sources == nil { - if !in.IsDelim(']') { - out.Sources = make([]*ValueSource, 0, 8) - } else { - out.Sources = []*ValueSource{} - } - } else { - out.Sources = (out.Sources)[:0] - } - for !in.IsDelim(']') { - var v2 *ValueSource - if in.IsNull() { - in.Skip() - v2 = nil - } else { - if v2 == nil { - v2 = new(ValueSource) - } - (*v2).UnmarshalEasyJSON(in) - } - out.Sources = append(out.Sources, v2) - in.WantComma() - } - in.Delim(']') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility1(out *jwriter.Writer, in Value) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"type\":" - out.RawString(prefix[1:]) - (in.Type).MarshalEasyJSON(out) - } - if (in.Value).IsDefined() { - const prefix string = ",\"value\":" - out.RawString(prefix) - (in.Value).MarshalEasyJSON(out) - } - if len(in.RelatedNodes) != 0 { - const prefix string = ",\"relatedNodes\":" - out.RawString(prefix) - { - out.RawByte('[') - for v3, v4 := range in.RelatedNodes { - if v3 > 0 { - out.RawByte(',') - } - if v4 == nil { - out.RawString("null") - } else { - (*v4).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - if len(in.Sources) != 0 { - const prefix string = ",\"sources\":" - out.RawString(prefix) - { - out.RawByte('[') - for v5, v6 := range in.Sources { - if v5 > 0 { - out.RawByte(',') - } - if v6 == nil { - out.RawString("null") - } else { - (*v6).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v Value) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility1(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v Value) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility1(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *Value) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility1(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Value) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility1(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility2(in *jlexer.Lexer, out *RelatedNode) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "backendDOMNodeId": - (out.BackendDOMNodeID).UnmarshalEasyJSON(in) - case "idref": - out.Idref = string(in.String()) - case "text": - out.Text = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility2(out *jwriter.Writer, in RelatedNode) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"backendDOMNodeId\":" - out.RawString(prefix[1:]) - out.Int64(int64(in.BackendDOMNodeID)) - } - if in.Idref != "" { - const prefix string = ",\"idref\":" - out.RawString(prefix) - out.String(string(in.Idref)) - } - if in.Text != "" { - const prefix string = ",\"text\":" - out.RawString(prefix) - out.String(string(in.Text)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v RelatedNode) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility2(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v RelatedNode) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility2(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *RelatedNode) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility2(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *RelatedNode) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility2(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility3(in *jlexer.Lexer, out *QueryAXTreeReturns) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodes": - if in.IsNull() { - in.Skip() - out.Nodes = nil - } else { - in.Delim('[') - if out.Nodes == nil { - if !in.IsDelim(']') { - out.Nodes = make([]*Node, 0, 8) - } else { - out.Nodes = []*Node{} - } - } else { - out.Nodes = (out.Nodes)[:0] - } - for !in.IsDelim(']') { - var v7 *Node - if in.IsNull() { - in.Skip() - v7 = nil - } else { - if v7 == nil { - v7 = new(Node) - } - (*v7).UnmarshalEasyJSON(in) - } - out.Nodes = append(out.Nodes, v7) - in.WantComma() - } - in.Delim(']') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility3(out *jwriter.Writer, in QueryAXTreeReturns) { - out.RawByte('{') - first := true - _ = first - if len(in.Nodes) != 0 { - const prefix string = ",\"nodes\":" - first = false - out.RawString(prefix[1:]) - { - out.RawByte('[') - for v8, v9 := range in.Nodes { - if v8 > 0 { - out.RawByte(',') - } - if v9 == nil { - out.RawString("null") - } else { - (*v9).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v QueryAXTreeReturns) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility3(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v QueryAXTreeReturns) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility3(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *QueryAXTreeReturns) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility3(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *QueryAXTreeReturns) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility3(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility4(in *jlexer.Lexer, out *QueryAXTreeParams) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodeId": - (out.NodeID).UnmarshalEasyJSON(in) - case "backendNodeId": - (out.BackendNodeID).UnmarshalEasyJSON(in) - case "objectId": - out.ObjectID = runtime.RemoteObjectID(in.String()) - case "accessibleName": - out.AccessibleName = string(in.String()) - case "role": - out.Role = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility4(out *jwriter.Writer, in QueryAXTreeParams) { - out.RawByte('{') - first := true - _ = first - if in.NodeID != 0 { - const prefix string = ",\"nodeId\":" - first = false - out.RawString(prefix[1:]) - out.Int64(int64(in.NodeID)) - } - if in.BackendNodeID != 0 { - const prefix string = ",\"backendNodeId\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int64(int64(in.BackendNodeID)) - } - if in.ObjectID != "" { - const prefix string = ",\"objectId\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.ObjectID)) - } - if in.AccessibleName != "" { - const prefix string = ",\"accessibleName\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.AccessibleName)) - } - if in.Role != "" { - const prefix string = ",\"role\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Role)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v QueryAXTreeParams) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility4(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v QueryAXTreeParams) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility4(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *QueryAXTreeParams) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility4(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *QueryAXTreeParams) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility4(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility5(in *jlexer.Lexer, out *Property) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "name": - (out.Name).UnmarshalEasyJSON(in) - case "value": - if in.IsNull() { - in.Skip() - out.Value = nil - } else { - if out.Value == nil { - out.Value = new(Value) - } - (*out.Value).UnmarshalEasyJSON(in) - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility5(out *jwriter.Writer, in Property) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"name\":" - out.RawString(prefix[1:]) - (in.Name).MarshalEasyJSON(out) - } - { - const prefix string = ",\"value\":" - out.RawString(prefix) - if in.Value == nil { - out.RawString("null") - } else { - (*in.Value).MarshalEasyJSON(out) - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v Property) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility5(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v Property) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility5(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *Property) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility5(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Property) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility5(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility6(in *jlexer.Lexer, out *Node) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodeId": - out.NodeID = NodeID(in.String()) - case "ignored": - out.Ignored = bool(in.Bool()) - case "ignoredReasons": - if in.IsNull() { - in.Skip() - out.IgnoredReasons = nil - } else { - in.Delim('[') - if out.IgnoredReasons == nil { - if !in.IsDelim(']') { - out.IgnoredReasons = make([]*Property, 0, 8) - } else { - out.IgnoredReasons = []*Property{} - } - } else { - out.IgnoredReasons = (out.IgnoredReasons)[:0] - } - for !in.IsDelim(']') { - var v10 *Property - if in.IsNull() { - in.Skip() - v10 = nil - } else { - if v10 == nil { - v10 = new(Property) - } - (*v10).UnmarshalEasyJSON(in) - } - out.IgnoredReasons = append(out.IgnoredReasons, v10) - in.WantComma() - } - in.Delim(']') - } - case "role": - if in.IsNull() { - in.Skip() - out.Role = nil - } else { - if out.Role == nil { - out.Role = new(Value) - } - (*out.Role).UnmarshalEasyJSON(in) - } - case "name": - if in.IsNull() { - in.Skip() - out.Name = nil - } else { - if out.Name == nil { - out.Name = new(Value) - } - (*out.Name).UnmarshalEasyJSON(in) - } - case "description": - if in.IsNull() { - in.Skip() - out.Description = nil - } else { - if out.Description == nil { - out.Description = new(Value) - } - (*out.Description).UnmarshalEasyJSON(in) - } - case "value": - if in.IsNull() { - in.Skip() - out.Value = nil - } else { - if out.Value == nil { - out.Value = new(Value) - } - (*out.Value).UnmarshalEasyJSON(in) - } - case "properties": - if in.IsNull() { - in.Skip() - out.Properties = nil - } else { - in.Delim('[') - if out.Properties == nil { - if !in.IsDelim(']') { - out.Properties = make([]*Property, 0, 8) - } else { - out.Properties = []*Property{} - } - } else { - out.Properties = (out.Properties)[:0] - } - for !in.IsDelim(']') { - var v11 *Property - if in.IsNull() { - in.Skip() - v11 = nil - } else { - if v11 == nil { - v11 = new(Property) - } - (*v11).UnmarshalEasyJSON(in) - } - out.Properties = append(out.Properties, v11) - in.WantComma() - } - in.Delim(']') - } - case "childIds": - if in.IsNull() { - in.Skip() - out.ChildIds = nil - } else { - in.Delim('[') - if out.ChildIds == nil { - if !in.IsDelim(']') { - out.ChildIds = make([]NodeID, 0, 4) - } else { - out.ChildIds = []NodeID{} - } - } else { - out.ChildIds = (out.ChildIds)[:0] - } - for !in.IsDelim(']') { - var v12 NodeID - v12 = NodeID(in.String()) - out.ChildIds = append(out.ChildIds, v12) - in.WantComma() - } - in.Delim(']') - } - case "backendDOMNodeId": - (out.BackendDOMNodeID).UnmarshalEasyJSON(in) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility6(out *jwriter.Writer, in Node) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"nodeId\":" - out.RawString(prefix[1:]) - out.String(string(in.NodeID)) - } - { - const prefix string = ",\"ignored\":" - out.RawString(prefix) - out.Bool(bool(in.Ignored)) - } - if len(in.IgnoredReasons) != 0 { - const prefix string = ",\"ignoredReasons\":" - out.RawString(prefix) - { - out.RawByte('[') - for v13, v14 := range in.IgnoredReasons { - if v13 > 0 { - out.RawByte(',') - } - if v14 == nil { - out.RawString("null") - } else { - (*v14).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - if in.Role != nil { - const prefix string = ",\"role\":" - out.RawString(prefix) - (*in.Role).MarshalEasyJSON(out) - } - if in.Name != nil { - const prefix string = ",\"name\":" - out.RawString(prefix) - (*in.Name).MarshalEasyJSON(out) - } - if in.Description != nil { - const prefix string = ",\"description\":" - out.RawString(prefix) - (*in.Description).MarshalEasyJSON(out) - } - if in.Value != nil { - const prefix string = ",\"value\":" - out.RawString(prefix) - (*in.Value).MarshalEasyJSON(out) - } - if len(in.Properties) != 0 { - const prefix string = ",\"properties\":" - out.RawString(prefix) - { - out.RawByte('[') - for v15, v16 := range in.Properties { - if v15 > 0 { - out.RawByte(',') - } - if v16 == nil { - out.RawString("null") - } else { - (*v16).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - if len(in.ChildIds) != 0 { - const prefix string = ",\"childIds\":" - out.RawString(prefix) - { - out.RawByte('[') - for v17, v18 := range in.ChildIds { - if v17 > 0 { - out.RawByte(',') - } - out.String(string(v18)) - } - out.RawByte(']') - } - } - if in.BackendDOMNodeID != 0 { - const prefix string = ",\"backendDOMNodeId\":" - out.RawString(prefix) - out.Int64(int64(in.BackendDOMNodeID)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v Node) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility6(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v Node) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility6(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *Node) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility6(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Node) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility6(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility7(in *jlexer.Lexer, out *GetPartialAXTreeReturns) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodes": - if in.IsNull() { - in.Skip() - out.Nodes = nil - } else { - in.Delim('[') - if out.Nodes == nil { - if !in.IsDelim(']') { - out.Nodes = make([]*Node, 0, 8) - } else { - out.Nodes = []*Node{} - } - } else { - out.Nodes = (out.Nodes)[:0] - } - for !in.IsDelim(']') { - var v19 *Node - if in.IsNull() { - in.Skip() - v19 = nil - } else { - if v19 == nil { - v19 = new(Node) - } - (*v19).UnmarshalEasyJSON(in) - } - out.Nodes = append(out.Nodes, v19) - in.WantComma() - } - in.Delim(']') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility7(out *jwriter.Writer, in GetPartialAXTreeReturns) { - out.RawByte('{') - first := true - _ = first - if len(in.Nodes) != 0 { - const prefix string = ",\"nodes\":" - first = false - out.RawString(prefix[1:]) - { - out.RawByte('[') - for v20, v21 := range in.Nodes { - if v20 > 0 { - out.RawByte(',') - } - if v21 == nil { - out.RawString("null") - } else { - (*v21).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v GetPartialAXTreeReturns) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility7(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v GetPartialAXTreeReturns) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility7(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *GetPartialAXTreeReturns) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility7(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *GetPartialAXTreeReturns) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility7(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility8(in *jlexer.Lexer, out *GetPartialAXTreeParams) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodeId": - (out.NodeID).UnmarshalEasyJSON(in) - case "backendNodeId": - (out.BackendNodeID).UnmarshalEasyJSON(in) - case "objectId": - out.ObjectID = runtime.RemoteObjectID(in.String()) - case "fetchRelatives": - out.FetchRelatives = bool(in.Bool()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility8(out *jwriter.Writer, in GetPartialAXTreeParams) { - out.RawByte('{') - first := true - _ = first - if in.NodeID != 0 { - const prefix string = ",\"nodeId\":" - first = false - out.RawString(prefix[1:]) - out.Int64(int64(in.NodeID)) - } - if in.BackendNodeID != 0 { - const prefix string = ",\"backendNodeId\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int64(int64(in.BackendNodeID)) - } - if in.ObjectID != "" { - const prefix string = ",\"objectId\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.ObjectID)) - } - if in.FetchRelatives { - const prefix string = ",\"fetchRelatives\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Bool(bool(in.FetchRelatives)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v GetPartialAXTreeParams) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility8(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v GetPartialAXTreeParams) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility8(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *GetPartialAXTreeParams) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility8(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *GetPartialAXTreeParams) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility8(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility9(in *jlexer.Lexer, out *GetFullAXTreeReturns) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodes": - if in.IsNull() { - in.Skip() - out.Nodes = nil - } else { - in.Delim('[') - if out.Nodes == nil { - if !in.IsDelim(']') { - out.Nodes = make([]*Node, 0, 8) - } else { - out.Nodes = []*Node{} - } - } else { - out.Nodes = (out.Nodes)[:0] - } - for !in.IsDelim(']') { - var v22 *Node - if in.IsNull() { - in.Skip() - v22 = nil - } else { - if v22 == nil { - v22 = new(Node) - } - (*v22).UnmarshalEasyJSON(in) - } - out.Nodes = append(out.Nodes, v22) - in.WantComma() - } - in.Delim(']') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility9(out *jwriter.Writer, in GetFullAXTreeReturns) { - out.RawByte('{') - first := true - _ = first - if len(in.Nodes) != 0 { - const prefix string = ",\"nodes\":" - first = false - out.RawString(prefix[1:]) - { - out.RawByte('[') - for v23, v24 := range in.Nodes { - if v23 > 0 { - out.RawByte(',') - } - if v24 == nil { - out.RawString("null") - } else { - (*v24).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v GetFullAXTreeReturns) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility9(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v GetFullAXTreeReturns) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility9(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *GetFullAXTreeReturns) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility9(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *GetFullAXTreeReturns) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility9(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility10(in *jlexer.Lexer, out *GetFullAXTreeParams) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "max_depth": - out.MaxDepth = int64(in.Int64()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility10(out *jwriter.Writer, in GetFullAXTreeParams) { - out.RawByte('{') - first := true - _ = first - if in.MaxDepth != 0 { - const prefix string = ",\"max_depth\":" - first = false - out.RawString(prefix[1:]) - out.Int64(int64(in.MaxDepth)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v GetFullAXTreeParams) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility10(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v GetFullAXTreeParams) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility10(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *GetFullAXTreeParams) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility10(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *GetFullAXTreeParams) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility10(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility11(in *jlexer.Lexer, out *GetChildAXNodesReturns) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "nodes": - if in.IsNull() { - in.Skip() - out.Nodes = nil - } else { - in.Delim('[') - if out.Nodes == nil { - if !in.IsDelim(']') { - out.Nodes = make([]*Node, 0, 8) - } else { - out.Nodes = []*Node{} - } - } else { - out.Nodes = (out.Nodes)[:0] - } - for !in.IsDelim(']') { - var v25 *Node - if in.IsNull() { - in.Skip() - v25 = nil - } else { - if v25 == nil { - v25 = new(Node) - } - (*v25).UnmarshalEasyJSON(in) - } - out.Nodes = append(out.Nodes, v25) - in.WantComma() - } - in.Delim(']') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility11(out *jwriter.Writer, in GetChildAXNodesReturns) { - out.RawByte('{') - first := true - _ = first - if len(in.Nodes) != 0 { - const prefix string = ",\"nodes\":" - first = false - out.RawString(prefix[1:]) - { - out.RawByte('[') - for v26, v27 := range in.Nodes { - if v26 > 0 { - out.RawByte(',') - } - if v27 == nil { - out.RawString("null") - } else { - (*v27).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v GetChildAXNodesReturns) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility11(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v GetChildAXNodesReturns) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility11(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *GetChildAXNodesReturns) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility11(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *GetChildAXNodesReturns) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility11(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility12(in *jlexer.Lexer, out *GetChildAXNodesParams) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "id": - out.ID = NodeID(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility12(out *jwriter.Writer, in GetChildAXNodesParams) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"id\":" - out.RawString(prefix[1:]) - out.String(string(in.ID)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v GetChildAXNodesParams) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility12(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v GetChildAXNodesParams) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility12(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *GetChildAXNodesParams) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility12(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *GetChildAXNodesParams) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility12(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility13(in *jlexer.Lexer, out *EnableParams) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility13(out *jwriter.Writer, in EnableParams) { - out.RawByte('{') - first := true - _ = first - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v EnableParams) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility13(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v EnableParams) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility13(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *EnableParams) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility13(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *EnableParams) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility13(l, v) -} -func easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility14(in *jlexer.Lexer, out *DisableParams) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility14(out *jwriter.Writer, in DisableParams) { - out.RawByte('{') - first := true - _ = first - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v DisableParams) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility14(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v DisableParams) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonC5a4559bEncodeGithubComChromedpCdprotoAccessibility14(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *DisableParams) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility14(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *DisableParams) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonC5a4559bDecodeGithubComChromedpCdprotoAccessibility14(l, v) -} diff --git a/vendor/github.com/chromedp/cdproto/accessibility/types.go b/vendor/github.com/chromedp/cdproto/accessibility/types.go deleted file mode 100644 index 655fc11c989..00000000000 --- a/vendor/github.com/chromedp/cdproto/accessibility/types.go +++ /dev/null @@ -1,451 +0,0 @@ -package accessibility - -// Code generated by cdproto-gen. DO NOT EDIT. - -import ( - "errors" - - "github.com/chromedp/cdproto/cdp" - "github.com/mailru/easyjson" - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" -) - -// NodeID unique accessibility node identifier. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXNodeId -type NodeID string - -// String returns the NodeID as string value. -func (t NodeID) String() string { - return string(t) -} - -// ValueType enum of possible property types. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueType -type ValueType string - -// String returns the ValueType as string value. -func (t ValueType) String() string { - return string(t) -} - -// ValueType values. -const ( - ValueTypeBoolean ValueType = "boolean" - ValueTypeTristate ValueType = "tristate" - ValueTypeBooleanOrUndefined ValueType = "booleanOrUndefined" - ValueTypeIdref ValueType = "idref" - ValueTypeIdrefList ValueType = "idrefList" - ValueTypeInteger ValueType = "integer" - ValueTypeNode ValueType = "node" - ValueTypeNodeList ValueType = "nodeList" - ValueTypeNumber ValueType = "number" - ValueTypeString ValueType = "string" - ValueTypeComputedString ValueType = "computedString" - ValueTypeToken ValueType = "token" - ValueTypeTokenList ValueType = "tokenList" - ValueTypeDomRelation ValueType = "domRelation" - ValueTypeRole ValueType = "role" - ValueTypeInternalRole ValueType = "internalRole" - ValueTypeValueUndefined ValueType = "valueUndefined" -) - -// MarshalEasyJSON satisfies easyjson.Marshaler. -func (t ValueType) MarshalEasyJSON(out *jwriter.Writer) { - out.String(string(t)) -} - -// MarshalJSON satisfies json.Marshaler. -func (t ValueType) MarshalJSON() ([]byte, error) { - return easyjson.Marshal(t) -} - -// UnmarshalEasyJSON satisfies easyjson.Unmarshaler. -func (t *ValueType) UnmarshalEasyJSON(in *jlexer.Lexer) { - switch ValueType(in.String()) { - case ValueTypeBoolean: - *t = ValueTypeBoolean - case ValueTypeTristate: - *t = ValueTypeTristate - case ValueTypeBooleanOrUndefined: - *t = ValueTypeBooleanOrUndefined - case ValueTypeIdref: - *t = ValueTypeIdref - case ValueTypeIdrefList: - *t = ValueTypeIdrefList - case ValueTypeInteger: - *t = ValueTypeInteger - case ValueTypeNode: - *t = ValueTypeNode - case ValueTypeNodeList: - *t = ValueTypeNodeList - case ValueTypeNumber: - *t = ValueTypeNumber - case ValueTypeString: - *t = ValueTypeString - case ValueTypeComputedString: - *t = ValueTypeComputedString - case ValueTypeToken: - *t = ValueTypeToken - case ValueTypeTokenList: - *t = ValueTypeTokenList - case ValueTypeDomRelation: - *t = ValueTypeDomRelation - case ValueTypeRole: - *t = ValueTypeRole - case ValueTypeInternalRole: - *t = ValueTypeInternalRole - case ValueTypeValueUndefined: - *t = ValueTypeValueUndefined - - default: - in.AddError(errors.New("unknown ValueType value")) - } -} - -// UnmarshalJSON satisfies json.Unmarshaler. -func (t *ValueType) UnmarshalJSON(buf []byte) error { - return easyjson.Unmarshal(buf, t) -} - -// ValueSourceType enum of possible property sources. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueSourceType -type ValueSourceType string - -// String returns the ValueSourceType as string value. -func (t ValueSourceType) String() string { - return string(t) -} - -// ValueSourceType values. -const ( - ValueSourceTypeAttribute ValueSourceType = "attribute" - ValueSourceTypeImplicit ValueSourceType = "implicit" - ValueSourceTypeStyle ValueSourceType = "style" - ValueSourceTypeContents ValueSourceType = "contents" - ValueSourceTypePlaceholder ValueSourceType = "placeholder" - ValueSourceTypeRelatedElement ValueSourceType = "relatedElement" -) - -// MarshalEasyJSON satisfies easyjson.Marshaler. -func (t ValueSourceType) MarshalEasyJSON(out *jwriter.Writer) { - out.String(string(t)) -} - -// MarshalJSON satisfies json.Marshaler. -func (t ValueSourceType) MarshalJSON() ([]byte, error) { - return easyjson.Marshal(t) -} - -// UnmarshalEasyJSON satisfies easyjson.Unmarshaler. -func (t *ValueSourceType) UnmarshalEasyJSON(in *jlexer.Lexer) { - switch ValueSourceType(in.String()) { - case ValueSourceTypeAttribute: - *t = ValueSourceTypeAttribute - case ValueSourceTypeImplicit: - *t = ValueSourceTypeImplicit - case ValueSourceTypeStyle: - *t = ValueSourceTypeStyle - case ValueSourceTypeContents: - *t = ValueSourceTypeContents - case ValueSourceTypePlaceholder: - *t = ValueSourceTypePlaceholder - case ValueSourceTypeRelatedElement: - *t = ValueSourceTypeRelatedElement - - default: - in.AddError(errors.New("unknown ValueSourceType value")) - } -} - -// UnmarshalJSON satisfies json.Unmarshaler. -func (t *ValueSourceType) UnmarshalJSON(buf []byte) error { - return easyjson.Unmarshal(buf, t) -} - -// ValueNativeSourceType enum of possible native property sources (as a -// subtype of a particular AXValueSourceType). -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueNativeSourceType -type ValueNativeSourceType string - -// String returns the ValueNativeSourceType as string value. -func (t ValueNativeSourceType) String() string { - return string(t) -} - -// ValueNativeSourceType values. -const ( - ValueNativeSourceTypeFigcaption ValueNativeSourceType = "figcaption" - ValueNativeSourceTypeLabel ValueNativeSourceType = "label" - ValueNativeSourceTypeLabelfor ValueNativeSourceType = "labelfor" - ValueNativeSourceTypeLabelwrapped ValueNativeSourceType = "labelwrapped" - ValueNativeSourceTypeLegend ValueNativeSourceType = "legend" - ValueNativeSourceTypeRubyannotation ValueNativeSourceType = "rubyannotation" - ValueNativeSourceTypeTablecaption ValueNativeSourceType = "tablecaption" - ValueNativeSourceTypeTitle ValueNativeSourceType = "title" - ValueNativeSourceTypeOther ValueNativeSourceType = "other" -) - -// MarshalEasyJSON satisfies easyjson.Marshaler. -func (t ValueNativeSourceType) MarshalEasyJSON(out *jwriter.Writer) { - out.String(string(t)) -} - -// MarshalJSON satisfies json.Marshaler. -func (t ValueNativeSourceType) MarshalJSON() ([]byte, error) { - return easyjson.Marshal(t) -} - -// UnmarshalEasyJSON satisfies easyjson.Unmarshaler. -func (t *ValueNativeSourceType) UnmarshalEasyJSON(in *jlexer.Lexer) { - switch ValueNativeSourceType(in.String()) { - case ValueNativeSourceTypeFigcaption: - *t = ValueNativeSourceTypeFigcaption - case ValueNativeSourceTypeLabel: - *t = ValueNativeSourceTypeLabel - case ValueNativeSourceTypeLabelfor: - *t = ValueNativeSourceTypeLabelfor - case ValueNativeSourceTypeLabelwrapped: - *t = ValueNativeSourceTypeLabelwrapped - case ValueNativeSourceTypeLegend: - *t = ValueNativeSourceTypeLegend - case ValueNativeSourceTypeRubyannotation: - *t = ValueNativeSourceTypeRubyannotation - case ValueNativeSourceTypeTablecaption: - *t = ValueNativeSourceTypeTablecaption - case ValueNativeSourceTypeTitle: - *t = ValueNativeSourceTypeTitle - case ValueNativeSourceTypeOther: - *t = ValueNativeSourceTypeOther - - default: - in.AddError(errors.New("unknown ValueNativeSourceType value")) - } -} - -// UnmarshalJSON satisfies json.Unmarshaler. -func (t *ValueNativeSourceType) UnmarshalJSON(buf []byte) error { - return easyjson.Unmarshal(buf, t) -} - -// ValueSource a single source for a computed AX property. -// -// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueSource -type ValueSource struct { - Type ValueSourceType `json:"type"` // What type of source this is. - Value *Value `json:"value,omitempty"` // The value of this property source. - Attribute string `json:"attribute,omitempty"` // The name of the relevant attribute, if any. - AttributeValue *Value `json:"attributeValue,omitempty"` // The value of the relevant attribute, if any. - Superseded bool `json:"superseded,omitempty"` // Whether this source is superseded by a higher priority source. - NativeSource ValueNativeSourceType `json:"nativeSource,omitempty"` // The native markup source for this value, e.g. a