initial rewrite, use micro v4 and not cms-xxx stuff #4
							
								
								
									
										35
									
								
								cmd/pkgdash/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								cmd/pkgdash/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/service" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	ctx, cancel := context.WithCancel(context.Background()) | ||||
| 	defer cancel() | ||||
|  | ||||
| 	ch := make(chan os.Signal, 1) | ||||
| 	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) | ||||
|  | ||||
| 	go func() { | ||||
| 		sig := <-ch | ||||
| 		logger.Infof(ctx, "handle signal %v, exiting", sig) | ||||
| 		cancel() | ||||
| 	}() | ||||
|  | ||||
| 	svc, err := service.NewService(ctx) | ||||
| 	if err != nil { | ||||
| 		logger.Fatalf(ctx, "failed to create service: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// start server | ||||
| 	if err = svc.Run(); err != nil { | ||||
| 		logger.Fatal(ctx, err) | ||||
| 	} | ||||
| } | ||||
| @@ -1,23 +0,0 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/service" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	svc, err := service.NewService(ctx) | ||||
| 	if err != nil { | ||||
| 		logger.Fatalf(ctx, "failed to create service: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// start server | ||||
| 	if err = svc.Run(); err != nil { | ||||
| 		logger.Fatal(ctx, err) | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -15,9 +15,9 @@ import ( | ||||
| 	"github.com/go-git/go-git/v5/plumbing/filemode" | ||||
| 	"github.com/go-git/go-git/v5/plumbing/object" | ||||
| 	"github.com/go-git/go-git/v5/storage/memory" | ||||
| 	flagconfig "go.unistack.org/micro-config-flag/v3" | ||||
| 	"go.unistack.org/micro/v3/config" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	flagconfig "go.unistack.org/micro-config-flag/v4" | ||||
| 	"go.unistack.org/micro/v4/config" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"golang.org/x/mod/modfile" | ||||
| 	"golang.org/x/mod/module" | ||||
| ) | ||||
|   | ||||
| @@ -1,22 +1,20 @@ | ||||
| package config | ||||
|  | ||||
| import service "go.unistack.org/cms-service" | ||||
|  | ||||
| type App struct { | ||||
| 	Address string `flag:"name=pkgdash.address,desc='listen address',default='127.0.0.1:8080'"` | ||||
| 	Name    string | ||||
| 	Version string | ||||
| } | ||||
|  | ||||
| type Config struct { | ||||
| 	App     *App | ||||
| 	Storage *service.ConfigStorage | ||||
| 	Logger  *service.ConfigLogger | ||||
| 	Service *service.ConfigService | ||||
| 	Core    *service.ConfigCore | ||||
| 	App        *App | ||||
| 	Address    string            `flag:"name=pkgdash.address,desc='listen address',default='127.0.0.1:8080'"` | ||||
| 	StorageDSN map[string]string `flag:"name=storage.dsn,desc='components storage dsn',default='all=sqlite+file:database.db'"` | ||||
| 	LogLevel   string            `flag:"name=logger.level,desc='logging level',default='info'"` | ||||
| } | ||||
|  | ||||
| func NewConfig() *Config { | ||||
| 	return &Config{ | ||||
| 		Service: &service.ConfigService{ | ||||
| 		App: &App{ | ||||
| 			Name:    ServiceName, | ||||
| 			Version: ServiceVersion, | ||||
| 		}, | ||||
|   | ||||
							
								
								
									
										12
									
								
								generate.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								generate.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| //go:build tools | ||||
| // +build tools | ||||
|  | ||||
| package main | ||||
|  | ||||
| //go:generate ./generate.sh | ||||
|  | ||||
| import ( | ||||
| 	_ "github.com/envoyproxy/protoc-gen-validate" | ||||
| 	_ "go.unistack.org/micro-proto/v4" | ||||
| 	_ "go.unistack.org/protoc-gen-go-micro/v4" | ||||
| ) | ||||
							
								
								
									
										15
									
								
								generate.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								generate.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #!/bin/sh -ex | ||||
|  | ||||
| PROTO_ARGS=" \ | ||||
| --proto_path=$(go list -f '{{ .Dir }}' -m github.com/envoyproxy/protoc-gen-validate) \ | ||||
| --proto_path=$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) \ | ||||
| --go_out=paths=source_relative:./proto \ | ||||
| --go-micro_out=paths=source_relative,components=micro|http,standalone=false:./proto \ | ||||
| --validate_out=paths=source_relative,lang=go:./proto \ | ||||
| --go-micro_out=components="openapiv3",openapi_file=./apidocs.swagger.yaml,debug=true,paths=source_relative:./proto | ||||
| " | ||||
|  | ||||
| find ./proto -type f -name "*.pb.go" -delete | ||||
| protoc -I./proto $PROTO_ARGS ./proto/*.proto || find ./proto -type f -name "*.pb.go" -delete | ||||
|  | ||||
| ./ui/node_modules/.bin/ng-openapi-gen -i ./proto/apidocs.swagger.yaml -o ./ui/src/app/api --removeStaleFiles true --ignoreUnusedModels false | ||||
							
								
								
									
										47
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								go.mod
									
									
									
									
									
								
							| @@ -11,18 +11,18 @@ require ( | ||||
| 	github.com/lib/pq v1.10.2 | ||||
| 	github.com/mattn/go-sqlite3 v1.14.16 | ||||
| 	github.com/pkg/errors v0.9.1 | ||||
| 	go.unistack.org/cms-service v0.0.1 | ||||
| 	go.unistack.org/micro-client-http/v3 v3.9.3 | ||||
| 	go.unistack.org/micro-config-flag/v3 v3.8.9 | ||||
| 	go.unistack.org/micro-proto/v3 v3.3.1 | ||||
| 	go.unistack.org/micro-server-http/v3 v3.11.6 | ||||
| 	go.unistack.org/micro/v3 v3.10.24 | ||||
| 	go.unistack.org/micro-config-flag/v4 v4.0.2 | ||||
| 	go.unistack.org/micro-proto/v4 v4.0.1 | ||||
| 	go.unistack.org/micro-server-http/v4 v4.0.9 | ||||
| 	go.unistack.org/micro/v4 v4.0.6 | ||||
| 	go.unistack.org/protoc-gen-go-micro/v4 v4.0.6 | ||||
| 	golang.org/x/mod v0.12.0 | ||||
| 	golang.org/x/net v0.12.0 | ||||
| 	golang.org/x/sync v0.3.0 | ||||
| 	google.golang.org/protobuf v1.31.0 | ||||
| ) | ||||
|  | ||||
| require go.unistack.org/micro-client-http/v4 v4.0.2 | ||||
|  | ||||
| require ( | ||||
| 	dario.cat/mergo v1.0.0 // indirect | ||||
| 	github.com/Microsoft/go-winio v0.6.1 // indirect | ||||
| @@ -31,23 +31,24 @@ require ( | ||||
| 	github.com/cloudflare/circl v1.3.3 // indirect | ||||
| 	github.com/dustin/go-humanize v1.0.1 // indirect | ||||
| 	github.com/emirpasic/gods v1.18.1 // indirect | ||||
| 	github.com/fatih/structtag v1.2.0 // indirect | ||||
| 	github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect | ||||
| 	github.com/go-git/go-billy/v5 v5.4.1 // indirect | ||||
| 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||||
| 	github.com/golang/protobuf v1.5.3 // indirect | ||||
| 	github.com/hashicorp/errwrap v1.1.0 // indirect | ||||
| 	github.com/hashicorp/go-multierror v1.1.1 // indirect | ||||
| 	github.com/google/gnostic v0.6.9 // indirect | ||||
| 	github.com/hashicorp/errwrap v1.0.0 // indirect | ||||
| 	github.com/hashicorp/go-multierror v1.1.0 // indirect | ||||
| 	github.com/iancoleman/strcase v0.2.0 // indirect | ||||
| 	github.com/imdario/mergo v0.3.16 // indirect | ||||
| 	github.com/jackc/chunkreader/v2 v2.0.1 // indirect | ||||
| 	github.com/jackc/pgconn v1.14.0 // indirect | ||||
| 	github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect | ||||
| 	github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530 // indirect | ||||
| 	github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451 // indirect | ||||
| 	github.com/jackc/pgio v1.0.0 // indirect | ||||
| 	github.com/jackc/pgpassfile v1.0.0 // indirect | ||||
| 	github.com/jackc/pgproto3/v2 v2.3.2 // indirect | ||||
| 	github.com/jackc/pgproto3/v2 v2.1.1 // indirect | ||||
| 	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect | ||||
| 	github.com/jackc/pgx/v4 v4.18.1 // indirect | ||||
| 	github.com/jackc/pgx/v5 v5.4.3 // indirect | ||||
| 	github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c // indirect | ||||
| 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect | ||||
| 	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | ||||
| 	github.com/kevinburke/ssh_config v1.2.0 // indirect | ||||
| @@ -56,27 +57,20 @@ require ( | ||||
| 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect | ||||
| 	github.com/pjbgf/sha1cd v0.3.0 // indirect | ||||
| 	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | ||||
| 	github.com/sergi/go-diff v1.3.1 // indirect | ||||
| 	github.com/sijms/go-ora/v2 v2.6.7 // indirect | ||||
| 	github.com/sergi/go-diff v1.1.0 // indirect | ||||
| 	github.com/skeema/knownhosts v1.2.0 // indirect | ||||
| 	github.com/spf13/afero v1.3.3 // indirect | ||||
| 	github.com/stretchr/testify v1.8.1 // indirect | ||||
| 	github.com/xanzy/ssh-agent v0.3.3 // indirect | ||||
| 	go.uber.org/atomic v1.10.0 // indirect | ||||
| 	go.unistack.org/cms-api-proto v0.0.5 // indirect | ||||
| 	go.unistack.org/micro-broker-service/v3 v3.8.2 // indirect | ||||
| 	go.unistack.org/micro-codec-yaml/v3 v3.10.0 // indirect | ||||
| 	go.unistack.org/micro-config-env/v3 v3.8.5 // indirect | ||||
| 	go.unistack.org/micro-config-file/v3 v3.8.3 // indirect | ||||
| 	go.unistack.org/micro-config-service/v3 v3.8.1 // indirect | ||||
| 	go.uber.org/atomic v1.6.0 // indirect | ||||
| 	golang.org/x/crypto v0.11.0 // indirect | ||||
| 	golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect | ||||
| 	golang.org/x/net v0.12.0 // indirect | ||||
| 	golang.org/x/sys v0.10.0 // indirect | ||||
| 	golang.org/x/text v0.11.0 // indirect | ||||
| 	golang.org/x/tools v0.11.0 // indirect | ||||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect | ||||
| 	google.golang.org/grpc v1.57.0 // indirect | ||||
| 	gopkg.in/warnings.v0 v0.1.2 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
| 	lukechampine.com/uint128 v1.3.0 // indirect | ||||
| 	modernc.org/cc/v3 v3.40.0 // indirect | ||||
| 	modernc.org/ccgo/v3 v3.16.13 // indirect | ||||
| @@ -87,5 +81,4 @@ require ( | ||||
| 	modernc.org/sqlite v1.21.0 // indirect | ||||
| 	modernc.org/strutil v1.1.3 // indirect | ||||
| 	modernc.org/token v1.1.0 // indirect | ||||
| 	sigs.k8s.io/yaml v1.3.0 // indirect | ||||
| ) | ||||
|   | ||||
							
								
								
									
										85
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								go.sum
									
									
									
									
									
								
							| @@ -350,6 +350,8 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBF | ||||
| github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= | ||||
| github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= | ||||
| github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||||
| github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= | ||||
| github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= | ||||
| github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= | ||||
| github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= | ||||
| github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= | ||||
| @@ -491,6 +493,7 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW | ||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= | ||||
| github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= | ||||
| github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= | ||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| @@ -556,14 +559,12 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t | ||||
| github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= | ||||
| github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= | ||||
| github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | ||||
| github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= | ||||
| github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | ||||
| github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= | ||||
| github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | ||||
| github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= | ||||
| github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= | ||||
| github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= | ||||
| github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= | ||||
| github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= | ||||
| github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | ||||
| @@ -577,7 +578,6 @@ github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ | ||||
| github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | ||||
| github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | ||||
| github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | ||||
| github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= | ||||
| github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= | ||||
| github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= | ||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||
| @@ -594,12 +594,10 @@ github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr | ||||
| github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= | ||||
| github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= | ||||
| github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= | ||||
| github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530 h1:dUJ578zuPEsXjtzOfEF0q9zDAfljJ9oFnTHcQaNkccw= | ||||
| github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= | ||||
| github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= | ||||
| github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= | ||||
| github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451 h1:WAvSpGf7MsFuzAtK4Vk7R4EVe+liW4x83r4oWu0WHKw= | ||||
| github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= | ||||
| github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw= | ||||
| github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= | ||||
| github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= | ||||
| github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= | ||||
| github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= | ||||
| @@ -616,9 +614,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1: | ||||
| github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= | ||||
| github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= | ||||
| github.com/jackc/pgproto3/v2 v2.0.7/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= | ||||
| github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= | ||||
| github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= | ||||
| github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= | ||||
| github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= | ||||
| github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= | ||||
| github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= | ||||
| github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= | ||||
| @@ -640,17 +637,13 @@ github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXg | ||||
| github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= | ||||
| github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= | ||||
| github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA= | ||||
| github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c h1:Dznn52SgVIVst9UyOT9brctYUgxs+CvVfPaC3jKrA50= | ||||
| github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= | ||||
| github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= | ||||
| github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= | ||||
| github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= | ||||
| github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= | ||||
| github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | ||||
| github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | ||||
| github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | ||||
| github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | ||||
| github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | ||||
| github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | ||||
| github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= | ||||
| github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= | ||||
| github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= | ||||
| @@ -892,16 +885,13 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF | ||||
| github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= | ||||
| github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= | ||||
| github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= | ||||
| github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= | ||||
| github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= | ||||
| github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= | ||||
| github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | ||||
| github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= | ||||
| github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||
| github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= | ||||
| github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||
| github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | ||||
| github.com/sijms/go-ora/v2 v2.6.7 h1:1tXyBLTkN+oGZwtQviClcCg7LYfcHZw069q+n1CUutM= | ||||
| github.com/sijms/go-ora/v2 v2.6.7/go.mod h1:EHxlY6x7y9HAsdfumurRfTd+v8NrEOTR3Xl4FWlH6xk= | ||||
| github.com/silas/dag v0.0.0-20211117232152-9d50aa809f35/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I= | ||||
| github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= | ||||
| github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= | ||||
| github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | ||||
| @@ -1014,9 +1004,8 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe | ||||
| go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||
| go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||
| go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= | ||||
| go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= | ||||
| go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= | ||||
| go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= | ||||
| go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= | ||||
| go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= | ||||
| go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= | ||||
| go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= | ||||
| @@ -1024,31 +1013,18 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E | ||||
| go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | ||||
| go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | ||||
| go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= | ||||
| go.unistack.org/cms-api-proto v0.0.5 h1:c5tTAP8RvJAkjkeYFmPhcx9k/NEE5Dfo0GDhwL5c530= | ||||
| go.unistack.org/cms-api-proto v0.0.5/go.mod h1:t5+6CxtaK1CxOv8fG/UJvj911K8+e9d86AHymNR6wDA= | ||||
| go.unistack.org/cms-service v0.0.1 h1:XKKZqjQD3ViPGRzjadnVX94wQlKcWxompZac9YTeTjw= | ||||
| go.unistack.org/cms-service v0.0.1/go.mod h1:3apbDEEgmoPfnPRpzgN40fCqbn/BdfXDk/Hvly8+bGk= | ||||
| go.unistack.org/micro-broker-service/v3 v3.8.2 h1:K30wBLsoLO0WbD9rhPi8S8asU9pfes/M2X9tX9HLr24= | ||||
| go.unistack.org/micro-broker-service/v3 v3.8.2/go.mod h1:qTlBl4vdJSl66SFIjdjOWFWKO0BFQ2ImbwiPCti/H8M= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.3 h1:5AicVsSwzAbIa1mpi99g5JhhDakUkgMV6e4F/Xyu3jI= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.3/go.mod h1:3zB0iVaYhG/xi0r/YvyTE422dOOOx1PAaiWlD2GSBlM= | ||||
| go.unistack.org/micro-codec-yaml/v3 v3.10.0 h1:cnNiWQZ3F+jsCX9DhEHBdIw8CjBItxb+TrKGGdlQ8F8= | ||||
| go.unistack.org/micro-codec-yaml/v3 v3.10.0/go.mod h1:UzwC3QZZ6+PgKSudlGZNLkugXzOFkp3sxhs/CctEwBY= | ||||
| go.unistack.org/micro-config-env/v3 v3.8.5 h1:k0BKpQflJ9mutzK//VcYw4XAKlKHTvg2GtkHTrEjbko= | ||||
| go.unistack.org/micro-config-env/v3 v3.8.5/go.mod h1:jz300Fzc9eDDogsfeJdEARW0TGXF7Pnp6CtiPhTjoA0= | ||||
| go.unistack.org/micro-config-file/v3 v3.8.3 h1:yoAyDtmWutlUkVgFUtc7JhwCX7H/2Jz0nFOC0XEx4Kk= | ||||
| go.unistack.org/micro-config-file/v3 v3.8.3/go.mod h1:dl+MQ27/P41+hINmSrZFltDSDYP1y2LItIDYb2jHFog= | ||||
| go.unistack.org/micro-config-flag/v3 v3.8.9 h1:I4eoJVV28CpxQvQ63TJ1fqK5JcV1gHmOZPveT2Vl5Iw= | ||||
| go.unistack.org/micro-config-flag/v3 v3.8.9/go.mod h1:eWI90dcZh5AOhkd83fF0KY17ea/DZPebkJ8K61yky+8= | ||||
| go.unistack.org/micro-config-service/v3 v3.8.1 h1:Q+RPWCb88VGz5+EQUx45Xeysf+Mon9Q2IvqCF3e8LZM= | ||||
| go.unistack.org/micro-config-service/v3 v3.8.1/go.mod h1:KdZJEuYwninyT04ysFkgEQa3OaMRa0kSQVPQHlumQoA= | ||||
| go.unistack.org/micro-proto/v3 v3.3.1 h1:nQ0MtWvP2G3QrpOgawVOPhpZZYkq6umTGDqs8FxJYIo= | ||||
| go.unistack.org/micro-proto/v3 v3.3.1/go.mod h1:cwRyv8uInM2I7EbU7O8Fx2Ls3N90Uw9UCCcq4olOdfE= | ||||
| go.unistack.org/micro-server-http/v3 v3.11.6 h1:BSjPyXrJ6OTyuCDE14XOGjLDJEICz2CEo2WfmSR3hqM= | ||||
| go.unistack.org/micro-server-http/v3 v3.11.6/go.mod h1:phNG9aosjbneXvZxEVaVQI+NHLLZ3eA82mOH6gGSShY= | ||||
| go.unistack.org/micro/v3 v3.10.14/go.mod h1:uMAc0U/x7dmtICCrblGf0ZLgYegu3VwQAquu+OFCw1Q= | ||||
| go.unistack.org/micro/v3 v3.10.24 h1:gIi4r0vUSpNLs+uRb4KKEXBLkE8iNp6ZnJsI5FV42j0= | ||||
| go.unistack.org/micro/v3 v3.10.24/go.mod h1:aywPekJP0n07xvmDgj+Si3VPmQzGMfj6tkHk/6kjXhU= | ||||
| go.unistack.org/micro-client-http/v4 v4.0.2 h1:0xsm2RCRWMfb1moeXQQ220uz52XE0R/PZvM9was/4lM= | ||||
| go.unistack.org/micro-client-http/v4 v4.0.2/go.mod h1:Z9QT/upeqrp/rXVkL0lk6AzrkTdes0W3QlFlZ+ytkqM= | ||||
| go.unistack.org/micro-config-flag/v4 v4.0.2 h1:qoDpT/H8a8TYZS9ucoNC0bLhNdp+UFlhnRWOuqIKAyo= | ||||
| go.unistack.org/micro-config-flag/v4 v4.0.2/go.mod h1:s0AYvz8rRtMHG2tkXoSmF8xFuHG12x3v1NERdMHDdiQ= | ||||
| go.unistack.org/micro-proto/v4 v4.0.1 h1:2RKHgtCOOcAFgKsnngGK5bqM/6MWXOjVCdw03dbuoF8= | ||||
| go.unistack.org/micro-proto/v4 v4.0.1/go.mod h1:ArmK7o+uFvxSY3dbJhKBBX4Pm1rhWdLEFf3LxBrMtec= | ||||
| go.unistack.org/micro-server-http/v4 v4.0.9 h1:ye7LVVJSXlvE1TBvEuk4m3iZrAJk0rzs6vD2/qO/o2w= | ||||
| go.unistack.org/micro-server-http/v4 v4.0.9/go.mod h1:Cu4utVz2u98fychmjA2Ls6clXrja0sqH6Xu/JTamf7Y= | ||||
| go.unistack.org/micro/v4 v4.0.6 h1:YFWvTh3VwyOd6NHYTQcf47n2TF5+p/EhpnbuBQX3qhk= | ||||
| go.unistack.org/micro/v4 v4.0.6/go.mod h1:bVEYTlPi0EsdgZZt311bIroDg9ict7ky3C87dSCCAGk= | ||||
| go.unistack.org/protoc-gen-go-micro/v4 v4.0.6 h1:qe6huziuXqRnsgvDSiaT1DR20iL676w37PMkdBEjvEk= | ||||
| go.unistack.org/protoc-gen-go-micro/v4 v4.0.6/go.mod h1:9bsKAlESlPXPBSmY/NDLL//smZbhnEMrnWyG+M8zVFA= | ||||
| golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| @@ -1076,7 +1052,6 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y | ||||
| golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||
| golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= | ||||
| golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= | ||||
| golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= | ||||
| golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= | ||||
| golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= | ||||
| @@ -1534,8 +1509,7 @@ google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKr | ||||
| google.golang.org/genproto v0.0.0-20210726143408-b02e89920bf0/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= | ||||
| google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= | ||||
| google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= | ||||
| google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= | ||||
| google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= | ||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||
| @@ -1565,8 +1539,7 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ | ||||
| google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= | ||||
| google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= | ||||
| google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= | ||||
| google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= | ||||
| google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= | ||||
| google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= | ||||
| google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= | ||||
| google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||
| google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||
| @@ -1581,7 +1554,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba | ||||
| google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||
| google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||
| google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||
| google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||
| google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= | ||||
| google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||
| gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= | ||||
| @@ -1615,12 +1587,9 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||||
| gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= | ||||
| @@ -1721,5 +1690,3 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK | ||||
| sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= | ||||
| sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= | ||||
| sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= | ||||
| sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= | ||||
| sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= | ||||
|   | ||||
| @@ -1,25 +0,0 @@ | ||||
| package encoders | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| type JSON struct{} | ||||
|  | ||||
| func (*JSON) Success(rw http.ResponseWriter, response interface{}) error { | ||||
| 	rw.Header().Set("Content-Type", "application/json; charset=utf-8") | ||||
| 	rw.WriteHeader(http.StatusOK) | ||||
|  | ||||
| 	return errors.WithStack(json.NewEncoder(rw).Encode(response)) | ||||
| } | ||||
|  | ||||
| func (*JSON) Error(rw http.ResponseWriter, err *pb.Error, status int) error { | ||||
| 	rw.Header().Set("Content-Type", "application/problem+json; charset=utf-8") | ||||
| 	rw.WriteHeader(status) | ||||
|  | ||||
| 	return errors.WithStack(json.NewEncoder(rw).Encode(&pb.ErrorRsp{Error: err})) | ||||
| } | ||||
| @@ -1,51 +0,0 @@ | ||||
| package encoders | ||||
|  | ||||
| import ( | ||||
| 	"github.com/pkg/errors" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"google.golang.org/protobuf/encoding/protojson" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| var ErrWrongResponseType = errors.New("JSONProto: wrong response message type") | ||||
|  | ||||
| type JSONProto struct { | ||||
| 	m protojson.MarshalOptions | ||||
| } | ||||
|  | ||||
| func NewJSONProto() *JSONProto { | ||||
| 	return &JSONProto{m: protojson.MarshalOptions{ | ||||
| 		EmitUnpopulated: true, | ||||
| 		UseProtoNames:   false, | ||||
| 	}} | ||||
| } | ||||
|  | ||||
| func (e *JSONProto) Success(rw http.ResponseWriter, response interface{}) error { | ||||
| 	rw.Header().Set("Content-Type", "application/json; charset=utf-8") | ||||
| 	rw.WriteHeader(http.StatusOK) | ||||
|  | ||||
| 	if v, ok := response.(proto.Message); ok { | ||||
| 		return errors.WithStack(e.Fmarshal(rw, v)) | ||||
| 	} | ||||
|  | ||||
| 	return ErrWrongResponseType | ||||
| } | ||||
|  | ||||
| func (e *JSONProto) Error(rw http.ResponseWriter, err *pb.Error, status int) error { | ||||
| 	rw.Header().Set("Content-Type", "application/problem+json; charset=utf-8") | ||||
| 	rw.WriteHeader(status) | ||||
|  | ||||
| 	return errors.WithStack(e.Fmarshal(rw, &pb.ErrorRsp{Error: err})) | ||||
| } | ||||
|  | ||||
| func (e *JSONProto) Fmarshal(w io.Writer, m proto.Message) error { | ||||
| 	b, err := e.m.Marshal(m) | ||||
| 	if len(b) > 0 { | ||||
| 		if _, err = w.Write(b); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
| @@ -1,6 +1,22 @@ | ||||
| package handler | ||||
|  | ||||
| import "github.com/pkg/errors" | ||||
| import ( | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/pkg/errors" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	badRequest    = `Bad Requet` | ||||
| 	internalError = `Internal Error` | ||||
| 	notFound      = `Source Not Found` | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	internalErrorCode = "1" | ||||
| 	badRequestCode    = "2" | ||||
| 	notFoundErrorCode = "3" | ||||
| ) | ||||
|  | ||||
| type UnmarshalError struct { | ||||
| 	err error | ||||
| @@ -18,16 +34,15 @@ func NewUnmarshalError(err error) error { | ||||
| 	return errors.WithStack(&UnmarshalError{err: err}) | ||||
| } | ||||
|  | ||||
| type InternalError struct { | ||||
| 	Err error | ||||
| } | ||||
|  | ||||
| func (e *InternalError) Error() string { | ||||
| 	return e.Err.Error() | ||||
| } | ||||
|  | ||||
| func NewInternalError(err error) error { | ||||
| 	return errors.WithStack(&InternalError{Err: err}) | ||||
| func NewInternalError(err error) *pb.ErrorRsp { | ||||
| 	return &pb.ErrorRsp{ | ||||
| 		Error: &pb.Error{ | ||||
| 			Code:    internalErrorCode, | ||||
| 			Title:   internalError, | ||||
| 			Uuid:    uuid.New().String(), | ||||
| 			Details: err.Error(), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type ParametersMissingError struct { | ||||
| @@ -42,26 +57,24 @@ func NewParametersMissingError(err error) error { | ||||
| 	return errors.WithStack(&ParametersMissingError{Err: err}) | ||||
| } | ||||
|  | ||||
| type NotFoundError struct { | ||||
| 	Err error | ||||
| func NewNotFoundError(err error) *pb.ErrorRsp { | ||||
| 	return &pb.ErrorRsp{ | ||||
| 		Error: &pb.Error{ | ||||
| 			Code:    notFoundErrorCode, | ||||
| 			Title:   notFound, | ||||
| 			Uuid:    uuid.New().String(), | ||||
| 			Details: err.Error(), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (e *NotFoundError) Error() string { | ||||
| 	return e.Err.Error() | ||||
| } | ||||
|  | ||||
| func NewNotFoundError(err error) error { | ||||
| 	return errors.WithStack(&NotFoundError{Err: err}) | ||||
| } | ||||
|  | ||||
| type ValidationError struct { | ||||
| 	Err error | ||||
| } | ||||
|  | ||||
| func (e *ValidationError) Error() string { | ||||
| 	return e.Err.Error() | ||||
| } | ||||
|  | ||||
| func NewValidationError(err error) error { | ||||
| 	return errors.WithStack(&ValidationError{Err: err}) | ||||
| func NewValidationError(err error) *pb.ErrorRsp { | ||||
| 	return &pb.ErrorRsp{ | ||||
| 		Error: &pb.Error{ | ||||
| 			Code:    badRequestCode, | ||||
| 			Title:   badRequest, | ||||
| 			Uuid:    uuid.New().String(), | ||||
| 			Details: err.Error(), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -2,26 +2,22 @@ package handler | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	cmsstorage "go.unistack.org/cms-service/storage" | ||||
| 	"go.unistack.org/micro/v3" | ||||
| 	"go.unistack.org/micro/v3/errors" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/config" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"database/sql" | ||||
| 	"errors" | ||||
| 	httpsrv "go.unistack.org/micro-server-http/v4" | ||||
| 	"go.unistack.org/micro/v4" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	cligit "go.unistack.org/unistack-org/pkgdash/service/client_git" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage" | ||||
| 	"google.golang.org/protobuf/encoding/protojson" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
| 	"io" | ||||
| 	"google.golang.org/protobuf/types/known/emptypb" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| ) | ||||
|  | ||||
| type Handler struct { | ||||
| 	svc   micro.Service | ||||
| 	store storage.Storage | ||||
|  | ||||
| 	writer writer | ||||
| 	protojson.MarshalOptions | ||||
| 	protojson.UnmarshalOptions | ||||
|  | ||||
| @@ -29,119 +25,80 @@ type Handler struct { | ||||
| 	chanUrl chan *pb.AddPackageReq | ||||
| } | ||||
|  | ||||
| func (h *Handler) ListPackage(w http.ResponseWriter, r *http.Request) { | ||||
| 	ctx := r.Context() | ||||
| func (h *Handler) ListPackage(ctx context.Context, _ *emptypb.Empty, rsp *pb.ListPackageRsp) error { | ||||
| 	logger := h.svc.Logger() | ||||
| 	logger.Debug(ctx, "Start getListPackage") | ||||
|  | ||||
| 	dbRsp, err := h.store.ListPackage(ctx) | ||||
| 	if err != nil { | ||||
| 		logger.Errorf(ctx, "error db response: %v", err) | ||||
| 		h.writer.Response(ctx, w, err) | ||||
| 		return | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusInternalServerError) | ||||
| 		return httpsrv.SetError(NewInternalError(err)) | ||||
| 	} | ||||
|  | ||||
| 	rsp := new(pb.ListPackageRsp) | ||||
| 	//rsp = new(pb.ListPackageRsp) | ||||
| 	rsp.Packages = dbRsp.Decode() | ||||
|  | ||||
| 	logger.Debug(ctx, "Success finish getListPackage") | ||||
| 	h.writer.Response(ctx, w, rsp) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Handler) UpdatePackage(w http.ResponseWriter, r *http.Request) { | ||||
| 	ctx := r.Context() | ||||
| func (h *Handler) UpdatePackage(ctx context.Context, req *pb.UpdatePackageReq, rsp *pb.UpdatePackageRsp) error { | ||||
| 	logger := h.svc.Logger() | ||||
| 	logger.Debug(ctx, "Start UpdatePackage") | ||||
|  | ||||
| 	defer r.Body.Close() | ||||
| 	all, err := io.ReadAll(r.Body) | ||||
| 	if err != nil { | ||||
| 	if err := req.Validate(); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewInternalError(err)) | ||||
| 		return | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusBadRequest) | ||||
| 		return httpsrv.SetError(NewValidationError(err)) | ||||
| 	} | ||||
|  | ||||
| 	req := new(pb.UpdatePackageReq) | ||||
| 	if err = h.Unmarshal(all, req); err != nil { | ||||
| 	if err := h.store.UpdatePackage(ctx, req); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewUnmarshalError(err)) | ||||
| 		return | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusInternalServerError) | ||||
| 		return httpsrv.SetError(NewInternalError(err)) | ||||
| 	} | ||||
|  | ||||
| 	if err = req.Validate(); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewValidationError(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if err = h.store.UpdatePackage(ctx, req); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewInternalError(err)) | ||||
| 		return | ||||
| 	} | ||||
| 	rsp.Id = req.Id | ||||
|  | ||||
| 	logger.Debug(ctx, "Success finish UpdatePackage") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Handler) AddComment(w http.ResponseWriter, r *http.Request) { | ||||
| 	ctx := r.Context() | ||||
| func (h *Handler) AddComment(ctx context.Context, req *pb.AddCommentReq, rsp *pb.AddCommentRsp) error { | ||||
| 	logger := h.svc.Logger() | ||||
| 	logger.Debug(ctx, "Start AddComment") | ||||
|  | ||||
| 	defer r.Body.Close() | ||||
| 	all, err := io.ReadAll(r.Body) | ||||
| 	err := req.Validate() | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewInternalError(err)) | ||||
| 		return | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusBadRequest) | ||||
| 		return httpsrv.SetError(NewValidationError(err)) | ||||
| 	} | ||||
|  | ||||
| 	req := new(pb.AddCommentReq) | ||||
| 	if err = h.Unmarshal(all, req); err != nil { | ||||
| 	if rsp.Id, err = h.store.AddComment(ctx, req); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewUnmarshalError(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if err = req.Validate(); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewValidationError(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if err = h.store.AddComment(ctx, req); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewInternalError(err)) | ||||
| 		return | ||||
| 		if errors.Is(err, sql.ErrNoRows) { | ||||
| 			httpsrv.SetRspCode(ctx, http.StatusNotFound) | ||||
| 			return httpsrv.SetError(NewNotFoundError(err)) | ||||
| 		} | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusInternalServerError) | ||||
| 		return httpsrv.SetError(NewInternalError(err)) | ||||
| 	} | ||||
|  | ||||
| 	logger.Debug(ctx, "Success finish addComment") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Handler) AddPackage(w http.ResponseWriter, r *http.Request) { | ||||
| 	ctx := r.Context() | ||||
| func (h *Handler) AddPackage(ctx context.Context, req *pb.AddPackageReq, rsp *pb.AddPackageRsp) error { | ||||
| 	logger := h.svc.Logger() | ||||
| 	logger.Debug(ctx, "Start AddPackage") | ||||
|  | ||||
| 	defer r.Body.Close() | ||||
| 	all, err := io.ReadAll(r.Body) | ||||
| 	err := req.Validate() | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewInternalError(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	req := new(pb.AddPackageReq) | ||||
| 	if err = h.Unmarshal(all, req); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewUnmarshalError(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if err = req.Validate(); err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewValidationError(err)) | ||||
| 		return | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusBadRequest) | ||||
| 		return httpsrv.SetError(NewValidationError(err)) | ||||
| 	} | ||||
|  | ||||
| 	if h.git.IsClose() { | ||||
| @@ -150,63 +107,64 @@ func (h *Handler) AddPackage(w http.ResponseWriter, r *http.Request) { | ||||
| 		h.chanUrl <- req | ||||
| 	} | ||||
|  | ||||
| 	rsp.Status = "Sent" | ||||
|  | ||||
| 	logger.Debug(ctx, "Success finish addPackage") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Handler) GetModule(w http.ResponseWriter, r *http.Request) { | ||||
| 	ctx := r.Context() | ||||
| func (h *Handler) GetModule(ctx context.Context, req *pb.GetModuleReq, rsp *pb.GetModuleRsp) error { | ||||
| 	logger := h.svc.Logger() | ||||
| 	logger.Debug(ctx, "Start GetModule") | ||||
|  | ||||
| 	req := new(pb.GetModuleReq) | ||||
| 	if err := URLValuesToProto(r.URL.Query(), req); err != nil { | ||||
| 		logger.Errorf(ctx, "Required parameter missing: %v", err) | ||||
| 		h.writer.Response(ctx, w, err) | ||||
| 		return | ||||
| 	err := req.Validate() | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusBadRequest) | ||||
| 		return httpsrv.SetError(NewValidationError(err)) | ||||
| 	} | ||||
|  | ||||
| 	modules, err := h.store.GetModule(ctx, req) | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		h.writer.Response(ctx, w, NewInternalError(err)) | ||||
| 		return | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusInternalServerError) | ||||
| 		return httpsrv.SetError(NewInternalError(err)) | ||||
| 	} | ||||
|  | ||||
| 	rsp := &pb.GetModuleRsp{Modules: modules.Decode()} | ||||
| 	h.writer.Response(ctx, w, rsp) | ||||
| 	rsp.Modules = modules.Decode() | ||||
|  | ||||
| 	logger.Debug(ctx, "Success finish getModule") | ||||
| } | ||||
|  | ||||
| func URLValuesToProto(vals url.Values, msg proto.Message) error { | ||||
| 	params := make(map[string]interface{}) | ||||
| 	var err error | ||||
| 	for k, v := range vals { | ||||
| 		if len(v) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		switch k { | ||||
| 		case "id[]": | ||||
| 			params[k] = v | ||||
| 		default: | ||||
| 			params[k] = v[0] | ||||
| 		} | ||||
| 	} | ||||
| 	b, err := json.Marshal(params) | ||||
| 	if err != nil { | ||||
| 		return NewUnmarshalError(err) | ||||
| 	} | ||||
| 	if err = protojson.Unmarshal(b, msg); err != nil { | ||||
| 		return NewUnmarshalError(err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func NewHandler(svc micro.Service, w writer, client cligit.Client) *Handler { | ||||
| func (h *Handler) GetComments(ctx context.Context, req *pb.GetCommentsReq, rsp *pb.GetCommentsRsp) error { | ||||
| 	logger := h.svc.Logger() | ||||
| 	logger.Debug(ctx, "Start GetModule") | ||||
|  | ||||
| 	err := req.Validate() | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusBadRequest) | ||||
| 		return httpsrv.SetError(NewValidationError(err)) | ||||
| 	} | ||||
|  | ||||
| 	comments, err := h.store.GetComment(ctx, req) | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		httpsrv.SetRspCode(ctx, http.StatusInternalServerError) | ||||
| 		return httpsrv.SetError(NewInternalError(err)) | ||||
| 	} | ||||
|  | ||||
| 	rsp.Comments = comments.Decode() | ||||
|  | ||||
| 	logger.Debug(ctx, "Success finish getModule") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func NewHandler(svc micro.Service, client cligit.Client) *Handler { | ||||
| 	h := &Handler{ | ||||
| 		svc:    svc, | ||||
| 		writer: w, | ||||
| 		git:    client, | ||||
| 		svc: svc, | ||||
| 		git: client, | ||||
| 	} | ||||
| 	h.EmitUnpopulated = true | ||||
| 	h.UseProtoNames = false | ||||
| @@ -214,18 +172,14 @@ func NewHandler(svc micro.Service, w writer, client cligit.Client) *Handler { | ||||
| } | ||||
|  | ||||
| func (h *Handler) Init(ctx context.Context) error { | ||||
| 	store := cmsstorage.InterfaceFromContext(h.svc.Options().Context) | ||||
| 	if store == nil { | ||||
| 		return cmsstorage.ErrMissingStorage | ||||
| 	} | ||||
| 	st, ok := store.(storage.Storage) | ||||
| 	if !ok { | ||||
| 		return errors.New(config.ServiceName, "error init storage", 1) | ||||
| 	store, err := storage.FromContext(h.svc.Options().Context) | ||||
| 	if err != nil { | ||||
| 		return errors.New("missing storage") | ||||
| 	} | ||||
|  | ||||
| 	h.chanUrl = h.git.Run(ctx, st) | ||||
| 	h.chanUrl = h.git.Run(ctx, store) | ||||
|  | ||||
| 	h.store = st | ||||
| 	h.store = store | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -1,34 +0,0 @@ | ||||
| package handler | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"golang.org/x/net/context" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	internalErrorCode = "1" | ||||
| 	badRequestCode    = "2" | ||||
| 	notFoundErrorCode = "3" | ||||
| ) | ||||
|  | ||||
| func mapError(ctx context.Context, err error) (result *pb.Error, status int) { | ||||
| 	status = http.StatusBadRequest | ||||
|  | ||||
| 	switch errors.Unwrap(err).(type) { | ||||
| 	case *UnmarshalError: | ||||
| 		result = &pb.Error{Code: badRequestCode, Title: "Bad request"} | ||||
| 	case *ParametersMissingError: | ||||
| 		result = &pb.Error{Code: badRequestCode, Title: "Required parameters are missing"} | ||||
| 	case *NotFoundError: | ||||
| 		result = &pb.Error{Code: notFoundErrorCode, Title: "Not found"} | ||||
| 		status = http.StatusNotFound | ||||
| 	default: | ||||
| 		status = http.StatusInternalServerError | ||||
| 		result = &pb.Error{Code: internalErrorCode, Title: "Internal error", Details: err.Error()} | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package handler | ||||
|  | ||||
| import "net/http" | ||||
|  | ||||
| func Methods(m string, next http.HandlerFunc) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, req *http.Request) { | ||||
| 		if req.Method != m { | ||||
| 			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		switch req.Method { | ||||
| 		case http.MethodPost: | ||||
| 			w.WriteHeader(http.StatusCreated) | ||||
| 		case http.MethodPut: | ||||
| 			w.WriteHeader(http.StatusNoContent) | ||||
| 		} | ||||
|  | ||||
| 		next.ServeHTTP(w, req) | ||||
| 	} | ||||
| } | ||||
| @@ -1,77 +0,0 @@ | ||||
| package handler | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| type encoder interface { | ||||
| 	Success(rw http.ResponseWriter, response interface{}) error | ||||
| 	Error(rw http.ResponseWriter, err *pb.Error, status int) error | ||||
| } | ||||
|  | ||||
| type writer interface { | ||||
| 	Response(ctx context.Context, rw http.ResponseWriter, value interface{}) | ||||
| } | ||||
|  | ||||
| // nolint | ||||
| type stackTracer interface { | ||||
| 	StackTrace() errors.StackTrace | ||||
| } | ||||
|  | ||||
| type Writer struct { | ||||
| 	encoder encoder | ||||
| } | ||||
|  | ||||
| func NewWriter(encoder encoder) (*Writer, error) { | ||||
| 	if encoder == nil { | ||||
| 		return nil, errors.New("empty encoder") | ||||
| 	} | ||||
| 	return &Writer{encoder: encoder}, nil | ||||
| } | ||||
|  | ||||
| func (w *Writer) Response(ctx context.Context, rw http.ResponseWriter, value interface{}) { | ||||
| 	var err error | ||||
|  | ||||
| 	if v, ok := value.(error); ok { | ||||
| 		err = w.error(ctx, rw, v) | ||||
| 	} else { | ||||
| 		err = w.success(rw, value) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, "Response writing error: ", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *Writer) error(ctx context.Context, rw http.ResponseWriter, err error) error { | ||||
| 	e, status := mapError(ctx, err) | ||||
| 	/* | ||||
| 		switch { | ||||
| 		case status >= http.StatusInternalServerError: | ||||
| 			logger.Errorf(ctx, "error: %s, code: %s, http status: %d, uuid: %s", err, e.Code, status, e.Uuid) | ||||
|  | ||||
| 			if err, ok := err.(stackTracer); ok { | ||||
| 				logger.Errorf(ctx, "error stacktrace: %+v, uuid: %s", err.StackTrace(), e.Uuid) | ||||
| 			} | ||||
|  | ||||
| 		default: | ||||
| 			logger.Infof(ctx, "error: %s, code: %s, http status: %d, uuid: %s", err, e.Code, status, e.Uuid) | ||||
|  | ||||
| 			if err, ok := err.(stackTracer); ok { | ||||
| 				logger.Infof(ctx, "error stacktrace: %+v, uuid: %s", err.StackTrace(), e.Uuid) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	*/ | ||||
|  | ||||
| 	return w.encoder.Error(rw, e, status) | ||||
| } | ||||
|  | ||||
| func (w *Writer) success(rw http.ResponseWriter, value interface{}) error { | ||||
| 	return w.encoder.Success(rw, value) | ||||
| } | ||||
| @@ -1,7 +1,9 @@ | ||||
| package models | ||||
|  | ||||
| import ( | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"github.com/jackc/pgtype" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type ListPackage []*Package | ||||
| @@ -42,3 +44,28 @@ func (l ListModule) Decode() []*pb.Module { | ||||
|  | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| type ListComment []*Comment | ||||
|  | ||||
| func (l ListComment) Decode() []*pb.Comment { | ||||
| 	result := make([]*pb.Comment, 0, len(l)) | ||||
| 	for i := range l { | ||||
| 		temp := &pb.Comment{ | ||||
| 			Id: l[i].ID, | ||||
| 			//Package:        l[i]., | ||||
| 			Text: l[i].Text, | ||||
| 		} | ||||
|  | ||||
| 		if l[i].Created.Status == pgtype.Present { | ||||
| 			temp.Created = l[i].Created.Time.Format(time.DateTime) | ||||
| 		} | ||||
|  | ||||
| 		if l[i].Updated.Status == pgtype.Present { | ||||
| 			temp.Updated = l[i].Updated.Time.Format(time.DateTime) | ||||
| 		} | ||||
|  | ||||
| 		result = append(result, temp) | ||||
| 	} | ||||
|  | ||||
| 	return result | ||||
| } | ||||
|   | ||||
							
								
								
									
										315
									
								
								proto/apidocs.swagger.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								proto/apidocs.swagger.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,315 @@ | ||||
| # Generated with protoc-gen-go-micro | ||||
|  | ||||
| openapi: 3.0.3 | ||||
| info: | ||||
|     title: PkgdashService API | ||||
|     version: 0.0.1 | ||||
| paths: | ||||
|     /v1/comment: | ||||
|         get: | ||||
|             tags: | ||||
|                 - PkgdashService | ||||
|             operationId: GetComments | ||||
|             parameters: | ||||
|                 - name: id | ||||
|                   in: query | ||||
|                   schema: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|             responses: | ||||
|                 default: | ||||
|                     description: Default | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ErrorRsp' | ||||
|                 "200": | ||||
|                     description: OK | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/GetCommentsRsp' | ||||
|     /v1/module: | ||||
|         get: | ||||
|             tags: | ||||
|                 - PkgdashService | ||||
|             operationId: GetModule | ||||
|             parameters: | ||||
|                 - name: id | ||||
|                   in: query | ||||
|                   schema: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|             responses: | ||||
|                 default: | ||||
|                     description: Default | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ErrorRsp' | ||||
|                 "200": | ||||
|                     description: OK | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/GetModuleRsp' | ||||
|     /v1/package: | ||||
|         post: | ||||
|             tags: | ||||
|                 - PkgdashService | ||||
|             operationId: AddPackage | ||||
|             requestBody: | ||||
|                 content: | ||||
|                     application/json: | ||||
|                         schema: | ||||
|                             $ref: '#/components/schemas/AddPackageReq' | ||||
|                 required: true | ||||
|             responses: | ||||
|                 default: | ||||
|                     description: Default | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ErrorRsp' | ||||
|                 "200": | ||||
|                     description: OK | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/AddPackageRsp' | ||||
|     /v1/package/{id}: | ||||
|         post: | ||||
|             tags: | ||||
|                 - PkgdashService | ||||
|             operationId: UpdateInfo | ||||
|             parameters: | ||||
|                 - name: id | ||||
|                   in: path | ||||
|                   required: true | ||||
|                   schema: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|             requestBody: | ||||
|                 content: | ||||
|                     application/json: | ||||
|                         schema: | ||||
|                             $ref: '#/components/schemas/UpdatePackageReq' | ||||
|                 required: true | ||||
|             responses: | ||||
|                 default: | ||||
|                     description: Default | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ErrorRsp' | ||||
|                 "200": | ||||
|                     description: OK | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/UpdatePackageRsp' | ||||
|     /v1/package/{pkg}/comment: | ||||
|         post: | ||||
|             tags: | ||||
|                 - PkgdashService | ||||
|             operationId: AddComment | ||||
|             parameters: | ||||
|                 - name: pkg | ||||
|                   in: path | ||||
|                   required: true | ||||
|                   schema: | ||||
|                     type: string | ||||
|             requestBody: | ||||
|                 content: | ||||
|                     application/json: | ||||
|                         schema: | ||||
|                             $ref: '#/components/schemas/AddCommentReq' | ||||
|                 required: true | ||||
|             responses: | ||||
|                 default: | ||||
|                     description: Default | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ErrorRsp' | ||||
|                 "200": | ||||
|                     description: OK | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/AddCommentRsp' | ||||
|     /v1/packages: | ||||
|         get: | ||||
|             tags: | ||||
|                 - PkgdashService | ||||
|             operationId: ListPackage | ||||
|             responses: | ||||
|                 default: | ||||
|                     description: Default | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ErrorRsp' | ||||
|                 "200": | ||||
|                     description: OK | ||||
|                     content: | ||||
|                         application/json: | ||||
|                             schema: | ||||
|                                 $ref: '#/components/schemas/ListPackageRsp' | ||||
| components: | ||||
|     schemas: | ||||
|         AddCommentReq: | ||||
|             type: object | ||||
|             properties: | ||||
|                 idPackage: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 text: | ||||
|                     type: string | ||||
|         AddCommentRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 id: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|         AddPackageReq: | ||||
|             type: object | ||||
|             properties: | ||||
|                 name: | ||||
|                     type: string | ||||
|                 url: | ||||
|                     type: string | ||||
|                 modules: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|         AddPackageRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 status: | ||||
|                     type: string | ||||
|         Comment: | ||||
|             type: object | ||||
|             properties: | ||||
|                 id: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 package: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 text: | ||||
|                     type: string | ||||
|                 created: | ||||
|                     type: string | ||||
|                 updated: | ||||
|                     type: string | ||||
|         Error: | ||||
|             type: object | ||||
|             properties: | ||||
|                 code: | ||||
|                     type: string | ||||
|                 title: | ||||
|                     type: string | ||||
|                 uuid: | ||||
|                     type: string | ||||
|                 details: | ||||
|                     type: string | ||||
|         ErrorRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 error: | ||||
|                     $ref: '#/components/schemas/Error' | ||||
|         GetCommentsRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 comments: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         $ref: '#/components/schemas/Comment' | ||||
|         GetModuleRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 modules: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         $ref: '#/components/schemas/Module' | ||||
|         ListPackageRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 packages: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         $ref: '#/components/schemas/Package' | ||||
|         Module: | ||||
|             type: object | ||||
|             properties: | ||||
|                 id: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 name: | ||||
|                     type: string | ||||
|                 version: | ||||
|                     type: string | ||||
|                 package: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 last_version: | ||||
|                     type: string | ||||
|         Package: | ||||
|             type: object | ||||
|             properties: | ||||
|                 id: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 name: | ||||
|                     type: string | ||||
|                 url: | ||||
|                     type: string | ||||
|                 modules: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|                 issues: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|                 comments: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|         UpdatePackageReq: | ||||
|             type: object | ||||
|             properties: | ||||
|                 id: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
|                 name: | ||||
|                     type: string | ||||
|                 url: | ||||
|                     type: string | ||||
|                 modules: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|                 issues: | ||||
|                     type: array | ||||
|                     items: | ||||
|                         type: integer | ||||
|                         format: uint64 | ||||
|         UpdatePackageRsp: | ||||
|             type: object | ||||
|             properties: | ||||
|                 id: | ||||
|                     type: integer | ||||
|                     format: uint64 | ||||
| tags: | ||||
|     - name: PkgdashService | ||||
| @@ -1,99 +0,0 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package proto; | ||||
|  | ||||
| option go_package = "go.unistack.org/unistack-org/pkgdash/proto/go_generate;go_generate"; | ||||
|  | ||||
| import "validate/validate.proto"; | ||||
| import "google/protobuf/wrappers.proto"; | ||||
|  | ||||
| service DashboardService { | ||||
|   rpc ListPackage(ListPackageReq) returns (ListPackageRsp) {}; | ||||
|   rpc UpdatePackage(UpdatePackageReq) returns (UpdatePackageRsp) {}; | ||||
|   rpc AddComment(AddCommentReq) returns (AddCommentRsp) {}; | ||||
|   rpc AddPackage(AddPackageReq) returns (AddPackageRsp) {}; | ||||
|   rpc GetModule(GetModuleReq) returns (GetModuleRsp) {}; | ||||
| }; | ||||
|  | ||||
| message ErrorRsp { | ||||
|   Error error = 1 [json_name = "error"]; | ||||
| } | ||||
|  | ||||
| message Error { | ||||
|   string code = 1 [json_name = "code"]; | ||||
|   string title = 2 [json_name = "title"]; | ||||
|   string uuid = 3 [json_name = "uuid"]; | ||||
|   string details = 4 [json_name = "details"]; | ||||
| } | ||||
|  | ||||
| message Package { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string url = 3 [(validate.rules).string.min_len = 1]; | ||||
|   repeated uint64 modules = 4; | ||||
|   repeated uint64 issues = 5; | ||||
|   repeated uint64 comments = 6; | ||||
| }; | ||||
|  | ||||
| message Module { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string version = 3 [(validate.rules).string.min_len = 1]; | ||||
|   uint64 package = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   string last_version = 5 [(validate.rules).string.min_len = 1]; | ||||
| } | ||||
|  | ||||
| message Issue { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 status = 2 [(validate.rules).uint64.gt = 0]; | ||||
|   string desc = 3 [(validate.rules).string.min_len = 1]; | ||||
|   uint64 package = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   repeated uint64 modules = 5; | ||||
| } | ||||
|  | ||||
| message Comment { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 package = 2 [(validate.rules).uint64.gt = 0]; | ||||
|   string text = 3; | ||||
|   uint64 created = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 updated = 5 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message ListPackageReq {} | ||||
| message ListPackageRsp{ | ||||
|   repeated Package packages = 1; | ||||
| } | ||||
|  | ||||
| message UpdatePackageReq { | ||||
|   google.protobuf.UInt64Value id = 1 [(validate.rules).message.required = true]; | ||||
|   google.protobuf.StringValue name = 2 [(validate.rules).message.required = true]; | ||||
|   google.protobuf.StringValue url = 3 [(validate.rules).message.required = true]; | ||||
|   repeated uint64 modules = 4 ; | ||||
|   repeated uint64 issues = 5 ; | ||||
| } | ||||
| message UpdatePackageRsp { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message AddCommentReq { | ||||
|   google.protobuf.UInt64Value idPackage = 1 [(validate.rules).message.required = true]; | ||||
|   string text = 2; | ||||
| } | ||||
|  | ||||
| message AddCommentRsp { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message AddPackageReq { | ||||
|   google.protobuf.StringValue name = 1 [(validate.rules).message.required = true]; | ||||
|   google.protobuf.StringValue url = 2  [(validate.rules).message.required = true]; | ||||
|   repeated uint64 modules = 3; | ||||
| } | ||||
| message AddPackageRsp{} | ||||
|  | ||||
| message GetModuleReq { | ||||
|   repeated uint64 id = 1 ; | ||||
| } | ||||
| message GetModuleRsp { | ||||
|   repeated Module modules = 1 ; | ||||
| } | ||||
| @@ -1,43 +0,0 @@ | ||||
| FROM golang:1.19-bullseye | ||||
|  | ||||
| RUN mkdir /build | ||||
| WORKDIR /build | ||||
|  | ||||
| RUN apt-get update && apt-get -y install --no-install-recommends protobuf-compiler libprotobuf-dev | ||||
|  | ||||
| ENV PATH=${PATH}:${GOBIN} | ||||
|  | ||||
| ENV GEN_VALIDATE=github.com/envoyproxy/protoc-gen-validate@v1.0.2 | ||||
| ENV GOOGLEAPIS=github.com/google/googleapis@v0.0.0-20200324113624-36c0febd0fa7 | ||||
| ENV GRPC_GATEWAY=github.com/grpc-ecosystem/grpc-gateway@v1.16.0 | ||||
|  | ||||
| RUN go install ${GEN_VALIDATE} | ||||
|  | ||||
| RUN go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway@v1.16.0 && \ | ||||
|     go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger@v1.16.0  && \ | ||||
|     go install google.golang.org/protobuf/cmd/protoc-gen-go@latest | ||||
|  | ||||
| RUN go install go.unistack.org/protoc-gen-go-micro/v3@latest | ||||
|  | ||||
| RUN go mod init proto | ||||
| RUN go get ${GOOGLEAPIS} && \ | ||||
|     go get ${GRPC_GATEWAY} && \ | ||||
| 	go get google.golang.org/grpc@v1.57.0 && \ | ||||
| 	go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway && \ | ||||
| 	go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 && \ | ||||
| 	go get google.golang.org/protobuf/cmd/protoc-gen-go && \ | ||||
|     go get go.unistack.org/micro-proto/v3@v3.3.1 | ||||
|  | ||||
| CMD rm -rf go_generate && \ | ||||
|     protoc \ | ||||
|         --validate_out=lang=go:. \ | ||||
|         --go-micro_out=debug=true,components="micro|http":. \ | ||||
|         --go_out=. \ | ||||
|         --grpc-gateway_out=. \ | ||||
|         --proto_path=/go/pkg/mod/go.unistack.org/micro-proto/v3@v3.3.1 \ | ||||
| 	    -I=./ \ | ||||
| 	    -I=/usr/include \ | ||||
| 	    -I=/go/pkg/mod/${GEN_VALIDATE} \ | ||||
| 	    -I=/go/pkg/mod/${GOOGLEAPIS} \ | ||||
| 	    -I=/go/pkg/mod/${GRPC_GATEWAY} \ | ||||
| 	    ./*.proto | ||||
| @@ -1,7 +0,0 @@ | ||||
| #New version of proto Makefile and Dockerfile can be found | ||||
| #at https://qcm-git.mbrd.ru/service-platform/examples/makefile | ||||
|  | ||||
| .PHONY: proto | ||||
| proto: | ||||
| 	docker build -t proto:latest . | ||||
| 	docker run --rm --name=proto -v `pwd`:/build proto:latest | ||||
| @@ -1,71 +0,0 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package proto; | ||||
|  | ||||
| option go_package = "./go_generate;go_generate"; | ||||
|  | ||||
| import "validate/validate.proto"; | ||||
|  | ||||
|  | ||||
| message ErrorRsp { | ||||
|   Error error = 1 [json_name = "error"]; | ||||
| } | ||||
|  | ||||
| message Error { | ||||
|   string code = 1 [json_name = "code"]; | ||||
|   string title = 2 [json_name = "title"]; | ||||
|   string uuid = 3 [json_name = "uuid"]; | ||||
|   string details = 4 [json_name = "details"]; | ||||
| } | ||||
|  | ||||
| message Package { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string url = 3 [(validate.rules).string.min_len = 1]; | ||||
|   repeated Module modules = 4; | ||||
|   repeated Issue issues = 5; | ||||
| }; | ||||
|  | ||||
| message Module { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string version = 3 [(validate.rules).string.min_len = 1]; | ||||
|   uint64 package = 4 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message Issue { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 status = 2 [(validate.rules).uint64.gt = 0]; | ||||
|   string desc = 3 [(validate.rules).string.min_len = 1]; | ||||
|   uint64 package = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   repeated uint64 modules = 5; | ||||
| } | ||||
|  | ||||
| message Comment { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 package = 2 [(validate.rules).uint64.gt = 0]; | ||||
|   string text = 3; | ||||
|   uint64 created = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 updated = 5 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message ListPackageReq {} | ||||
| message ListPackageRsp{ | ||||
|   repeated Package packages = 1; | ||||
| } | ||||
|  | ||||
| message UpdateInfoPackageRsp { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
| message UpdateInfoPackageReq { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message CommentRsp { | ||||
|   uint64 idPackage = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string text = 2; | ||||
| } | ||||
|  | ||||
| message CommentReq { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
| @@ -1,42 +0,0 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package proto; | ||||
|  | ||||
| option go_package = "./go_generate;go_generate"; | ||||
|  | ||||
| import "dashboard.proto"; | ||||
| import "google/api/annotations.proto"; | ||||
| import "protoc-gen-swagger/options/annotations.proto"; | ||||
|  | ||||
| option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { | ||||
|   info: { | ||||
|     title: "service-platform/product-services/mts-money/gateway-proto", | ||||
|     version: "0"; | ||||
|   }; | ||||
|   consumes: "application/json"; | ||||
|   produces: "application/json"; | ||||
| }; | ||||
|  | ||||
| service DashboardService { | ||||
|   rpc ListPackage(ListPackageReq) returns (ListPackageRsp) { | ||||
|     option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { | ||||
|       operation_id: "ListPackage"; | ||||
|       responses: { | ||||
|         key: "default"; | ||||
|         value: { | ||||
|           description: "Error response"; | ||||
|           schema: { | ||||
|             json_schema: { | ||||
|               ref: ".go_generate.ErrorRsp"; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
|     option (google.api.http) = { | ||||
|       get: "/listPackage"; | ||||
|     }; | ||||
|   }; | ||||
|   rpc UpdateInfo(UpdateInfoPackageRsp) returns (UpdateInfoPackageReq) {}; | ||||
|   rpc AddComment(CommentRsp) returns (CommentReq) {}; | ||||
| }; | ||||
| @@ -1,9 +0,0 @@ | ||||
| //go:build tools | ||||
| // +build tools | ||||
|  | ||||
| package proto | ||||
|  | ||||
| import ( | ||||
| 	_ "github.com/envoyproxy/protoc-gen-validate" | ||||
| 	_ "go.unistack.org/micro-proto/v3" | ||||
| ) | ||||
| @@ -1,14 +0,0 @@ | ||||
| #!/bin/sh -ex | ||||
|  | ||||
|  PROTO_ARGS=" \ | ||||
| --proto_path=$(go list -f '{{ .Dir }}' -m github.com/envoyproxy/protoc-gen-validate) \ | ||||
| --proto_path=$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) \ | ||||
| --go_out=paths=source_relative:go_generate \ | ||||
| --go-micro_out=module=go.unistack.org/unistack-org/pkgdash/proto/go_generate,components=micro|http,standalone=true:./micro \ | ||||
| --validate_out=paths=source_relative,lang=go:go_generate | ||||
| " | ||||
|  | ||||
| find . -not \( -name "*.sh" -or -name  "*.proto" -or -name "generate.go" -or -name "Dockerfile" -or -name "Makefile" \) -delete | ||||
| mkdir -p micro go_generate && \ | ||||
| protoc -I. $PROTO_ARGS ./*.proto || \ | ||||
| find . -not \( -name "*.sh" -or -name  "*.proto" -or -name "generate.go" -or -name "Dockerfile" -or -name "Makefile" \) -delete | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,37 +0,0 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // versions: | ||||
| // - protoc-gen-go-micro v3.10.3 | ||||
| // - protoc              v4.23.4 | ||||
| // source: dashboard.proto | ||||
|  | ||||
| package go_generate | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	v3 "go.unistack.org/micro-server-http/v3" | ||||
| 	client "go.unistack.org/micro/v3/client" | ||||
| 	go_generate "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	DashboardServiceName = "DashboardService" | ||||
| ) | ||||
| var ( | ||||
| 	DashboardServiceServerEndpoints = []v3.EndpointMetadata{} | ||||
| ) | ||||
|  | ||||
| type DashboardServiceClient interface { | ||||
| 	ListPackage(ctx context.Context, req *go_generate.ListPackageReq, opts ...client.CallOption) (*go_generate.ListPackageRsp, error) | ||||
| 	UpdatePackage(ctx context.Context, req *go_generate.UpdatePackageReq, opts ...client.CallOption) (*go_generate.UpdatePackageRsp, error) | ||||
| 	AddComment(ctx context.Context, req *go_generate.AddCommentReq, opts ...client.CallOption) (*go_generate.AddCommentRsp, error) | ||||
| 	AddPackage(ctx context.Context, req *go_generate.AddPackageReq, opts ...client.CallOption) (*go_generate.AddPackageRsp, error) | ||||
| 	GetModule(ctx context.Context, req *go_generate.GetModuleReq, opts ...client.CallOption) (*go_generate.GetModuleRsp, error) | ||||
| } | ||||
|  | ||||
| type DashboardServiceServer interface { | ||||
| 	ListPackage(ctx context.Context, req *go_generate.ListPackageReq, rsp *go_generate.ListPackageRsp) error | ||||
| 	UpdatePackage(ctx context.Context, req *go_generate.UpdatePackageReq, rsp *go_generate.UpdatePackageRsp) error | ||||
| 	AddComment(ctx context.Context, req *go_generate.AddCommentReq, rsp *go_generate.AddCommentRsp) error | ||||
| 	AddPackage(ctx context.Context, req *go_generate.AddPackageReq, rsp *go_generate.AddPackageRsp) error | ||||
| 	GetModule(ctx context.Context, req *go_generate.GetModuleReq, rsp *go_generate.GetModuleRsp) error | ||||
| } | ||||
| @@ -1,109 +0,0 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // protoc-gen-go-micro version: v3.10.3 | ||||
| // source: dashboard.proto | ||||
|  | ||||
| package go_generate | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	_ "go.unistack.org/micro-client-http/v3" | ||||
| 	v3 "go.unistack.org/micro-server-http/v3" | ||||
| 	client "go.unistack.org/micro/v3/client" | ||||
| 	server "go.unistack.org/micro/v3/server" | ||||
| 	go_generate "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| ) | ||||
|  | ||||
| type dashboardServiceClient struct { | ||||
| 	c    client.Client | ||||
| 	name string | ||||
| } | ||||
|  | ||||
| func NewDashboardServiceClient(name string, c client.Client) DashboardServiceClient { | ||||
| 	return &dashboardServiceClient{c: c, name: name} | ||||
| } | ||||
|  | ||||
| func (c *dashboardServiceClient) ListPackage(ctx context.Context, req *go_generate.ListPackageReq, opts ...client.CallOption) (*go_generate.ListPackageRsp, error) { | ||||
| 	rsp := &go_generate.ListPackageRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "DashboardService.ListPackage", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *dashboardServiceClient) UpdatePackage(ctx context.Context, req *go_generate.UpdatePackageReq, opts ...client.CallOption) (*go_generate.UpdatePackageRsp, error) { | ||||
| 	rsp := &go_generate.UpdatePackageRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "DashboardService.UpdatePackage", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *dashboardServiceClient) AddComment(ctx context.Context, req *go_generate.AddCommentReq, opts ...client.CallOption) (*go_generate.AddCommentRsp, error) { | ||||
| 	rsp := &go_generate.AddCommentRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "DashboardService.AddComment", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *dashboardServiceClient) AddPackage(ctx context.Context, req *go_generate.AddPackageReq, opts ...client.CallOption) (*go_generate.AddPackageRsp, error) { | ||||
| 	rsp := &go_generate.AddPackageRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "DashboardService.AddPackage", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *dashboardServiceClient) GetModule(ctx context.Context, req *go_generate.GetModuleReq, opts ...client.CallOption) (*go_generate.GetModuleRsp, error) { | ||||
| 	rsp := &go_generate.GetModuleRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "DashboardService.GetModule", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| type dashboardServiceServer struct { | ||||
| 	DashboardServiceServer | ||||
| } | ||||
|  | ||||
| func (h *dashboardServiceServer) ListPackage(ctx context.Context, req *go_generate.ListPackageReq, rsp *go_generate.ListPackageRsp) error { | ||||
| 	return h.DashboardServiceServer.ListPackage(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *dashboardServiceServer) UpdatePackage(ctx context.Context, req *go_generate.UpdatePackageReq, rsp *go_generate.UpdatePackageRsp) error { | ||||
| 	return h.DashboardServiceServer.UpdatePackage(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *dashboardServiceServer) AddComment(ctx context.Context, req *go_generate.AddCommentReq, rsp *go_generate.AddCommentRsp) error { | ||||
| 	return h.DashboardServiceServer.AddComment(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *dashboardServiceServer) AddPackage(ctx context.Context, req *go_generate.AddPackageReq, rsp *go_generate.AddPackageRsp) error { | ||||
| 	return h.DashboardServiceServer.AddPackage(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *dashboardServiceServer) GetModule(ctx context.Context, req *go_generate.GetModuleReq, rsp *go_generate.GetModuleRsp) error { | ||||
| 	return h.DashboardServiceServer.GetModule(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func RegisterDashboardServiceServer(s server.Server, sh DashboardServiceServer, opts ...server.HandlerOption) error { | ||||
| 	type dashboardService interface { | ||||
| 		ListPackage(ctx context.Context, req *go_generate.ListPackageReq, rsp *go_generate.ListPackageRsp) error | ||||
| 		UpdatePackage(ctx context.Context, req *go_generate.UpdatePackageReq, rsp *go_generate.UpdatePackageRsp) error | ||||
| 		AddComment(ctx context.Context, req *go_generate.AddCommentReq, rsp *go_generate.AddCommentRsp) error | ||||
| 		AddPackage(ctx context.Context, req *go_generate.AddPackageReq, rsp *go_generate.AddPackageRsp) error | ||||
| 		GetModule(ctx context.Context, req *go_generate.GetModuleReq, rsp *go_generate.GetModuleRsp) error | ||||
| 	} | ||||
| 	type DashboardService struct { | ||||
| 		dashboardService | ||||
| 	} | ||||
| 	h := &dashboardServiceServer{sh} | ||||
| 	var nopts []server.HandlerOption | ||||
| 	nopts = append(nopts, v3.HandlerEndpoints(DashboardServiceServerEndpoints)) | ||||
| 	return s.Handle(s.NewHandler(&DashboardService{h}, append(nopts, opts...)...)) | ||||
| } | ||||
							
								
								
									
										1616
									
								
								proto/pkgdash.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1616
									
								
								proto/pkgdash.pb.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,7 +1,7 @@ | ||||
| // Code generated by protoc-gen-validate. DO NOT EDIT. | ||||
| // source: dashboard.proto | ||||
| // source: pkgdash.proto | ||||
| 
 | ||||
| package go_generate | ||||
| package pkgdashpb | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| @@ -740,27 +740,9 @@ func (m *Comment) validate(all bool) error { | ||||
| 
 | ||||
| 	// no validation rules for Text | ||||
| 
 | ||||
| 	if m.GetCreated() <= 0 { | ||||
| 		err := CommentValidationError{ | ||||
| 			field:  "Created", | ||||
| 			reason: "value must be greater than 0", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| 		} | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 	// no validation rules for Created | ||||
| 
 | ||||
| 	if m.GetUpdated() <= 0 { | ||||
| 		err := CommentValidationError{ | ||||
| 			field:  "Updated", | ||||
| 			reason: "value must be greater than 0", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| 		} | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 	// no validation rules for Updated | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return CommentMultiError(errors) | ||||
| @@ -1095,10 +1077,10 @@ func (m *UpdatePackageReq) validate(all bool) error { | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	if m.GetId() == nil { | ||||
| 	if m.GetId() <= 0 { | ||||
| 		err := UpdatePackageReqValidationError{ | ||||
| 			field:  "Id", | ||||
| 			reason: "value is required", | ||||
| 			reason: "value must be greater than 0", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| @@ -1106,39 +1088,10 @@ func (m *UpdatePackageReq) validate(all bool) error { | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if all { | ||||
| 		switch v := interface{}(m.GetId()).(type) { | ||||
| 		case interface{ ValidateAll() error }: | ||||
| 			if err := v.ValidateAll(); err != nil { | ||||
| 				errors = append(errors, UpdatePackageReqValidationError{ | ||||
| 					field:  "Id", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		case interface{ Validate() error }: | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				errors = append(errors, UpdatePackageReqValidationError{ | ||||
| 					field:  "Id", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} else if v, ok := interface{}(m.GetId()).(interface{ Validate() error }); ok { | ||||
| 		if err := v.Validate(); err != nil { | ||||
| 			return UpdatePackageReqValidationError{ | ||||
| 				field:  "Id", | ||||
| 				reason: "embedded message failed validation", | ||||
| 				cause:  err, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if m.GetName() == nil { | ||||
| 	if utf8.RuneCountInString(m.GetName()) < 1 { | ||||
| 		err := UpdatePackageReqValidationError{ | ||||
| 			field:  "Name", | ||||
| 			reason: "value is required", | ||||
| 			reason: "value length must be at least 1 runes", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| @@ -1146,39 +1099,10 @@ func (m *UpdatePackageReq) validate(all bool) error { | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if all { | ||||
| 		switch v := interface{}(m.GetName()).(type) { | ||||
| 		case interface{ ValidateAll() error }: | ||||
| 			if err := v.ValidateAll(); err != nil { | ||||
| 				errors = append(errors, UpdatePackageReqValidationError{ | ||||
| 					field:  "Name", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		case interface{ Validate() error }: | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				errors = append(errors, UpdatePackageReqValidationError{ | ||||
| 					field:  "Name", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} else if v, ok := interface{}(m.GetName()).(interface{ Validate() error }); ok { | ||||
| 		if err := v.Validate(); err != nil { | ||||
| 			return UpdatePackageReqValidationError{ | ||||
| 				field:  "Name", | ||||
| 				reason: "embedded message failed validation", | ||||
| 				cause:  err, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if m.GetUrl() == nil { | ||||
| 	if utf8.RuneCountInString(m.GetUrl()) < 1 { | ||||
| 		err := UpdatePackageReqValidationError{ | ||||
| 			field:  "Url", | ||||
| 			reason: "value is required", | ||||
| 			reason: "value length must be at least 1 runes", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| @@ -1186,35 +1110,6 @@ func (m *UpdatePackageReq) validate(all bool) error { | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if all { | ||||
| 		switch v := interface{}(m.GetUrl()).(type) { | ||||
| 		case interface{ ValidateAll() error }: | ||||
| 			if err := v.ValidateAll(); err != nil { | ||||
| 				errors = append(errors, UpdatePackageReqValidationError{ | ||||
| 					field:  "Url", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		case interface{ Validate() error }: | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				errors = append(errors, UpdatePackageReqValidationError{ | ||||
| 					field:  "Url", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} else if v, ok := interface{}(m.GetUrl()).(interface{ Validate() error }); ok { | ||||
| 		if err := v.Validate(); err != nil { | ||||
| 			return UpdatePackageReqValidationError{ | ||||
| 				field:  "Url", | ||||
| 				reason: "embedded message failed validation", | ||||
| 				cause:  err, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return UpdatePackageReqMultiError(errors) | ||||
| 	} | ||||
| @@ -1404,6 +1299,118 @@ var _ interface { | ||||
| 	ErrorName() string | ||||
| } = UpdatePackageRspValidationError{} | ||||
| 
 | ||||
| // Validate checks the field values on CommentReq with the rules defined in the | ||||
| // proto definition for this message. If any rules are violated, the first | ||||
| // error encountered is returned, or nil if there are no violations. | ||||
| func (m *CommentReq) Validate() error { | ||||
| 	return m.validate(false) | ||||
| } | ||||
| 
 | ||||
| // ValidateAll checks the field values on CommentReq with the rules defined in | ||||
| // the proto definition for this message. If any rules are violated, the | ||||
| // result is a list of violation errors wrapped in CommentReqMultiError, or | ||||
| // nil if none found. | ||||
| func (m *CommentReq) ValidateAll() error { | ||||
| 	return m.validate(true) | ||||
| } | ||||
| 
 | ||||
| func (m *CommentReq) validate(all bool) error { | ||||
| 	if m == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	if m.GetPkg() <= 0 { | ||||
| 		err := CommentReqValidationError{ | ||||
| 			field:  "Pkg", | ||||
| 			reason: "value must be greater than 0", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| 		} | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	// no validation rules for Text | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return CommentReqMultiError(errors) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // CommentReqMultiError is an error wrapping multiple validation errors | ||||
| // returned by CommentReq.ValidateAll() if the designated constraints aren't met. | ||||
| type CommentReqMultiError []error | ||||
| 
 | ||||
| // Error returns a concatenation of all the error messages it wraps. | ||||
| func (m CommentReqMultiError) Error() string { | ||||
| 	var msgs []string | ||||
| 	for _, err := range m { | ||||
| 		msgs = append(msgs, err.Error()) | ||||
| 	} | ||||
| 	return strings.Join(msgs, "; ") | ||||
| } | ||||
| 
 | ||||
| // AllErrors returns a list of validation violation errors. | ||||
| func (m CommentReqMultiError) AllErrors() []error { return m } | ||||
| 
 | ||||
| // CommentReqValidationError is the validation error returned by | ||||
| // CommentReq.Validate if the designated constraints aren't met. | ||||
| type CommentReqValidationError struct { | ||||
| 	field  string | ||||
| 	reason string | ||||
| 	cause  error | ||||
| 	key    bool | ||||
| } | ||||
| 
 | ||||
| // Field function returns field value. | ||||
| func (e CommentReqValidationError) Field() string { return e.field } | ||||
| 
 | ||||
| // Reason function returns reason value. | ||||
| func (e CommentReqValidationError) Reason() string { return e.reason } | ||||
| 
 | ||||
| // Cause function returns cause value. | ||||
| func (e CommentReqValidationError) Cause() error { return e.cause } | ||||
| 
 | ||||
| // Key function returns key value. | ||||
| func (e CommentReqValidationError) Key() bool { return e.key } | ||||
| 
 | ||||
| // ErrorName returns error name. | ||||
| func (e CommentReqValidationError) ErrorName() string { return "CommentReqValidationError" } | ||||
| 
 | ||||
| // Error satisfies the builtin error interface | ||||
| func (e CommentReqValidationError) Error() string { | ||||
| 	cause := "" | ||||
| 	if e.cause != nil { | ||||
| 		cause = fmt.Sprintf(" | caused by: %v", e.cause) | ||||
| 	} | ||||
| 
 | ||||
| 	key := "" | ||||
| 	if e.key { | ||||
| 		key = "key for " | ||||
| 	} | ||||
| 
 | ||||
| 	return fmt.Sprintf( | ||||
| 		"invalid %sCommentReq.%s: %s%s", | ||||
| 		key, | ||||
| 		e.field, | ||||
| 		e.reason, | ||||
| 		cause) | ||||
| } | ||||
| 
 | ||||
| var _ error = CommentReqValidationError{} | ||||
| 
 | ||||
| var _ interface { | ||||
| 	Field() string | ||||
| 	Reason() string | ||||
| 	Key() bool | ||||
| 	Cause() error | ||||
| 	ErrorName() string | ||||
| } = CommentReqValidationError{} | ||||
| 
 | ||||
| // Validate checks the field values on AddCommentReq with the rules defined in | ||||
| // the proto definition for this message. If any rules are violated, the first | ||||
| // error encountered is returned, or nil if there are no violations. | ||||
| @@ -1426,10 +1433,10 @@ func (m *AddCommentReq) validate(all bool) error { | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	if m.GetIdPackage() == nil { | ||||
| 	if m.GetIdPackage() <= 0 { | ||||
| 		err := AddCommentReqValidationError{ | ||||
| 			field:  "IdPackage", | ||||
| 			reason: "value is required", | ||||
| 			reason: "value must be greater than 0", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| @@ -1437,35 +1444,6 @@ func (m *AddCommentReq) validate(all bool) error { | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if all { | ||||
| 		switch v := interface{}(m.GetIdPackage()).(type) { | ||||
| 		case interface{ ValidateAll() error }: | ||||
| 			if err := v.ValidateAll(); err != nil { | ||||
| 				errors = append(errors, AddCommentReqValidationError{ | ||||
| 					field:  "IdPackage", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		case interface{ Validate() error }: | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				errors = append(errors, AddCommentReqValidationError{ | ||||
| 					field:  "IdPackage", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} else if v, ok := interface{}(m.GetIdPackage()).(interface{ Validate() error }); ok { | ||||
| 		if err := v.Validate(); err != nil { | ||||
| 			return AddCommentReqValidationError{ | ||||
| 				field:  "IdPackage", | ||||
| 				reason: "embedded message failed validation", | ||||
| 				cause:  err, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// no validation rules for Text | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| @@ -1679,10 +1657,10 @@ func (m *AddPackageReq) validate(all bool) error { | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	if m.GetName() == nil { | ||||
| 	if utf8.RuneCountInString(m.GetName()) < 1 { | ||||
| 		err := AddPackageReqValidationError{ | ||||
| 			field:  "Name", | ||||
| 			reason: "value is required", | ||||
| 			reason: "value length must be at least 1 runes", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| @@ -1690,39 +1668,10 @@ func (m *AddPackageReq) validate(all bool) error { | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if all { | ||||
| 		switch v := interface{}(m.GetName()).(type) { | ||||
| 		case interface{ ValidateAll() error }: | ||||
| 			if err := v.ValidateAll(); err != nil { | ||||
| 				errors = append(errors, AddPackageReqValidationError{ | ||||
| 					field:  "Name", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		case interface{ Validate() error }: | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				errors = append(errors, AddPackageReqValidationError{ | ||||
| 					field:  "Name", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} else if v, ok := interface{}(m.GetName()).(interface{ Validate() error }); ok { | ||||
| 		if err := v.Validate(); err != nil { | ||||
| 			return AddPackageReqValidationError{ | ||||
| 				field:  "Name", | ||||
| 				reason: "embedded message failed validation", | ||||
| 				cause:  err, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if m.GetUrl() == nil { | ||||
| 	if utf8.RuneCountInString(m.GetUrl()) < 1 { | ||||
| 		err := AddPackageReqValidationError{ | ||||
| 			field:  "Url", | ||||
| 			reason: "value is required", | ||||
| 			reason: "value length must be at least 1 runes", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| @@ -1730,35 +1679,6 @@ func (m *AddPackageReq) validate(all bool) error { | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if all { | ||||
| 		switch v := interface{}(m.GetUrl()).(type) { | ||||
| 		case interface{ ValidateAll() error }: | ||||
| 			if err := v.ValidateAll(); err != nil { | ||||
| 				errors = append(errors, AddPackageReqValidationError{ | ||||
| 					field:  "Url", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		case interface{ Validate() error }: | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				errors = append(errors, AddPackageReqValidationError{ | ||||
| 					field:  "Url", | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} else if v, ok := interface{}(m.GetUrl()).(interface{ Validate() error }); ok { | ||||
| 		if err := v.Validate(); err != nil { | ||||
| 			return AddPackageReqValidationError{ | ||||
| 				field:  "Url", | ||||
| 				reason: "embedded message failed validation", | ||||
| 				cause:  err, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return AddPackageReqMultiError(errors) | ||||
| 	} | ||||
| @@ -1859,6 +1779,17 @@ func (m *AddPackageRsp) validate(all bool) error { | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	if utf8.RuneCountInString(m.GetStatus()) < 1 { | ||||
| 		err := AddPackageRspValidationError{ | ||||
| 			field:  "Status", | ||||
| 			reason: "value length must be at least 1 runes", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| 		} | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return AddPackageRspMultiError(errors) | ||||
| 	} | ||||
| @@ -2168,3 +2099,279 @@ var _ interface { | ||||
| 	Cause() error | ||||
| 	ErrorName() string | ||||
| } = GetModuleRspValidationError{} | ||||
| 
 | ||||
| // Validate checks the field values on GetCommentsReq with the rules defined in | ||||
| // the proto definition for this message. If any rules are violated, the first | ||||
| // error encountered is returned, or nil if there are no violations. | ||||
| func (m *GetCommentsReq) Validate() error { | ||||
| 	return m.validate(false) | ||||
| } | ||||
| 
 | ||||
| // ValidateAll checks the field values on GetCommentsReq with the rules defined | ||||
| // in the proto definition for this message. If any rules are violated, the | ||||
| // result is a list of violation errors wrapped in GetCommentsReqMultiError, | ||||
| // or nil if none found. | ||||
| func (m *GetCommentsReq) ValidateAll() error { | ||||
| 	return m.validate(true) | ||||
| } | ||||
| 
 | ||||
| func (m *GetCommentsReq) validate(all bool) error { | ||||
| 	if m == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	if len(m.GetId()) < 1 { | ||||
| 		err := GetCommentsReqValidationError{ | ||||
| 			field:  "Id", | ||||
| 			reason: "value must contain at least 1 item(s)", | ||||
| 		} | ||||
| 		if !all { | ||||
| 			return err | ||||
| 		} | ||||
| 		errors = append(errors, err) | ||||
| 	} | ||||
| 
 | ||||
| 	_GetCommentsReq_Id_Unique := make(map[uint64]struct{}, len(m.GetId())) | ||||
| 
 | ||||
| 	for idx, item := range m.GetId() { | ||||
| 		_, _ = idx, item | ||||
| 
 | ||||
| 		if _, exists := _GetCommentsReq_Id_Unique[item]; exists { | ||||
| 			err := GetCommentsReqValidationError{ | ||||
| 				field:  fmt.Sprintf("Id[%v]", idx), | ||||
| 				reason: "repeated value must contain unique items", | ||||
| 			} | ||||
| 			if !all { | ||||
| 				return err | ||||
| 			} | ||||
| 			errors = append(errors, err) | ||||
| 		} else { | ||||
| 			_GetCommentsReq_Id_Unique[item] = struct{}{} | ||||
| 		} | ||||
| 
 | ||||
| 		if item <= 0 { | ||||
| 			err := GetCommentsReqValidationError{ | ||||
| 				field:  fmt.Sprintf("Id[%v]", idx), | ||||
| 				reason: "value must be greater than 0", | ||||
| 			} | ||||
| 			if !all { | ||||
| 				return err | ||||
| 			} | ||||
| 			errors = append(errors, err) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return GetCommentsReqMultiError(errors) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // GetCommentsReqMultiError is an error wrapping multiple validation errors | ||||
| // returned by GetCommentsReq.ValidateAll() if the designated constraints | ||||
| // aren't met. | ||||
| type GetCommentsReqMultiError []error | ||||
| 
 | ||||
| // Error returns a concatenation of all the error messages it wraps. | ||||
| func (m GetCommentsReqMultiError) Error() string { | ||||
| 	var msgs []string | ||||
| 	for _, err := range m { | ||||
| 		msgs = append(msgs, err.Error()) | ||||
| 	} | ||||
| 	return strings.Join(msgs, "; ") | ||||
| } | ||||
| 
 | ||||
| // AllErrors returns a list of validation violation errors. | ||||
| func (m GetCommentsReqMultiError) AllErrors() []error { return m } | ||||
| 
 | ||||
| // GetCommentsReqValidationError is the validation error returned by | ||||
| // GetCommentsReq.Validate if the designated constraints aren't met. | ||||
| type GetCommentsReqValidationError struct { | ||||
| 	field  string | ||||
| 	reason string | ||||
| 	cause  error | ||||
| 	key    bool | ||||
| } | ||||
| 
 | ||||
| // Field function returns field value. | ||||
| func (e GetCommentsReqValidationError) Field() string { return e.field } | ||||
| 
 | ||||
| // Reason function returns reason value. | ||||
| func (e GetCommentsReqValidationError) Reason() string { return e.reason } | ||||
| 
 | ||||
| // Cause function returns cause value. | ||||
| func (e GetCommentsReqValidationError) Cause() error { return e.cause } | ||||
| 
 | ||||
| // Key function returns key value. | ||||
| func (e GetCommentsReqValidationError) Key() bool { return e.key } | ||||
| 
 | ||||
| // ErrorName returns error name. | ||||
| func (e GetCommentsReqValidationError) ErrorName() string { return "GetCommentsReqValidationError" } | ||||
| 
 | ||||
| // Error satisfies the builtin error interface | ||||
| func (e GetCommentsReqValidationError) Error() string { | ||||
| 	cause := "" | ||||
| 	if e.cause != nil { | ||||
| 		cause = fmt.Sprintf(" | caused by: %v", e.cause) | ||||
| 	} | ||||
| 
 | ||||
| 	key := "" | ||||
| 	if e.key { | ||||
| 		key = "key for " | ||||
| 	} | ||||
| 
 | ||||
| 	return fmt.Sprintf( | ||||
| 		"invalid %sGetCommentsReq.%s: %s%s", | ||||
| 		key, | ||||
| 		e.field, | ||||
| 		e.reason, | ||||
| 		cause) | ||||
| } | ||||
| 
 | ||||
| var _ error = GetCommentsReqValidationError{} | ||||
| 
 | ||||
| var _ interface { | ||||
| 	Field() string | ||||
| 	Reason() string | ||||
| 	Key() bool | ||||
| 	Cause() error | ||||
| 	ErrorName() string | ||||
| } = GetCommentsReqValidationError{} | ||||
| 
 | ||||
| // Validate checks the field values on GetCommentsRsp with the rules defined in | ||||
| // the proto definition for this message. If any rules are violated, the first | ||||
| // error encountered is returned, or nil if there are no violations. | ||||
| func (m *GetCommentsRsp) Validate() error { | ||||
| 	return m.validate(false) | ||||
| } | ||||
| 
 | ||||
| // ValidateAll checks the field values on GetCommentsRsp with the rules defined | ||||
| // in the proto definition for this message. If any rules are violated, the | ||||
| // result is a list of violation errors wrapped in GetCommentsRspMultiError, | ||||
| // or nil if none found. | ||||
| func (m *GetCommentsRsp) ValidateAll() error { | ||||
| 	return m.validate(true) | ||||
| } | ||||
| 
 | ||||
| func (m *GetCommentsRsp) validate(all bool) error { | ||||
| 	if m == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var errors []error | ||||
| 
 | ||||
| 	for idx, item := range m.GetComments() { | ||||
| 		_, _ = idx, item | ||||
| 
 | ||||
| 		if all { | ||||
| 			switch v := interface{}(item).(type) { | ||||
| 			case interface{ ValidateAll() error }: | ||||
| 				if err := v.ValidateAll(); err != nil { | ||||
| 					errors = append(errors, GetCommentsRspValidationError{ | ||||
| 						field:  fmt.Sprintf("Comments[%v]", idx), | ||||
| 						reason: "embedded message failed validation", | ||||
| 						cause:  err, | ||||
| 					}) | ||||
| 				} | ||||
| 			case interface{ Validate() error }: | ||||
| 				if err := v.Validate(); err != nil { | ||||
| 					errors = append(errors, GetCommentsRspValidationError{ | ||||
| 						field:  fmt.Sprintf("Comments[%v]", idx), | ||||
| 						reason: "embedded message failed validation", | ||||
| 						cause:  err, | ||||
| 					}) | ||||
| 				} | ||||
| 			} | ||||
| 		} else if v, ok := interface{}(item).(interface{ Validate() error }); ok { | ||||
| 			if err := v.Validate(); err != nil { | ||||
| 				return GetCommentsRspValidationError{ | ||||
| 					field:  fmt.Sprintf("Comments[%v]", idx), | ||||
| 					reason: "embedded message failed validation", | ||||
| 					cause:  err, | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errors) > 0 { | ||||
| 		return GetCommentsRspMultiError(errors) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // GetCommentsRspMultiError is an error wrapping multiple validation errors | ||||
| // returned by GetCommentsRsp.ValidateAll() if the designated constraints | ||||
| // aren't met. | ||||
| type GetCommentsRspMultiError []error | ||||
| 
 | ||||
| // Error returns a concatenation of all the error messages it wraps. | ||||
| func (m GetCommentsRspMultiError) Error() string { | ||||
| 	var msgs []string | ||||
| 	for _, err := range m { | ||||
| 		msgs = append(msgs, err.Error()) | ||||
| 	} | ||||
| 	return strings.Join(msgs, "; ") | ||||
| } | ||||
| 
 | ||||
| // AllErrors returns a list of validation violation errors. | ||||
| func (m GetCommentsRspMultiError) AllErrors() []error { return m } | ||||
| 
 | ||||
| // GetCommentsRspValidationError is the validation error returned by | ||||
| // GetCommentsRsp.Validate if the designated constraints aren't met. | ||||
| type GetCommentsRspValidationError struct { | ||||
| 	field  string | ||||
| 	reason string | ||||
| 	cause  error | ||||
| 	key    bool | ||||
| } | ||||
| 
 | ||||
| // Field function returns field value. | ||||
| func (e GetCommentsRspValidationError) Field() string { return e.field } | ||||
| 
 | ||||
| // Reason function returns reason value. | ||||
| func (e GetCommentsRspValidationError) Reason() string { return e.reason } | ||||
| 
 | ||||
| // Cause function returns cause value. | ||||
| func (e GetCommentsRspValidationError) Cause() error { return e.cause } | ||||
| 
 | ||||
| // Key function returns key value. | ||||
| func (e GetCommentsRspValidationError) Key() bool { return e.key } | ||||
| 
 | ||||
| // ErrorName returns error name. | ||||
| func (e GetCommentsRspValidationError) ErrorName() string { return "GetCommentsRspValidationError" } | ||||
| 
 | ||||
| // Error satisfies the builtin error interface | ||||
| func (e GetCommentsRspValidationError) Error() string { | ||||
| 	cause := "" | ||||
| 	if e.cause != nil { | ||||
| 		cause = fmt.Sprintf(" | caused by: %v", e.cause) | ||||
| 	} | ||||
| 
 | ||||
| 	key := "" | ||||
| 	if e.key { | ||||
| 		key = "key for " | ||||
| 	} | ||||
| 
 | ||||
| 	return fmt.Sprintf( | ||||
| 		"invalid %sGetCommentsRsp.%s: %s%s", | ||||
| 		key, | ||||
| 		e.field, | ||||
| 		e.reason, | ||||
| 		cause) | ||||
| } | ||||
| 
 | ||||
| var _ error = GetCommentsRspValidationError{} | ||||
| 
 | ||||
| var _ interface { | ||||
| 	Field() string | ||||
| 	Reason() string | ||||
| 	Key() bool | ||||
| 	Cause() error | ||||
| 	ErrorName() string | ||||
| } = GetCommentsRspValidationError{} | ||||
							
								
								
									
										201
									
								
								proto/pkgdash.proto
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								proto/pkgdash.proto
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,201 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package pkgdash; | ||||
|  | ||||
| option go_package = "go.unistack.org/unistack-org/pkgdash/proto;pkgdashpb"; | ||||
|  | ||||
| import "api/annotations.proto"; | ||||
| import "openapiv3/annotations.proto"; | ||||
| import "validate/validate.proto"; | ||||
| import "google/protobuf/empty.proto"; | ||||
|  | ||||
| service PkgdashService { | ||||
|   rpc ListPackage(google.protobuf.Empty) returns (ListPackageRsp) { | ||||
|     option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "ListPackage"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: {_ref: ".pkgdash.ErrorRsp"}; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|     option (micro.api.http) = { | ||||
|       get: "/v1/packages"; | ||||
|     }; | ||||
|   }; | ||||
|   rpc UpdatePackage(UpdatePackageReq) returns (UpdatePackageRsp) { | ||||
|     option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "UpdateInfo"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: {_ref: ".pkgdash.ErrorRsp"}; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|     option (micro.api.http) = { | ||||
|       post: "/v1/package/{id}"; | ||||
|       body: "*"; | ||||
|     }; | ||||
|   }; | ||||
|   rpc AddComment(AddCommentReq) returns (AddCommentRsp) { | ||||
|     option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "AddComment"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: {_ref: ".pkgdash.ErrorRsp"}; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|     option (micro.api.http) = { | ||||
|       post: "/v1/package/{pkg}/comment"; | ||||
|       body: "*"; | ||||
|     }; | ||||
|   }; | ||||
|   rpc AddPackage(AddPackageReq) returns (AddPackageRsp) { | ||||
|     option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "AddPackage"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: {_ref: ".pkgdash.ErrorRsp"}; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|     option (micro.api.http) = { | ||||
|       post: "/v1/package"; | ||||
|       body: "*"; | ||||
|     }; | ||||
|   }; | ||||
|   rpc GetModule(GetModuleReq) returns (GetModuleRsp) { | ||||
|     option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "GetModule"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: {_ref: ".pkgdash.ErrorRsp"}; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|     option (micro.api.http) = { | ||||
|       get: "/v1/module"; | ||||
|     }; | ||||
|   }; | ||||
|   rpc GetComments(GetCommentsReq) returns (GetCommentsRsp) { | ||||
|     option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "GetComments"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: {_ref: ".pkgdash.ErrorRsp"}; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|     option (micro.api.http) = { | ||||
|       get: "/v1/comment"; | ||||
|     }; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| message ErrorRsp { | ||||
|   Error error = 1 [json_name = "error"]; | ||||
| } | ||||
|  | ||||
| message Error { | ||||
|   string code = 1 [json_name = "code"]; | ||||
|   string title = 2 [json_name = "title"]; | ||||
|   string uuid = 3 [json_name = "uuid"]; | ||||
|   string details = 4 [json_name = "details"]; | ||||
| } | ||||
|  | ||||
| message Package { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string url = 3 [(validate.rules).string.min_len = 1]; | ||||
|   repeated uint64 modules = 4; | ||||
|   repeated uint64 issues = 5; | ||||
|   repeated uint64 comments = 6; | ||||
| }; | ||||
|  | ||||
| message Module { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string version = 3 [(validate.rules).string.min_len = 1]; | ||||
|   uint64 package = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   string last_version = 5 [(validate.rules).string.min_len = 1]; | ||||
| } | ||||
|  | ||||
| message Issue { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 status = 2 [(validate.rules).uint64.gt = 0]; | ||||
|   string desc = 3 [(validate.rules).string.min_len = 1]; | ||||
|   uint64 package = 4 [(validate.rules).uint64.gt = 0]; | ||||
|   repeated uint64 modules = 5; | ||||
| } | ||||
|  | ||||
| message Comment { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   uint64 package = 2 [(validate.rules).uint64.gt = 0]; | ||||
|   string text = 3; | ||||
|   string created = 4 ; | ||||
|   string updated = 5 ; | ||||
| } | ||||
|  | ||||
| message ListPackageReq {} | ||||
| message ListPackageRsp{ | ||||
|   repeated Package packages = 1; | ||||
| } | ||||
|  | ||||
| message UpdatePackageReq { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string name = 2 [(validate.rules).string.min_len = 1]; | ||||
|   string url = 3 [(validate.rules).string.min_len = 1]; | ||||
|   repeated uint64 modules = 4 ; | ||||
|   repeated uint64 issues = 5 ; | ||||
| } | ||||
| message UpdatePackageRsp { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message CommentReq { | ||||
|   uint64 pkg = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string text = 2; | ||||
| } | ||||
|  | ||||
| message AddCommentReq { | ||||
|   uint64 idPackage = 1 [(validate.rules).uint64.gt = 0]; | ||||
|   string text = 2; | ||||
| } | ||||
|  | ||||
| message AddCommentRsp { | ||||
|   uint64 id = 1 [(validate.rules).uint64.gt = 0]; | ||||
| } | ||||
|  | ||||
| message AddPackageReq { | ||||
|   string name = 1 [(validate.rules).string.min_len = 1]; | ||||
|   string url = 2  [(validate.rules).string.min_len = 1]; | ||||
|   repeated uint64 modules = 3; | ||||
| } | ||||
|  | ||||
| message AddPackageRsp{ | ||||
|   string status = 1 [(validate.rules).string.min_len = 1]; | ||||
| } | ||||
|  | ||||
| message GetModuleReq { | ||||
|   repeated uint64 id = 1 ; | ||||
| } | ||||
| message GetModuleRsp { | ||||
|   repeated Module modules = 1 ; | ||||
| } | ||||
|  | ||||
| message GetCommentsReq { | ||||
|   repeated uint64 id = 1 [(validate.rules).repeated = { | ||||
|     unique: true | ||||
|     min_items: 1 | ||||
|     items: { | ||||
|       uint64: { | ||||
|         gt: 0 | ||||
|       } | ||||
|     } | ||||
|   }] ; | ||||
| } | ||||
|  | ||||
| message GetCommentsRsp { | ||||
|   repeated Comment comments = 1; | ||||
| } | ||||
							
								
								
									
										36
									
								
								proto/pkgdash_micro.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								proto/pkgdash_micro.pb.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // versions: | ||||
| // - protoc-gen-go-micro v4.0.2 | ||||
| // - protoc              v4.23.4 | ||||
| // source: pkgdash.proto | ||||
|  | ||||
| package pkgdashpb | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	_ "go.unistack.org/micro/v4/client" | ||||
| 	options "go.unistack.org/micro/v4/options" | ||||
| 	emptypb "google.golang.org/protobuf/types/known/emptypb" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	PkgdashServiceName = "PkgdashService" | ||||
| ) | ||||
|  | ||||
| type PkgdashServiceClient interface { | ||||
| 	ListPackage(ctx context.Context, req *emptypb.Empty, opts ...options.Option) (*ListPackageRsp, error) | ||||
| 	UpdatePackage(ctx context.Context, req *UpdatePackageReq, opts ...options.Option) (*UpdatePackageRsp, error) | ||||
| 	AddComment(ctx context.Context, req *AddCommentReq, opts ...options.Option) (*AddCommentRsp, error) | ||||
| 	AddPackage(ctx context.Context, req *AddPackageReq, opts ...options.Option) (*AddPackageRsp, error) | ||||
| 	GetModule(ctx context.Context, req *GetModuleReq, opts ...options.Option) (*GetModuleRsp, error) | ||||
| 	GetComments(ctx context.Context, req *GetCommentsReq, opts ...options.Option) (*GetCommentsRsp, error) | ||||
| } | ||||
|  | ||||
| type PkgdashServiceServer interface { | ||||
| 	ListPackage(ctx context.Context, req *emptypb.Empty, rsp *ListPackageRsp) error | ||||
| 	UpdatePackage(ctx context.Context, req *UpdatePackageReq, rsp *UpdatePackageRsp) error | ||||
| 	AddComment(ctx context.Context, req *AddCommentReq, rsp *AddCommentRsp) error | ||||
| 	AddPackage(ctx context.Context, req *AddPackageReq, rsp *AddPackageRsp) error | ||||
| 	GetModule(ctx context.Context, req *GetModuleReq, rsp *GetModuleRsp) error | ||||
| 	GetComments(ctx context.Context, req *GetCommentsReq, rsp *GetCommentsRsp) error | ||||
| } | ||||
							
								
								
									
										229
									
								
								proto/pkgdash_micro_http.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								proto/pkgdash_micro_http.pb.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // protoc-gen-go-micro version: v4.0.2 | ||||
| // source: pkgdash.proto | ||||
|  | ||||
| package pkgdashpb | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	v41 "go.unistack.org/micro-client-http/v4" | ||||
| 	v4 "go.unistack.org/micro-server-http/v4" | ||||
| 	client "go.unistack.org/micro/v4/client" | ||||
| 	options "go.unistack.org/micro/v4/options" | ||||
| 	server "go.unistack.org/micro/v4/server" | ||||
| 	emptypb "google.golang.org/protobuf/types/known/emptypb" | ||||
| 	http "net/http" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	PkgdashServiceServerEndpoints = []v4.EndpointMetadata{ | ||||
| 		{ | ||||
| 			Name:   "PkgdashService.ListPackage", | ||||
| 			Path:   "/v1/packages", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "PkgdashService.UpdatePackage", | ||||
| 			Path:   "/v1/package/{id}", | ||||
| 			Method: "POST", | ||||
| 			Body:   "*", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "PkgdashService.AddComment", | ||||
| 			Path:   "/v1/package/{pkg}/comment", | ||||
| 			Method: "POST", | ||||
| 			Body:   "*", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "PkgdashService.AddPackage", | ||||
| 			Path:   "/v1/package", | ||||
| 			Method: "POST", | ||||
| 			Body:   "*", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "PkgdashService.GetModule", | ||||
| 			Path:   "/v1/module", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "PkgdashService.GetComments", | ||||
| 			Path:   "/v1/comment", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| type pkgdashServiceClient struct { | ||||
| 	c    client.Client | ||||
| 	name string | ||||
| } | ||||
|  | ||||
| func NewPkgdashServiceClient(name string, c client.Client) PkgdashServiceClient { | ||||
| 	return &pkgdashServiceClient{c: c, name: name} | ||||
| } | ||||
|  | ||||
| func (c *pkgdashServiceClient) ListPackage(ctx context.Context, req *emptypb.Empty, opts ...options.Option) (*ListPackageRsp, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &ErrorRsp{} | ||||
| 	opts = append(opts, | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/v1/packages"), | ||||
| 	) | ||||
| 	rsp := &ListPackageRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "PkgdashService.ListPackage", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *pkgdashServiceClient) UpdatePackage(ctx context.Context, req *UpdatePackageReq, opts ...options.Option) (*UpdatePackageRsp, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &ErrorRsp{} | ||||
| 	opts = append(opts, | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v41.Method(http.MethodPost), | ||||
| 		v41.Path("/v1/package/{id}"), | ||||
| 		v41.Body("*"), | ||||
| 	) | ||||
| 	rsp := &UpdatePackageRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "PkgdashService.UpdatePackage", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *pkgdashServiceClient) AddComment(ctx context.Context, req *AddCommentReq, opts ...options.Option) (*AddCommentRsp, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &ErrorRsp{} | ||||
| 	opts = append(opts, | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v41.Method(http.MethodPost), | ||||
| 		v41.Path("/v1/package/{pkg}/comment"), | ||||
| 		v41.Body("*"), | ||||
| 	) | ||||
| 	rsp := &AddCommentRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "PkgdashService.AddComment", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *pkgdashServiceClient) AddPackage(ctx context.Context, req *AddPackageReq, opts ...options.Option) (*AddPackageRsp, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &ErrorRsp{} | ||||
| 	opts = append(opts, | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v41.Method(http.MethodPost), | ||||
| 		v41.Path("/v1/package"), | ||||
| 		v41.Body("*"), | ||||
| 	) | ||||
| 	rsp := &AddPackageRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "PkgdashService.AddPackage", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *pkgdashServiceClient) GetModule(ctx context.Context, req *GetModuleReq, opts ...options.Option) (*GetModuleRsp, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &ErrorRsp{} | ||||
| 	opts = append(opts, | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/v1/module"), | ||||
| 	) | ||||
| 	rsp := &GetModuleRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "PkgdashService.GetModule", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *pkgdashServiceClient) GetComments(ctx context.Context, req *GetCommentsReq, opts ...options.Option) (*GetCommentsRsp, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &ErrorRsp{} | ||||
| 	opts = append(opts, | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/v1/comment"), | ||||
| 	) | ||||
| 	rsp := &GetCommentsRsp{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "PkgdashService.GetComments", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| type pkgdashServiceServer struct { | ||||
| 	PkgdashServiceServer | ||||
| } | ||||
|  | ||||
| func (h *pkgdashServiceServer) ListPackage(ctx context.Context, req *emptypb.Empty, rsp *ListPackageRsp) error { | ||||
| 	return h.PkgdashServiceServer.ListPackage(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *pkgdashServiceServer) UpdatePackage(ctx context.Context, req *UpdatePackageReq, rsp *UpdatePackageRsp) error { | ||||
| 	return h.PkgdashServiceServer.UpdatePackage(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *pkgdashServiceServer) AddComment(ctx context.Context, req *AddCommentReq, rsp *AddCommentRsp) error { | ||||
| 	return h.PkgdashServiceServer.AddComment(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *pkgdashServiceServer) AddPackage(ctx context.Context, req *AddPackageReq, rsp *AddPackageRsp) error { | ||||
| 	return h.PkgdashServiceServer.AddPackage(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *pkgdashServiceServer) GetModule(ctx context.Context, req *GetModuleReq, rsp *GetModuleRsp) error { | ||||
| 	return h.PkgdashServiceServer.GetModule(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *pkgdashServiceServer) GetComments(ctx context.Context, req *GetCommentsReq, rsp *GetCommentsRsp) error { | ||||
| 	return h.PkgdashServiceServer.GetComments(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func RegisterPkgdashServiceServer(s server.Server, sh PkgdashServiceServer, opts ...options.Option) error { | ||||
| 	type pkgdashService interface { | ||||
| 		ListPackage(ctx context.Context, req *emptypb.Empty, rsp *ListPackageRsp) error | ||||
| 		UpdatePackage(ctx context.Context, req *UpdatePackageReq, rsp *UpdatePackageRsp) error | ||||
| 		AddComment(ctx context.Context, req *AddCommentReq, rsp *AddCommentRsp) error | ||||
| 		AddPackage(ctx context.Context, req *AddPackageReq, rsp *AddPackageRsp) error | ||||
| 		GetModule(ctx context.Context, req *GetModuleReq, rsp *GetModuleRsp) error | ||||
| 		GetComments(ctx context.Context, req *GetCommentsReq, rsp *GetCommentsRsp) error | ||||
| 	} | ||||
| 	type PkgdashService struct { | ||||
| 		pkgdashService | ||||
| 	} | ||||
| 	h := &pkgdashServiceServer{sh} | ||||
| 	var nopts []options.Option | ||||
| 	nopts = append(nopts, v4.HandlerEndpoints(PkgdashServiceServerEndpoints)) | ||||
| 	return s.Handle(&PkgdashService{h}, append(nopts, opts...)...) | ||||
| } | ||||
| @@ -3,9 +3,6 @@ package client_git | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/internal" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/models" | ||||
| 	"io" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| @@ -16,8 +13,11 @@ import ( | ||||
| 	"github.com/go-git/go-git/v5/plumbing/filemode" | ||||
| 	"github.com/go-git/go-git/v5/plumbing/object" | ||||
| 	"github.com/go-git/go-git/v5/storage/memory" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/internal" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/models" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage" | ||||
| 	"golang.org/x/mod/modfile" | ||||
| 	"golang.org/x/mod/module" | ||||
| @@ -72,7 +72,7 @@ func (c *client) Done() <-chan struct{} { | ||||
| } | ||||
|  | ||||
| func runner(ctx context.Context, st storage.Storage, req *pb.AddPackageReq) { | ||||
| 	modules, err := getGoModule(ctx, req.Url.Value) | ||||
| 	modules, err := getGoModule(ctx, req.Url) | ||||
| 	if err != nil { | ||||
| 		logger.Error(ctx, err) | ||||
| 		return | ||||
|   | ||||
| @@ -3,12 +3,12 @@ package client_git | ||||
| import ( | ||||
| 	"context" | ||||
| 	"database/sql" | ||||
| 	"embed" | ||||
| 	"fmt" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage/postgres" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage/sqlite" | ||||
| 	"google.golang.org/protobuf/types/known/wrapperspb" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| @@ -23,11 +23,8 @@ func TestClientPG(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	st, err := postgres.NewStorage(conn) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	fucntion := postgres.NewStorage() | ||||
| 	st := fucntion(conn, embed.FS{}) | ||||
| 	s, ok := st.(storage.Storage) | ||||
| 	if !ok { | ||||
| 		t.Fatal("typecast error") | ||||
| @@ -40,8 +37,8 @@ func TestClientPG(t *testing.T) { | ||||
| 	ch := cli.Run(ctx, s) | ||||
|  | ||||
| 	data := &pb.AddPackageReq{ | ||||
| 		Name: wrapperspb.String("test"), | ||||
| 		Url:  wrapperspb.String("https://github.com/dantedenis/service_history.git"), | ||||
| 		Name: "test", | ||||
| 		Url:  "https://github.com/dantedenis/service_history.git", | ||||
| 	} | ||||
|  | ||||
| 	ch <- data | ||||
| @@ -59,11 +56,8 @@ func TestClientLite(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	st, err := sqlite.NewStorage(conn) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	function := sqlite.NewStorage() | ||||
| 	st := function(conn, embed.FS{}) | ||||
| 	s, ok := st.(storage.Storage) | ||||
| 	if !ok { | ||||
| 		t.Fatal("typecast error") | ||||
| @@ -76,8 +70,8 @@ func TestClientLite(t *testing.T) { | ||||
| 	ch := cli.Run(ctx, s) | ||||
|  | ||||
| 	data := &pb.AddPackageReq{ | ||||
| 		Name: wrapperspb.String("test"), | ||||
| 		Url:  wrapperspb.String("https://github.com/dantedenis/service_history.git"), | ||||
| 		Name: "test", | ||||
| 		Url:  "https://github.com/dantedenis/service_history.git", | ||||
| 	} | ||||
|  | ||||
| 	ch <- data | ||||
|   | ||||
| @@ -1,9 +0,0 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	service "go.unistack.org/cms-service" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	service.RegisterService("pkgdash", NewService) | ||||
| } | ||||
| @@ -2,83 +2,65 @@ package service | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	cmsstorage "go.unistack.org/cms-service/storage" | ||||
| 	"database/sql" | ||||
| 	httpsrv "go.unistack.org/micro-server-http/v4" | ||||
| 	"go.unistack.org/micro/v4" | ||||
| 	"go.unistack.org/micro/v4/config" | ||||
| 	microcfg "go.unistack.org/micro/v4/config" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/micro/v4/options" | ||||
| 	"go.unistack.org/micro/v4/register" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| 	intcfg "go.unistack.org/unistack-org/pkgdash/config" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/handler" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/handler/encoders" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/service/client_git" | ||||
| 	"net/http" | ||||
|  | ||||
| 	//pbmicro "go.unistack.org/unistack-org/pkgdash/proto/micro" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage" | ||||
|  | ||||
| 	cmsservice "go.unistack.org/cms-service" | ||||
| 	"go.unistack.org/micro/v3" | ||||
| 	"go.unistack.org/micro/v3/config" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v3/register" | ||||
| 	microuter "go.unistack.org/micro/v3/router" | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func NewService(ctx context.Context) (micro.Service, error) { | ||||
| 	var reg register.Register | ||||
| 	var router microuter.Router | ||||
|  | ||||
| 	if ctx == nil { | ||||
| 		ctx = context.Background() | ||||
| 	} | ||||
|  | ||||
| 	cfg := intcfg.NewConfig() | ||||
| 	cs := cmsservice.NewConfigLocal(cfg) | ||||
|  | ||||
| 	if r, ok := register.FromContext(ctx); ok && r != nil { | ||||
| 		reg = r | ||||
| 	} else { | ||||
| 		reg = register.NewRegister() | ||||
| 	} | ||||
| 	if r, ok := microuter.FromContext(ctx); ok && r != nil { | ||||
| 		router = r | ||||
| 	} else { | ||||
| 		router = microuter.NewRouter() | ||||
| 	} | ||||
| 	cs := microcfg.NewConfig(config.Struct(cfg)) | ||||
|  | ||||
| 	svc := micro.NewService( | ||||
| 		micro.Register(reg), | ||||
| 		micro.Router(router), | ||||
| 		micro.Config(cs...), | ||||
| 	// TODO | ||||
| 	mgsrv := httpsrv.NewServer( | ||||
| 		options.Register(reg), | ||||
| 	) | ||||
|  | ||||
| 	writer, err := handler.NewWriter(encoders.NewJSONProto()) | ||||
| 	if err != nil { | ||||
| 		logger.Fatalf(ctx, "failed init writer: %v", err) | ||||
| 	} | ||||
| 	svc := micro.NewService( | ||||
| 		micro.Config(cs), | ||||
| 	) | ||||
|  | ||||
| 	h := handler.NewHandler(svc, writer, client_git.NewClient(5)) | ||||
| 	h := handler.NewHandler(svc, client_git.NewClient(5)) | ||||
|  | ||||
| 	if err = svc.Init( | ||||
| 	if err := svc.Init( | ||||
| 		micro.AfterStart(func(_ context.Context) error { | ||||
| 			return h.Init(svc.Options().Context) | ||||
| 		}), | ||||
| 		micro.BeforeStart(func(ctx context.Context) error { | ||||
| 			if err = config.Load(ctx, cs, config.LoadOverride(true)); err != nil { | ||||
| 			if err := config.Load(ctx, []config.Config{cs}, config.LoadOverride(true)); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if err = config.Validate(ctx, cfg); err != nil { | ||||
| 			if err := config.Validate(ctx, cfg); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if err = svc.Init( | ||||
| 				micro.Name(cfg.Service.Name), | ||||
| 				micro.Version(cfg.Service.Version), | ||||
| 			if err := svc.Init( | ||||
| 				micro.Name(intcfg.ServiceName), | ||||
| 				micro.Version(intcfg.ServiceVersion), | ||||
| 			); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if err = svc.Server("http").Init( | ||||
| 				server.Address(cfg.App.Address), | ||||
| 				server.Name(cfg.Service.Name), | ||||
| 				server.Version(cfg.Service.Version), | ||||
| 			if err := svc.Server("http").Init( | ||||
| 				options.Address(cfg.Address), | ||||
| 				options.Name(cfg.App.Name), | ||||
| 				server.Version(cfg.App.Version), | ||||
| 			); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| @@ -86,57 +68,66 @@ func NewService(ctx context.Context) (micro.Service, error) { | ||||
| 			return nil | ||||
| 		}), | ||||
| 		micro.BeforeStart(func(_ context.Context) error { | ||||
| 			level := logger.InfoLevel | ||||
| 			if v, ok := cfg.Logger.Level[cfg.Service.Name]; ok { | ||||
| 				level = logger.ParseLevel(v) | ||||
| 			} else if v, ok = cfg.Logger.Level["all"]; ok { | ||||
| 				level = logger.ParseLevel(v) | ||||
| 			} | ||||
| 			log := logger.NewLogger( | ||||
| 				logger.WithLevel(level), | ||||
| 				logger.WithLevel(logger.ParseLevel(cfg.LogLevel)), | ||||
| 				logger.WithCallerSkipCount(3), | ||||
| 			) | ||||
| 			return svc.Init(micro.Logger(log)) | ||||
| 		}), | ||||
| 		micro.BeforeStart(func(_ context.Context) error { | ||||
| 		micro.BeforeStart(func(ctx context.Context) error { | ||||
| 			var connstr string | ||||
| 			if v, ok := cfg.Storage.DSN[cfg.Service.Name]; ok { | ||||
| 			if v, ok := cfg.StorageDSN[cfg.App.Name]; ok { | ||||
| 				connstr = v | ||||
| 			} else if v, ok = cfg.Storage.DSN["all"]; ok { | ||||
| 			} else if v, ok = cfg.StorageDSN["all"]; ok { | ||||
| 				connstr = v | ||||
| 			} | ||||
| 			scheme, dsn, err := cmsstorage.StorageOptions(connstr) | ||||
|  | ||||
| 			scheme, dsn, err := storageOptions(connstr) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			db, dbok := cmsstorage.FromContext(svc.Options().Context) | ||||
| 			if !dbok { | ||||
| 				db, err = cmsstorage.NewStorage(scheme, dsn) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 			store, err := storage.NewStorage(scheme, db) | ||||
| 			conn, err := connectDataBase(scheme, dsn) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			return svc.Init(micro.Context(cmsstorage.InterfaceNewContext(svc.Options().Context, store))) | ||||
| 			store, err := storage.NewStorage(scheme, conn) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			ctx = storage.InContext(ctx, store) | ||||
| 			return svc.Init(micro.Context(ctx)) | ||||
| 		}), | ||||
| 	); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	mux := http.NewServeMux() | ||||
|  | ||||
| 	mux.HandleFunc("/listPackage", handler.Methods(http.MethodGet, h.ListPackage)) | ||||
| 	mux.HandleFunc("/updatePackage", handler.Methods(http.MethodPost, h.UpdatePackage)) | ||||
| 	mux.HandleFunc("/addComment", handler.Methods(http.MethodPut, h.AddComment)) | ||||
| 	mux.HandleFunc("/addPackage", handler.Methods(http.MethodPost, h.AddPackage)) | ||||
| 	mux.HandleFunc("/getModule", handler.Methods(http.MethodGet, h.GetModule)) | ||||
|  | ||||
| 	if err = svc.Server().Handle(svc.Server().NewHandler(mux)); err != nil { | ||||
| 	if err := pb.RegisterPkgdashServiceServer(mgsrv, h); err != nil { | ||||
| 		logger.Fatalf(ctx, "failed to register handler: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return svc, nil | ||||
| } | ||||
|  | ||||
| func storageOptions(dsn string) (string, string, error) { | ||||
| 	u, err := url.Parse(dsn) | ||||
| 	if err != nil { | ||||
| 		return "", "", err | ||||
| 	} | ||||
| 	scheme := u.Scheme | ||||
| 	if idx := strings.Index(u.Scheme, "+"); idx > 0 { | ||||
| 		scheme = u.Scheme[:idx] | ||||
| 		u.Scheme = u.Scheme[idx+1:] | ||||
| 	} | ||||
| 	return scheme, u.String(), nil | ||||
| } | ||||
|  | ||||
| func connectDataBase(driverName, dsn string) (*sql.DB, error) { | ||||
| 	conn, err := sql.Open(driverName, dsn) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err = conn.Ping(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return conn, err | ||||
| } | ||||
|   | ||||
| @@ -24,5 +24,9 @@ insert into package(name, url, modules) values ($1, $2, $3); | ||||
| insert into module(name, version, last_version)  values | ||||
| %s | ||||
| returning id; | ||||
| ` | ||||
| 	queryGetModule = ` | ||||
| select id, name, version, last_version from module | ||||
| where id in %s ; | ||||
| ` | ||||
| ) | ||||
| @@ -6,16 +6,16 @@ import ( | ||||
| 	"embed" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/golang-migrate/migrate/v4" | ||||
| 	mpgx "github.com/golang-migrate/migrate/v4/database/pgx" | ||||
| 	"github.com/golang-migrate/migrate/v4/source/iofs" | ||||
| 	"github.com/lib/pq" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/config" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/models" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -27,13 +27,9 @@ type Postgres struct { | ||||
| 	fs embed.FS | ||||
| } | ||||
|  | ||||
| func NewStorage(db *sql.DB) (interface{}, error) { | ||||
| 	return &Postgres{db: db}, nil | ||||
| } | ||||
|  | ||||
| func NewStorageFS(fs embed.FS) func(*sql.DB) (interface{}, error) { | ||||
| 	return func(db *sql.DB) (interface{}, error) { | ||||
| 		return &Postgres{db: db, fs: fs}, nil | ||||
| func NewStorage() func(*sql.DB, embed.FS) interface{} { | ||||
| 	return func(db *sql.DB, fs embed.FS) interface{} { | ||||
| 		return &Postgres{db: db, fs: fs} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -138,7 +134,7 @@ func (s *Postgres) AddComment(ctx context.Context, req *pb.AddCommentReq) error | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	res, err := tx.ExecContext(ctx, queryAddComment, req.Text, req.IdPackage.Value) | ||||
| 	res, err := tx.ExecContext(ctx, queryAddComment, req.Text, req.IdPackage) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -168,7 +164,7 @@ func (s *Postgres) AddPackage(ctx context.Context, req *pb.AddPackageReq) error | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	res, err := tx.ExecContext(ctx, queryAddPackage, req.Name.Value, req.Url.Value, pq.Array(req.Modules)) | ||||
| 	res, err := tx.ExecContext(ctx, queryAddPackage, req.Name, req.Url, pq.Array(req.Modules)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
| @@ -12,7 +12,7 @@ select | ||||
|     from package; | ||||
| ` | ||||
| 	queryAddComment = ` | ||||
| insert into comment(text) values ($1) ; | ||||
| insert into comment(text) values ($1) returning id; | ||||
| update package | ||||
| set comments = json_insert(comments, '$[#]', ( select last_insert_rowid() as id from comment )) | ||||
| where id = $2 ; | ||||
| @@ -28,5 +28,10 @@ returning id; | ||||
| 	queryGetModule = ` | ||||
| select id, name, version, last_version from module | ||||
| where id in %s ; | ||||
| ` | ||||
| 
 | ||||
| 	queryGetComments = ` | ||||
| select id, text, created, updated from comment | ||||
| where id in %s ; | ||||
| ` | ||||
| ) | ||||
| @@ -8,16 +8,15 @@ import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	_ "github.com/mattn/go-sqlite3" | ||||
|  | ||||
| 	"github.com/golang-migrate/migrate/v4" | ||||
| 	"github.com/golang-migrate/migrate/v4/database/sqlite" | ||||
| 	"github.com/golang-migrate/migrate/v4/source/iofs" | ||||
| 	"github.com/lib/pq" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	_ "github.com/mattn/go-sqlite3" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/config" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/models" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -29,13 +28,9 @@ type Sqlite struct { | ||||
| 	fs embed.FS | ||||
| } | ||||
|  | ||||
| func NewStorage(db *sql.DB) (interface{}, error) { | ||||
| 	return &Sqlite{db: db}, nil | ||||
| } | ||||
|  | ||||
| func NewStorageFS(fs embed.FS) func(*sql.DB) (interface{}, error) { | ||||
| 	return func(db *sql.DB) (interface{}, error) { | ||||
| 		return &Sqlite{db: db, fs: fs}, nil | ||||
| func NewStorage() func(*sql.DB, embed.FS) interface{} { | ||||
| 	return func(db *sql.DB, fs embed.FS) interface{} { | ||||
| 		return &Sqlite{db: db, fs: fs} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -124,10 +119,10 @@ func (s *Sqlite) ListPackage(ctx context.Context) (models.ListPackage, error) { | ||||
| 	return result, err | ||||
| } | ||||
|  | ||||
| func (s *Sqlite) AddComment(ctx context.Context, req *pb.AddCommentReq) error { | ||||
| func (s *Sqlite) AddComment(ctx context.Context, req *pb.AddCommentReq) (id uint64, err error) { | ||||
| 	tx, err := s.db.BeginTx(ctx, nil) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return 0, err | ||||
| 	} | ||||
|  | ||||
| 	defer func() { | ||||
| @@ -140,18 +135,11 @@ func (s *Sqlite) AddComment(ctx context.Context, req *pb.AddCommentReq) error { | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	res, err := tx.ExecContext(ctx, queryAddComment, req.Text, req.IdPackage.Value) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	if err = tx.QueryRowContext(ctx, queryAddComment, req.Text, req.IdPackage).Scan(&id); err != nil { | ||||
| 		return id, err | ||||
| 	} | ||||
|  | ||||
| 	if aff, affErr := res.RowsAffected(); err != nil { | ||||
| 		err = affErr | ||||
| 	} else if aff == 0 { | ||||
| 		err = errors.New("rows affected is 0") | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| 	return id, err | ||||
| } | ||||
|  | ||||
| func (s *Sqlite) AddPackage(ctx context.Context, req *pb.AddPackageReq) error { | ||||
| @@ -170,7 +158,7 @@ func (s *Sqlite) AddPackage(ctx context.Context, req *pb.AddPackageReq) error { | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	res, err := tx.ExecContext(ctx, queryAddPackage, req.Name.Value, req.Url.Value, pq.Array(req.Modules)) | ||||
| 	res, err := tx.ExecContext(ctx, queryAddPackage, req.Name, req.Url, pq.Array(req.Modules)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -261,6 +249,36 @@ func (s *Sqlite) GetModule(ctx context.Context, req *pb.GetModuleReq) (result mo | ||||
| 	return result, err | ||||
| } | ||||
|  | ||||
| func (s *Sqlite) GetComment(ctx context.Context, req *pb.GetCommentsReq) (result models.ListComment, err error) { | ||||
| 	query := fmt.Sprintf(queryGetComments, generateArrayIneq(len(req.Id))) | ||||
|  | ||||
| 	rows, err := s.db.QueryContext(ctx, query, convertSliceUInt(req.Id...)...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer func() { | ||||
| 		if err = rows.Close(); err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		err = rows.Err() | ||||
| 	}() | ||||
| 	for rows.Next() { | ||||
| 		tmp := &models.Comment{} | ||||
| 		if err = rows.Scan( | ||||
| 			&tmp.ID, | ||||
| 			&tmp.Text, | ||||
| 			&tmp.Created, | ||||
| 			&tmp.Updated, | ||||
| 		); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		result = append(result, tmp) | ||||
| 	} | ||||
|  | ||||
| 	return result, err | ||||
| } | ||||
|  | ||||
| func convertSliceUInt(arg ...uint64) []interface{} { | ||||
| 	result := make([]interface{}, 0, len(arg)) | ||||
| 	for i := range arg { | ||||
|   | ||||
| @@ -4,37 +4,68 @@ import ( | ||||
| 	"context" | ||||
| 	"database/sql" | ||||
| 	"embed" | ||||
| 	"errors" | ||||
|  | ||||
| 	"go.unistack.org/unistack-org/pkgdash/models" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage/postgres" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage/sqlite" | ||||
|  | ||||
| 	cmsstorage "go.unistack.org/cms-service/storage" | ||||
| ) | ||||
|  | ||||
| //go:embed migrations | ||||
| var fs embed.FS | ||||
|  | ||||
| var ( | ||||
| 	storages = cmsstorage.NewStorageInterface() | ||||
| 	storages = map[string]func(*sql.DB, embed.FS) interface{}{ | ||||
| 		"postgres": postgres.NewStorage(), | ||||
| 		"sqlite":   sqlite.NewStorage(), | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	storages.RegisterStorage("postgres", postgres.NewStorageFS(fs)) | ||||
| 	storages.RegisterStorage("sqlite", sqlite.NewStorageFS(fs)) | ||||
| type contextKey string | ||||
|  | ||||
| var ( | ||||
| 	storeIdent = contextKey("store") | ||||
| ) | ||||
|  | ||||
| type Migrate interface { | ||||
| 	MigrateUp() error | ||||
| 	MigrateDown() error | ||||
| } | ||||
|  | ||||
| type Storage interface { | ||||
| 	cmsstorage.Migrator | ||||
| 	Migrate | ||||
|  | ||||
| 	ListPackage(ctx context.Context) (models.ListPackage, error) | ||||
| 	UpdatePackage(ctx context.Context, req *pb.UpdatePackageReq) error | ||||
| 	AddComment(ctx context.Context, req *pb.AddCommentReq) error | ||||
| 	AddComment(ctx context.Context, req *pb.AddCommentReq) (uint64, error) | ||||
| 	AddPackage(ctx context.Context, req *pb.AddPackageReq) error | ||||
| 	InsertButchModules(ctx context.Context, req []models.Module) ([]uint64, error) | ||||
| 	GetModule(ctx context.Context, req *pb.GetModuleReq) (models.ListModule, error) | ||||
| 	GetComment(ctx context.Context, req *pb.GetCommentsReq) (models.ListComment, error) | ||||
| } | ||||
|  | ||||
| func NewStorage(name string, db *sql.DB) (interface{}, error) { | ||||
| 	return storages.NewStorage(name, db) | ||||
| func NewStorage(name string, db *sql.DB) (Storage, error) { | ||||
| 	function, ok := storages[name] | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("incorrect name store") | ||||
| 	} | ||||
| 	store := function(db, fs) | ||||
| 	database, ok := store.(Storage) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("dont implements interface Storage") | ||||
| 	} | ||||
| 	return database, nil | ||||
| } | ||||
|  | ||||
| func InContext(ctx context.Context, val Storage) context.Context { | ||||
| 	return context.WithValue(ctx, storeIdent, val) | ||||
| } | ||||
|  | ||||
| func FromContext(ctx context.Context) (Storage, error) { | ||||
| 	if store, ok := ctx.Value(storeIdent).(Storage); !ok { | ||||
| 		return nil, errors.New("empty store") | ||||
| 	} else { | ||||
| 		return store, nil | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import ( | ||||
| 	"context" | ||||
| 	"database/sql" | ||||
| 	"fmt" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" | ||||
| 	pb "go.unistack.org/unistack-org/pkgdash/proto" | ||||
| 	"go.unistack.org/unistack-org/pkgdash/storage/sqlite" | ||||
| 	"testing" | ||||
| ) | ||||
| @@ -19,18 +19,16 @@ func TestGetModule(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	st, err := sqlite.NewStorage(conn) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	st := sqlite.NewStorage() | ||||
| 	store := st(conn, fs) | ||||
|  | ||||
| 	s, ok := st.(Storage) | ||||
| 	s, ok := store.(Storage) | ||||
| 	if !ok { | ||||
| 		t.Fatal("typecast error") | ||||
| 		t.Fatal("dont implements interface Storage") | ||||
| 	} | ||||
|  | ||||
| 	req := &pb.GetModuleReq{ | ||||
| 		Id: []uint64{1, 2, 5, 40}, | ||||
| 		Id: []uint64{1, 2, 3}, | ||||
| 	} | ||||
|  | ||||
| 	module, err := s.GetModule(context.Background(), req) | ||||
| @@ -40,3 +38,31 @@ func TestGetModule(t *testing.T) { | ||||
|  | ||||
| 	fmt.Println(module) | ||||
| } | ||||
|  | ||||
| func TestGetComment(t *testing.T) { | ||||
| 	conn, err := sql.Open("sqlite3", "/Users/devstigneev_local/GolandProjects/unistack/pkgdash/identifier.sqlite") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer conn.Close() | ||||
| 	if err = conn.Ping(); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	st := sqlite.NewStorage() | ||||
| 	store := st(conn, fs) | ||||
|  | ||||
| 	s, ok := store.(Storage) | ||||
| 	if !ok { | ||||
| 		t.Fatal("dont implements interface Storage") | ||||
| 	} | ||||
|  | ||||
| 	req := &pb.GetCommentsReq{ | ||||
| 		Id: []uint64{1, 2, 3, 15}, | ||||
| 	} | ||||
| 	comments, err := s.GetComment(context.Background(), req) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	fmt.Println(comments.Decode()) | ||||
| } | ||||
|   | ||||
							
								
								
									
										16
									
								
								ui/.browserslistrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								ui/.browserslistrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. | ||||
| # For additional information regarding the format and rule options, please see: | ||||
| # https://github.com/browserslist/browserslist#queries | ||||
|  | ||||
| # For the full list of supported browsers by the Angular framework, please see: | ||||
| # https://angular.io/guide/browser-support | ||||
|  | ||||
| # You can see what browsers were selected by your queries by running: | ||||
| #   npx browserslist | ||||
|  | ||||
| last 1 Chrome version | ||||
| last 1 Firefox version | ||||
| last 2 Edge major versions | ||||
| last 2 Safari major versions | ||||
| last 2 iOS major versions | ||||
| Firefox ESR | ||||
							
								
								
									
										3
									
								
								ui/.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ui/.dockerignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| node_modules | ||||
| */node_modules | ||||
| **/node_modules | ||||
							
								
								
									
										16
									
								
								ui/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								ui/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| # Editor configuration, see https://editorconfig.org | ||||
| root = true | ||||
|  | ||||
| [*] | ||||
| charset = utf-8 | ||||
| indent_style = space | ||||
| indent_size = 2 | ||||
| insert_final_newline = true | ||||
| trim_trailing_whitespace = true | ||||
|  | ||||
| [*.ts] | ||||
| quote_type = single | ||||
|  | ||||
| [*.md] | ||||
| max_line_length = off | ||||
| trim_trailing_whitespace = false | ||||
							
								
								
									
										42
									
								
								ui/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								ui/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| # See http://help.github.com/ignore-files/ for more about ignoring files. | ||||
|  | ||||
| # Compiled output | ||||
| /dist | ||||
| /tmp | ||||
| /out-tsc | ||||
| /bazel-out | ||||
|  | ||||
| # Node | ||||
| /node_modules | ||||
| npm-debug.log | ||||
| yarn-error.log | ||||
|  | ||||
| # IDEs and editors | ||||
| .idea/ | ||||
| .project | ||||
| .classpath | ||||
| .c9/ | ||||
| *.launch | ||||
| .settings/ | ||||
| *.sublime-workspace | ||||
|  | ||||
| # Visual Studio Code | ||||
| .vscode/* | ||||
| !.vscode/settings.json | ||||
| !.vscode/tasks.json | ||||
| !.vscode/launch.json | ||||
| !.vscode/extensions.json | ||||
| .history/* | ||||
|  | ||||
| # Miscellaneous | ||||
| /.angular/cache | ||||
| .sass-cache/ | ||||
| /connect.lock | ||||
| /coverage | ||||
| /libpeerconnection.log | ||||
| testem.log | ||||
| /typings | ||||
|  | ||||
| # System files | ||||
| .DS_Store | ||||
| Thumbs.db | ||||
							
								
								
									
										27
									
								
								ui/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								ui/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| # Ui | ||||
|  | ||||
| This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.1.4. | ||||
|  | ||||
| ## Development server | ||||
|  | ||||
| Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. | ||||
|  | ||||
| ## Code scaffolding | ||||
|  | ||||
| Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. | ||||
|  | ||||
| ## Build | ||||
|  | ||||
| Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. | ||||
|  | ||||
| ## Running unit tests | ||||
|  | ||||
| Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). | ||||
|  | ||||
| ## Running end-to-end tests | ||||
|  | ||||
| Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. | ||||
|  | ||||
| ## Further help | ||||
|  | ||||
| To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. | ||||
							
								
								
									
										111
									
								
								ui/angular.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								ui/angular.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| { | ||||
|   "$schema": "./node_modules/@angular/cli/lib/config/schema.json", | ||||
|   "version": 1, | ||||
|   "newProjectRoot": "projects", | ||||
|   "projects": { | ||||
|     "ui": { | ||||
|       "projectType": "application", | ||||
|       "schematics": { | ||||
|         "@schematics/angular:component": { | ||||
|           "style": "scss" | ||||
|         }, | ||||
|         "@schematics/angular:application": { | ||||
|           "strict": true | ||||
|         } | ||||
|       }, | ||||
|       "root": "", | ||||
|       "sourceRoot": "src", | ||||
|       "prefix": "app", | ||||
|       "architect": { | ||||
|         "build": { | ||||
|           "builder": "@angular-devkit/build-angular:browser", | ||||
|           "options": { | ||||
|             "outputPath": "dist/ui", | ||||
|             "index": "src/index.html", | ||||
|             "main": "src/main.ts", | ||||
|             "polyfills": "src/polyfills.ts", | ||||
|             "tsConfig": "tsconfig.app.json", | ||||
|             "inlineStyleLanguage": "scss", | ||||
|             "assets": [ | ||||
|               "src/favicon.ico", | ||||
|               "src/assets" | ||||
|             ], | ||||
|             "styles": [ | ||||
|               "src/styles.scss" | ||||
|             ], | ||||
|             "scripts": [] | ||||
|           }, | ||||
|           "configurations": { | ||||
|             "production": { | ||||
|               "budgets": [ | ||||
|                 { | ||||
|                   "type": "initial", | ||||
|                   "maximumWarning": "500kb", | ||||
|                   "maximumError": "1mb" | ||||
|                 }, | ||||
|                 { | ||||
|                   "type": "anyComponentStyle", | ||||
|                   "maximumWarning": "2kb", | ||||
|                   "maximumError": "4kb" | ||||
|                 } | ||||
|               ], | ||||
|               "fileReplacements": [ | ||||
|                 { | ||||
|                   "replace": "src/environments/environment.ts", | ||||
|                   "with": "src/environments/environment.prod.ts" | ||||
|                 } | ||||
|               ], | ||||
|               "outputHashing": "all" | ||||
|             }, | ||||
|             "development": { | ||||
|               "buildOptimizer": false, | ||||
|               "optimization": false, | ||||
|               "vendorChunk": true, | ||||
|               "extractLicenses": false, | ||||
|               "sourceMap": true, | ||||
|               "namedChunks": true | ||||
|             } | ||||
|           }, | ||||
|           "defaultConfiguration": "production" | ||||
|         }, | ||||
|         "serve": { | ||||
|           "builder": "@angular-devkit/build-angular:dev-server", | ||||
|           "configurations": { | ||||
|             "production": { | ||||
|               "browserTarget": "ui:build:production" | ||||
|             }, | ||||
|             "development": { | ||||
|               "browserTarget": "ui:build:development" | ||||
|             } | ||||
|           }, | ||||
|           "defaultConfiguration": "development" | ||||
|         }, | ||||
|         "extract-i18n": { | ||||
|           "builder": "@angular-devkit/build-angular:extract-i18n", | ||||
|           "options": { | ||||
|             "browserTarget": "ui:build" | ||||
|           } | ||||
|         }, | ||||
|         "test": { | ||||
|           "builder": "@angular-devkit/build-angular:karma", | ||||
|           "options": { | ||||
|             "main": "src/test.ts", | ||||
|             "polyfills": "src/polyfills.ts", | ||||
|             "tsConfig": "tsconfig.spec.json", | ||||
|             "karmaConfig": "karma.conf.js", | ||||
|             "inlineStyleLanguage": "scss", | ||||
|             "assets": [ | ||||
|               "src/favicon.ico", | ||||
|               "src/assets" | ||||
|             ], | ||||
|             "styles": [ | ||||
|               "src/styles.scss" | ||||
|             ], | ||||
|             "scripts": [] | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "defaultProject": "ui" | ||||
| } | ||||
							
								
								
									
										44
									
								
								ui/karma.conf.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ui/karma.conf.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // Karma configuration file, see link for more information | ||||
| // https://karma-runner.github.io/1.0/config/configuration-file.html | ||||
|  | ||||
| module.exports = function (config) { | ||||
|   config.set({ | ||||
|     basePath: '', | ||||
|     frameworks: ['jasmine', '@angular-devkit/build-angular'], | ||||
|     plugins: [ | ||||
|       require('karma-jasmine'), | ||||
|       require('karma-chrome-launcher'), | ||||
|       require('karma-jasmine-html-reporter'), | ||||
|       require('karma-coverage'), | ||||
|       require('@angular-devkit/build-angular/plugins/karma') | ||||
|     ], | ||||
|     client: { | ||||
|       jasmine: { | ||||
|         // you can add configuration options for Jasmine here | ||||
|         // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html | ||||
|         // for example, you can disable the random execution with `random: false` | ||||
|         // or set a specific seed with `seed: 4321` | ||||
|       }, | ||||
|       clearContext: false // leave Jasmine Spec Runner output visible in browser | ||||
|     }, | ||||
|     jasmineHtmlReporter: { | ||||
|       suppressAll: true // removes the duplicated traces | ||||
|     }, | ||||
|     coverageReporter: { | ||||
|       dir: require('path').join(__dirname, './coverage/ui'), | ||||
|       subdir: '.', | ||||
|       reporters: [ | ||||
|         { type: 'html' }, | ||||
|         { type: 'text-summary' } | ||||
|       ] | ||||
|     }, | ||||
|     reporters: ['progress', 'kjhtml'], | ||||
|     port: 9876, | ||||
|     colors: true, | ||||
|     logLevel: config.LOG_INFO, | ||||
|     autoWatch: true, | ||||
|     browsers: ['Chrome'], | ||||
|     singleRun: false, | ||||
|     restartOnFileChange: true | ||||
|   }); | ||||
| }; | ||||
							
								
								
									
										11976
									
								
								ui/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										11976
									
								
								ui/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										40
									
								
								ui/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								ui/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| { | ||||
|   "name": "ui", | ||||
|   "version": "0.0.0", | ||||
|   "scripts": { | ||||
|     "ng": "ng", | ||||
|     "start": "ng serve", | ||||
|     "build": "ng build", | ||||
|     "watch": "ng build --watch --configuration development", | ||||
|     "test": "ng test" | ||||
|   }, | ||||
|   "private": true, | ||||
|   "dependencies": { | ||||
|     "@angular/animations": "~13.1.0", | ||||
|     "@angular/common": "~13.1.0", | ||||
|     "@angular/compiler": "~13.1.0", | ||||
|     "@angular/core": "~13.1.0", | ||||
|     "@angular/forms": "~13.1.0", | ||||
|     "@angular/platform-browser": "~13.1.0", | ||||
|     "@angular/platform-browser-dynamic": "~13.1.0", | ||||
|     "@angular/router": "~13.1.0", | ||||
|     "ng-openapi-gen": "^0.25.1", | ||||
|     "rxjs": "~7.4.0", | ||||
|     "tslib": "^2.3.0", | ||||
|     "zone.js": "~0.11.4" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@angular-devkit/build-angular": "~13.1.4", | ||||
|     "@angular/cli": "~13.1.4", | ||||
|     "@angular/compiler-cli": "~13.1.0", | ||||
|     "@types/jasmine": "~3.10.0", | ||||
|     "@types/node": "^12.11.1", | ||||
|     "jasmine-core": "~3.10.0", | ||||
|     "karma": "~6.3.0", | ||||
|     "karma-chrome-launcher": "~3.1.0", | ||||
|     "karma-coverage": "~2.1.0", | ||||
|     "karma-jasmine": "~4.0.0", | ||||
|     "karma-jasmine-html-reporter": "~1.7.0", | ||||
|     "typescript": "~4.5.2" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										20
									
								
								ui/src/app/api/api-configuration.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								ui/src/app/api/api-configuration.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { Injectable } from '@angular/core'; | ||||
|  | ||||
| /** | ||||
|  * Global configuration | ||||
|  */ | ||||
| @Injectable({ | ||||
|   providedIn: 'root', | ||||
| }) | ||||
| export class ApiConfiguration { | ||||
|   rootUrl: string = ''; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Parameters for `ApiModule.forRoot()` | ||||
|  */ | ||||
| export interface ApiConfigurationParams { | ||||
|   rootUrl?: string; | ||||
| } | ||||
							
								
								
									
										46
									
								
								ui/src/app/api/api.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								ui/src/app/api/api.module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; | ||||
| import { HttpClient } from '@angular/common/http'; | ||||
| import { ApiConfiguration, ApiConfigurationParams } from './api-configuration'; | ||||
|  | ||||
| import { PkgdashServiceService } from './services/pkgdash-service.service'; | ||||
|  | ||||
| /** | ||||
|  * Module that provides all services and configuration. | ||||
|  */ | ||||
| @NgModule({ | ||||
|   imports: [], | ||||
|   exports: [], | ||||
|   declarations: [], | ||||
|   providers: [ | ||||
|     PkgdashServiceService, | ||||
|     ApiConfiguration | ||||
|   ], | ||||
| }) | ||||
| export class ApiModule { | ||||
|   static forRoot(params: ApiConfigurationParams): ModuleWithProviders<ApiModule> { | ||||
|     return { | ||||
|       ngModule: ApiModule, | ||||
|       providers: [ | ||||
|         { | ||||
|           provide: ApiConfiguration, | ||||
|           useValue: params | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   constructor(  | ||||
|     @Optional() @SkipSelf() parentModule: ApiModule, | ||||
|     @Optional() http: HttpClient | ||||
|   ) { | ||||
|     if (parentModule) { | ||||
|       throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); | ||||
|     } | ||||
|     if (!http) { | ||||
|       throw new Error('You need to import the HttpClientModule in your AppModule! \n' + | ||||
|       'See also https://github.com/angular/angular/issues/20575'); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										34
									
								
								ui/src/app/api/base-service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ui/src/app/api/base-service.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { HttpClient } from '@angular/common/http'; | ||||
| import { ApiConfiguration } from './api-configuration'; | ||||
|  | ||||
| /** | ||||
|  * Base class for services | ||||
|  */ | ||||
| @Injectable() | ||||
| export class BaseService { | ||||
|   constructor( | ||||
|     protected config: ApiConfiguration, | ||||
|     protected http: HttpClient | ||||
|   ) { | ||||
|   } | ||||
|  | ||||
|   private _rootUrl: string = ''; | ||||
|  | ||||
|   /** | ||||
|    * Returns the root url for all operations in this service. If not set directly in this | ||||
|    * service, will fallback to `ApiConfiguration.rootUrl`. | ||||
|    */ | ||||
|   get rootUrl(): string { | ||||
|     return this._rootUrl || this.config.rootUrl; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Sets the root URL for API operations in this service. | ||||
|    */ | ||||
|   set rootUrl(rootUrl: string) { | ||||
|     this._rootUrl = rootUrl; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										16
									
								
								ui/src/app/api/models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								ui/src/app/api/models.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export { AddCommentReq } from './models/add-comment-req'; | ||||
| export { AddCommentRsp } from './models/add-comment-rsp'; | ||||
| export { AddPackageReq } from './models/add-package-req'; | ||||
| export { AddPackageRsp } from './models/add-package-rsp'; | ||||
| export { Comment } from './models/comment'; | ||||
| export { Error } from './models/error'; | ||||
| export { ErrorRsp } from './models/error-rsp'; | ||||
| export { GetCommentsRsp } from './models/get-comments-rsp'; | ||||
| export { GetModuleRsp } from './models/get-module-rsp'; | ||||
| export { ListPackageRsp } from './models/list-package-rsp'; | ||||
| export { Module } from './models/module'; | ||||
| export { Package } from './models/package'; | ||||
| export { UpdatePackageReq } from './models/update-package-req'; | ||||
| export { UpdatePackageRsp } from './models/update-package-rsp'; | ||||
							
								
								
									
										6
									
								
								ui/src/app/api/models/add-comment-req.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ui/src/app/api/models/add-comment-req.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface AddCommentReq { | ||||
|   idPackage?: number; | ||||
|   text?: string; | ||||
| } | ||||
							
								
								
									
										5
									
								
								ui/src/app/api/models/add-comment-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ui/src/app/api/models/add-comment-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface AddCommentRsp { | ||||
|   id?: number; | ||||
| } | ||||
							
								
								
									
										7
									
								
								ui/src/app/api/models/add-package-req.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								ui/src/app/api/models/add-package-req.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface AddPackageReq { | ||||
|   modules?: Array<number>; | ||||
|   name?: string; | ||||
|   url?: string; | ||||
| } | ||||
							
								
								
									
										5
									
								
								ui/src/app/api/models/add-package-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ui/src/app/api/models/add-package-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface AddPackageRsp { | ||||
|   status?: string; | ||||
| } | ||||
							
								
								
									
										9
									
								
								ui/src/app/api/models/comment.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								ui/src/app/api/models/comment.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface Comment { | ||||
|   created?: string; | ||||
|   id?: number; | ||||
|   package?: number; | ||||
|   text?: string; | ||||
|   updated?: string; | ||||
| } | ||||
							
								
								
									
										6
									
								
								ui/src/app/api/models/error-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ui/src/app/api/models/error-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { Error } from './error'; | ||||
| export interface ErrorRsp { | ||||
|   error?: Error; | ||||
| } | ||||
							
								
								
									
										8
									
								
								ui/src/app/api/models/error.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ui/src/app/api/models/error.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface Error { | ||||
|   code?: string; | ||||
|   details?: string; | ||||
|   title?: string; | ||||
|   uuid?: string; | ||||
| } | ||||
							
								
								
									
										6
									
								
								ui/src/app/api/models/get-comments-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ui/src/app/api/models/get-comments-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { Comment } from './comment'; | ||||
| export interface GetCommentsRsp { | ||||
|   comments?: Array<Comment>; | ||||
| } | ||||
							
								
								
									
										6
									
								
								ui/src/app/api/models/get-module-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ui/src/app/api/models/get-module-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { Module } from './module'; | ||||
| export interface GetModuleRsp { | ||||
|   modules?: Array<Module>; | ||||
| } | ||||
							
								
								
									
										6
									
								
								ui/src/app/api/models/list-package-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ui/src/app/api/models/list-package-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { Package } from './package'; | ||||
| export interface ListPackageRsp { | ||||
|   packages?: Array<Package>; | ||||
| } | ||||
							
								
								
									
										9
									
								
								ui/src/app/api/models/module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								ui/src/app/api/models/module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface Module { | ||||
|   id?: number; | ||||
|   last_version?: string; | ||||
|   name?: string; | ||||
|   package?: number; | ||||
|   version?: string; | ||||
| } | ||||
							
								
								
									
										10
									
								
								ui/src/app/api/models/package.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ui/src/app/api/models/package.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface Package { | ||||
|   comments?: Array<number>; | ||||
|   id?: number; | ||||
|   issues?: Array<number>; | ||||
|   modules?: Array<number>; | ||||
|   name?: string; | ||||
|   url?: string; | ||||
| } | ||||
							
								
								
									
										9
									
								
								ui/src/app/api/models/update-package-req.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								ui/src/app/api/models/update-package-req.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface UpdatePackageReq { | ||||
|   id?: number; | ||||
|   issues?: Array<number>; | ||||
|   modules?: Array<number>; | ||||
|   name?: string; | ||||
|   url?: string; | ||||
| } | ||||
							
								
								
									
										5
									
								
								ui/src/app/api/models/update-package-rsp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ui/src/app/api/models/update-package-rsp.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export interface UpdatePackageRsp { | ||||
|   id?: number; | ||||
| } | ||||
							
								
								
									
										368
									
								
								ui/src/app/api/request-builder.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								ui/src/app/api/request-builder.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { HttpRequest, HttpParameterCodec, HttpParams, HttpHeaders, HttpContext } from '@angular/common/http'; | ||||
|  | ||||
| /** | ||||
|  * Custom parameter codec to correctly handle the plus sign in parameter | ||||
|  * values. See https://github.com/angular/angular/issues/18261 | ||||
|  */ | ||||
| class ParameterCodec implements HttpParameterCodec { | ||||
|   encodeKey(key: string): string { | ||||
|     return encodeURIComponent(key); | ||||
|   } | ||||
|  | ||||
|   encodeValue(value: string): string { | ||||
|     return encodeURIComponent(value); | ||||
|   } | ||||
|  | ||||
|   decodeKey(key: string): string { | ||||
|     return decodeURIComponent(key); | ||||
|   } | ||||
|  | ||||
|   decodeValue(value: string): string { | ||||
|     return decodeURIComponent(value); | ||||
|   } | ||||
| } | ||||
| const ParameterCodecInstance = new ParameterCodec(); | ||||
|  | ||||
| /** | ||||
|  * Defines the options for appending a parameter | ||||
|  */ | ||||
| interface ParameterOptions { | ||||
|   style?: string; | ||||
|   explode?: boolean; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Base class for a parameter | ||||
|  */ | ||||
| abstract class Parameter { | ||||
|   constructor(public name: string, public value: any, public options: ParameterOptions, defaultStyle: string, defaultExplode: boolean) { | ||||
|     this.options = options || {}; | ||||
|     if (this.options.style === null || this.options.style === undefined) { | ||||
|       this.options.style = defaultStyle; | ||||
|     } | ||||
|     if (this.options.explode === null || this.options.explode === undefined) { | ||||
|       this.options.explode = defaultExplode; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   serializeValue(value: any, separator = ','): string { | ||||
|     if (value === null || value === undefined) { | ||||
|       return ''; | ||||
|     } else if (value instanceof Array) { | ||||
|       return value.map(v => this.serializeValue(v).split(separator).join(encodeURIComponent(separator))).join(separator); | ||||
|     } else if (typeof value === 'object') { | ||||
|       const array: string[] = []; | ||||
|       for (const key of Object.keys(value)) { | ||||
|         let propVal = value[key]; | ||||
|         if (propVal !== null && propVal !== undefined) { | ||||
|           propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator)); | ||||
|           if (this.options.explode) { | ||||
|             array.push(`${key}=${propVal}`); | ||||
|           } else { | ||||
|             array.push(key); | ||||
|             array.push(propVal); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       return array.join(separator); | ||||
|     } else { | ||||
|       return String(value); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * A parameter in the operation path | ||||
|  */ | ||||
| class PathParameter extends Parameter { | ||||
|   constructor(name: string, value: any, options: ParameterOptions) { | ||||
|     super(name, value, options, 'simple', false); | ||||
|   } | ||||
|  | ||||
|   append(path: string): string { | ||||
|     let value = this.value; | ||||
|     if (value === null || value === undefined) { | ||||
|       value = ''; | ||||
|     } | ||||
|     let prefix = this.options.style === 'label' ? '.' : ''; | ||||
|     let separator = this.options.explode ? prefix === '' ? ',' : prefix : ','; | ||||
|     let alreadySerialized = false; | ||||
|     if (this.options.style === 'matrix') { | ||||
|       // The parameter name is just used as prefix, except in some cases... | ||||
|       prefix = `;${this.name}=`; | ||||
|       if (this.options.explode && typeof value === 'object') { | ||||
|         prefix = ';'; | ||||
|         if (value instanceof Array) { | ||||
|           // For arrays we have to repeat the name for each element | ||||
|           value = value.map(v => `${this.name}=${this.serializeValue(v, ';')}`); | ||||
|           value = value.join(';'); | ||||
|           alreadySerialized = true; | ||||
|         } else { | ||||
|           // For objects we have to put each the key / value pairs | ||||
|           value = this.serializeValue(value, ';'); | ||||
|           alreadySerialized = true | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator)); | ||||
|     // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account | ||||
|     path = path.replace(`{${this.name}}`, value); | ||||
|     path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value); | ||||
|     return path; | ||||
|   } | ||||
|  | ||||
|   // @ts-ignore | ||||
|   serializeValue(value: any, separator = ','): string { | ||||
|     var result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator); | ||||
|     result = result.replace(/%3D/g, '='); | ||||
|     result = result.replace(/%3B/g, ';'); | ||||
|     result = result.replace(/%2C/g, ','); | ||||
|     return result; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * A parameter in the query | ||||
|  */ | ||||
| class QueryParameter extends Parameter { | ||||
|   constructor(name: string, value: any, options: ParameterOptions) { | ||||
|     super(name, value, options, 'form', true); | ||||
|   } | ||||
|  | ||||
|   append(params: HttpParams): HttpParams { | ||||
|     if (this.value instanceof Array) { | ||||
|       // Array serialization | ||||
|       if (this.options.explode) { | ||||
|         for (const v of this.value) { | ||||
|           params = params.append(this.name, this.serializeValue(v)); | ||||
|         } | ||||
|       } else { | ||||
|         const separator = this.options.style === 'spaceDelimited' | ||||
|           ? ' ' : this.options.style === 'pipeDelimited' | ||||
|             ? '|' : ','; | ||||
|         return params.append(this.name, this.serializeValue(this.value, separator)); | ||||
|       } | ||||
|     } else if (this.value !== null && typeof this.value === 'object') { | ||||
|       // Object serialization | ||||
|       if (this.options.style === 'deepObject') { | ||||
|         // Append a parameter for each key, in the form `name[key]` | ||||
|         for (const key of Object.keys(this.value)) { | ||||
|           const propVal = this.value[key]; | ||||
|           if (propVal !== null && propVal !== undefined) { | ||||
|             params = params.append(`${this.name}[${key}]`, this.serializeValue(propVal)); | ||||
|           } | ||||
|         } | ||||
|       } else if (this.options.explode) { | ||||
|         // Append a parameter for each key without using the parameter name | ||||
|         for (const key of Object.keys(this.value)) { | ||||
|           const propVal = this.value[key]; | ||||
|           if (propVal !== null && propVal !== undefined) { | ||||
|             params = params.append(key, this.serializeValue(propVal)); | ||||
|           } | ||||
|         } | ||||
|       } else { | ||||
|         // Append a single parameter whose values are a comma-separated list of key,value,key,value... | ||||
|         const array: any[] = []; | ||||
|         for (const key of Object.keys(this.value)) { | ||||
|           const propVal = this.value[key]; | ||||
|           if (propVal !== null && propVal !== undefined) { | ||||
|             array.push(key); | ||||
|             array.push(propVal); | ||||
|           } | ||||
|         } | ||||
|         params = params.append(this.name, this.serializeValue(array)); | ||||
|       } | ||||
|     } else if (this.value !== null && this.value !== undefined) { | ||||
|       // Plain value | ||||
|       params = params.append(this.name, this.serializeValue(this.value)); | ||||
|     } | ||||
|     return params; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * A parameter in the HTTP request header | ||||
|  */ | ||||
| class HeaderParameter extends Parameter { | ||||
|   constructor(name: string, value: any, options: ParameterOptions) { | ||||
|     super(name, value, options, 'simple', false); | ||||
|   } | ||||
|  | ||||
|   append(headers: HttpHeaders): HttpHeaders { | ||||
|     if (this.value !== null && this.value !== undefined) { | ||||
|       if (this.value instanceof Array) { | ||||
|         for (const v of this.value) { | ||||
|           headers = headers.append(this.name, this.serializeValue(v)); | ||||
|         } | ||||
|       } else { | ||||
|         headers = headers.append(this.name, this.serializeValue(this.value)); | ||||
|       } | ||||
|     } | ||||
|     return headers; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Helper to build http requests from parameters | ||||
|  */ | ||||
| export class RequestBuilder { | ||||
|  | ||||
|   private _path = new Map<string, PathParameter>(); | ||||
|   private _query = new Map<string, QueryParameter>(); | ||||
|   private _header = new Map<string, HeaderParameter>(); | ||||
|   _bodyContent: any | null; | ||||
|   _bodyContentType?: string; | ||||
|  | ||||
|   constructor( | ||||
|     public rootUrl: string, | ||||
|     public operationPath: string, | ||||
|     public method: string) { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Sets a path parameter | ||||
|    */ | ||||
|   path(name: string, value: any, options?: ParameterOptions): void { | ||||
|     this._path.set(name, new PathParameter(name, value, options || {})); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Sets a query parameter | ||||
|    */ | ||||
|   query(name: string, value: any, options?: ParameterOptions): void { | ||||
|     this._query.set(name, new QueryParameter(name, value, options || {})); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Sets a header parameter | ||||
|    */ | ||||
|   header(name: string, value: any, options?: ParameterOptions): void { | ||||
|     this._header.set(name, new HeaderParameter(name, value, options || {})); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Sets the body content, along with the content type | ||||
|    */ | ||||
|   body(value: any, contentType = 'application/json'): void { | ||||
|     if (value instanceof Blob) { | ||||
|       this._bodyContentType = value.type; | ||||
|     } else { | ||||
|       this._bodyContentType = contentType; | ||||
|     } | ||||
|     if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') { | ||||
|       // Handle URL-encoded data | ||||
|       const pairs: Array<[string, string]> = []; | ||||
|       for (const key of Object.keys(value)) { | ||||
|         let val = value[key]; | ||||
|         if (!(val instanceof Array)) { | ||||
|           val = [val]; | ||||
|         } | ||||
|         for (const v of val) { | ||||
|           const formValue = this.formDataValue(v); | ||||
|           if (formValue !== null) { | ||||
|             pairs.push([key, formValue]); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       this._bodyContent = pairs.map(p => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&'); | ||||
|     } else if (this._bodyContentType === 'multipart/form-data') { | ||||
|       // Handle multipart form data | ||||
|       const formData = new FormData(); | ||||
|       if (value !== null && value !== undefined) { | ||||
|         for (const key of Object.keys(value)) { | ||||
|           const val = value[key]; | ||||
|           if (val instanceof Array) { | ||||
|             for (const v of val) { | ||||
|               const toAppend = this.formDataValue(v); | ||||
|               if (toAppend !== null) { | ||||
|                 formData.append(key, toAppend); | ||||
|               } | ||||
|             } | ||||
|           } else { | ||||
|             const toAppend = this.formDataValue(val); | ||||
|             if (toAppend !== null) { | ||||
|               formData.set(key, toAppend); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       this._bodyContent = formData; | ||||
|     } else { | ||||
|       // The body is the plain content | ||||
|       this._bodyContent = value; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private formDataValue(value: any): any { | ||||
|     if (value === null || value === undefined) { | ||||
|       return null; | ||||
|     } | ||||
|     if (value instanceof Blob) { | ||||
|       return value; | ||||
|     } | ||||
|     if (typeof value === 'object') { | ||||
|       return JSON.stringify(value); | ||||
|     } | ||||
|     return String(value); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Builds the request with the current set parameters | ||||
|    */ | ||||
|   build<T = any>(options?: { | ||||
|     /** Which content types to accept */ | ||||
|     accept?: string; | ||||
|  | ||||
|     /** The expected response type */ | ||||
|     responseType?: 'json' | 'text' | 'blob' | 'arraybuffer'; | ||||
|  | ||||
|     /** Whether to report progress on uploads / downloads */ | ||||
|     reportProgress?: boolean; | ||||
|  | ||||
|     /** Allow passing HttpContext for HttpClient */ | ||||
|     context?: HttpContext; | ||||
|   }): HttpRequest<T> { | ||||
|  | ||||
|     options = options || {}; | ||||
|  | ||||
|     // Path parameters | ||||
|     let path = this.operationPath; | ||||
|     for (const pathParam of this._path.values()) { | ||||
|       path = pathParam.append(path); | ||||
|     } | ||||
|     const url = this.rootUrl + path; | ||||
|  | ||||
|     // Query parameters | ||||
|     let httpParams = new HttpParams({ | ||||
|       encoder: ParameterCodecInstance | ||||
|     }); | ||||
|     for (const queryParam of this._query.values()) { | ||||
|       httpParams = queryParam.append(httpParams); | ||||
|     } | ||||
|  | ||||
|     // Header parameters | ||||
|     let httpHeaders = new HttpHeaders(); | ||||
|     if (options.accept) { | ||||
|       httpHeaders = httpHeaders.append('Accept', options.accept); | ||||
|     } | ||||
|     for (const headerParam of this._header.values()) { | ||||
|       httpHeaders = headerParam.append(httpHeaders); | ||||
|     } | ||||
|  | ||||
|     // Request content headers | ||||
|     if (this._bodyContentType && !(this._bodyContent instanceof FormData)) { | ||||
|       httpHeaders = httpHeaders.set('Content-Type', this._bodyContentType); | ||||
|     } | ||||
|  | ||||
|     // Perform the request | ||||
|     return new HttpRequest<T>(this.method.toUpperCase(), url, this._bodyContent, { | ||||
|       params: httpParams, | ||||
|       headers: httpHeaders, | ||||
|       responseType: options.responseType, | ||||
|       reportProgress: options.reportProgress, | ||||
|       context: options.context | ||||
|     }); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										1
									
								
								ui/src/app/api/services.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ui/src/app/api/services.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export { PkgdashServiceService } from './services/pkgdash-service.service'; | ||||
							
								
								
									
										314
									
								
								ui/src/app/api/services/pkgdash-service.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								ui/src/app/api/services/pkgdash-service.service.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,314 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { HttpClient, HttpContext, HttpResponse } from '@angular/common/http'; | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { filter, map } from 'rxjs/operators'; | ||||
|  | ||||
| import { BaseService } from '../base-service'; | ||||
| import { ApiConfiguration } from '../api-configuration'; | ||||
| import { StrictHttpResponse } from '../strict-http-response'; | ||||
| import { RequestBuilder } from '../request-builder'; | ||||
|  | ||||
| import { AddCommentReq } from '../models/add-comment-req'; | ||||
| import { AddCommentRsp } from '../models/add-comment-rsp'; | ||||
| import { AddPackageReq } from '../models/add-package-req'; | ||||
| import { AddPackageRsp } from '../models/add-package-rsp'; | ||||
| import { GetCommentsRsp } from '../models/get-comments-rsp'; | ||||
| import { GetModuleRsp } from '../models/get-module-rsp'; | ||||
| import { ListPackageRsp } from '../models/list-package-rsp'; | ||||
| import { UpdatePackageReq } from '../models/update-package-req'; | ||||
| import { UpdatePackageRsp } from '../models/update-package-rsp'; | ||||
|  | ||||
| @Injectable({ providedIn: 'root' }) | ||||
| export class PkgdashServiceService extends BaseService { | ||||
|   constructor(config: ApiConfiguration, http: HttpClient) { | ||||
|     super(config, http); | ||||
|   } | ||||
|  | ||||
|   /** Path part for operation `getComments()` */ | ||||
|   static readonly GetCommentsPath = '/v1/comment'; | ||||
|  | ||||
|   /** | ||||
|    * This method provides access to the full `HttpResponse`, allowing access to response headers. | ||||
|    * To access only the response body, use `getComments()` instead. | ||||
|    * | ||||
|    * This method doesn't expect any request body. | ||||
|    */ | ||||
|   getComments$Response( | ||||
|     params?: { | ||||
|       id?: Array<number>; | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<StrictHttpResponse<GetCommentsRsp>> { | ||||
|     const rb = new RequestBuilder(this.rootUrl, PkgdashServiceService.GetCommentsPath, 'get'); | ||||
|     if (params) { | ||||
|       rb.query('id', params.id, {}); | ||||
|     } | ||||
|  | ||||
|     return this.http.request( | ||||
|       rb.build({ responseType: 'json', accept: 'application/json', context }) | ||||
|     ).pipe( | ||||
|       filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse), | ||||
|       map((r: HttpResponse<any>) => { | ||||
|         return r as StrictHttpResponse<GetCommentsRsp>; | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This method provides access only to the response body. | ||||
|    * To access the full response (for headers, for example), `getComments$Response()` instead. | ||||
|    * | ||||
|    * This method doesn't expect any request body. | ||||
|    */ | ||||
|   getComments( | ||||
|     params?: { | ||||
|       id?: Array<number>; | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<GetCommentsRsp> { | ||||
|     return this.getComments$Response(params, context).pipe( | ||||
|       map((r: StrictHttpResponse<GetCommentsRsp>): GetCommentsRsp => r.body) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** Path part for operation `getModule()` */ | ||||
|   static readonly GetModulePath = '/v1/module'; | ||||
|  | ||||
|   /** | ||||
|    * This method provides access to the full `HttpResponse`, allowing access to response headers. | ||||
|    * To access only the response body, use `getModule()` instead. | ||||
|    * | ||||
|    * This method doesn't expect any request body. | ||||
|    */ | ||||
|   getModule$Response( | ||||
|     params?: { | ||||
|       id?: Array<number>; | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<StrictHttpResponse<GetModuleRsp>> { | ||||
|     const rb = new RequestBuilder(this.rootUrl, PkgdashServiceService.GetModulePath, 'get'); | ||||
|     if (params) { | ||||
|       rb.query('id', params.id, {}); | ||||
|     } | ||||
|  | ||||
|     return this.http.request( | ||||
|       rb.build({ responseType: 'json', accept: 'application/json', context }) | ||||
|     ).pipe( | ||||
|       filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse), | ||||
|       map((r: HttpResponse<any>) => { | ||||
|         return r as StrictHttpResponse<GetModuleRsp>; | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This method provides access only to the response body. | ||||
|    * To access the full response (for headers, for example), `getModule$Response()` instead. | ||||
|    * | ||||
|    * This method doesn't expect any request body. | ||||
|    */ | ||||
|   getModule( | ||||
|     params?: { | ||||
|       id?: Array<number>; | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<GetModuleRsp> { | ||||
|     return this.getModule$Response(params, context).pipe( | ||||
|       map((r: StrictHttpResponse<GetModuleRsp>): GetModuleRsp => r.body) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** Path part for operation `addPackage()` */ | ||||
|   static readonly AddPackagePath = '/v1/package'; | ||||
|  | ||||
|   /** | ||||
|    * This method provides access to the full `HttpResponse`, allowing access to response headers. | ||||
|    * To access only the response body, use `addPackage()` instead. | ||||
|    * | ||||
|    * This method sends `application/json` and handles request body of type `application/json`. | ||||
|    */ | ||||
|   addPackage$Response( | ||||
|     params: { | ||||
|       body: AddPackageReq | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<StrictHttpResponse<AddPackageRsp>> { | ||||
|     const rb = new RequestBuilder(this.rootUrl, PkgdashServiceService.AddPackagePath, 'post'); | ||||
|     if (params) { | ||||
|       rb.body(params.body, 'application/json'); | ||||
|     } | ||||
|  | ||||
|     return this.http.request( | ||||
|       rb.build({ responseType: 'json', accept: 'application/json', context }) | ||||
|     ).pipe( | ||||
|       filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse), | ||||
|       map((r: HttpResponse<any>) => { | ||||
|         return r as StrictHttpResponse<AddPackageRsp>; | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This method provides access only to the response body. | ||||
|    * To access the full response (for headers, for example), `addPackage$Response()` instead. | ||||
|    * | ||||
|    * This method sends `application/json` and handles request body of type `application/json`. | ||||
|    */ | ||||
|   addPackage( | ||||
|     params: { | ||||
|       body: AddPackageReq | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<AddPackageRsp> { | ||||
|     return this.addPackage$Response(params, context).pipe( | ||||
|       map((r: StrictHttpResponse<AddPackageRsp>): AddPackageRsp => r.body) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** Path part for operation `updateInfo()` */ | ||||
|   static readonly UpdateInfoPath = '/v1/package/{id}'; | ||||
|  | ||||
|   /** | ||||
|    * This method provides access to the full `HttpResponse`, allowing access to response headers. | ||||
|    * To access only the response body, use `updateInfo()` instead. | ||||
|    * | ||||
|    * This method sends `application/json` and handles request body of type `application/json`. | ||||
|    */ | ||||
|   updateInfo$Response( | ||||
|     params: { | ||||
|       id: number; | ||||
|       body: UpdatePackageReq | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<StrictHttpResponse<UpdatePackageRsp>> { | ||||
|     const rb = new RequestBuilder(this.rootUrl, PkgdashServiceService.UpdateInfoPath, 'post'); | ||||
|     if (params) { | ||||
|       rb.path('id', params.id, {}); | ||||
|       rb.body(params.body, 'application/json'); | ||||
|     } | ||||
|  | ||||
|     return this.http.request( | ||||
|       rb.build({ responseType: 'json', accept: 'application/json', context }) | ||||
|     ).pipe( | ||||
|       filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse), | ||||
|       map((r: HttpResponse<any>) => { | ||||
|         return r as StrictHttpResponse<UpdatePackageRsp>; | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This method provides access only to the response body. | ||||
|    * To access the full response (for headers, for example), `updateInfo$Response()` instead. | ||||
|    * | ||||
|    * This method sends `application/json` and handles request body of type `application/json`. | ||||
|    */ | ||||
|   updateInfo( | ||||
|     params: { | ||||
|       id: number; | ||||
|       body: UpdatePackageReq | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<UpdatePackageRsp> { | ||||
|     return this.updateInfo$Response(params, context).pipe( | ||||
|       map((r: StrictHttpResponse<UpdatePackageRsp>): UpdatePackageRsp => r.body) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** Path part for operation `addComment()` */ | ||||
|   static readonly AddCommentPath = '/v1/package/{pkg}/comment'; | ||||
|  | ||||
|   /** | ||||
|    * This method provides access to the full `HttpResponse`, allowing access to response headers. | ||||
|    * To access only the response body, use `addComment()` instead. | ||||
|    * | ||||
|    * This method sends `application/json` and handles request body of type `application/json`. | ||||
|    */ | ||||
|   addComment$Response( | ||||
|     params: { | ||||
|       pkg: string; | ||||
|       body: AddCommentReq | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<StrictHttpResponse<AddCommentRsp>> { | ||||
|     const rb = new RequestBuilder(this.rootUrl, PkgdashServiceService.AddCommentPath, 'post'); | ||||
|     if (params) { | ||||
|       rb.path('pkg', params.pkg, {}); | ||||
|       rb.body(params.body, 'application/json'); | ||||
|     } | ||||
|  | ||||
|     return this.http.request( | ||||
|       rb.build({ responseType: 'json', accept: 'application/json', context }) | ||||
|     ).pipe( | ||||
|       filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse), | ||||
|       map((r: HttpResponse<any>) => { | ||||
|         return r as StrictHttpResponse<AddCommentRsp>; | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This method provides access only to the response body. | ||||
|    * To access the full response (for headers, for example), `addComment$Response()` instead. | ||||
|    * | ||||
|    * This method sends `application/json` and handles request body of type `application/json`. | ||||
|    */ | ||||
|   addComment( | ||||
|     params: { | ||||
|       pkg: string; | ||||
|       body: AddCommentReq | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<AddCommentRsp> { | ||||
|     return this.addComment$Response(params, context).pipe( | ||||
|       map((r: StrictHttpResponse<AddCommentRsp>): AddCommentRsp => r.body) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** Path part for operation `listPackage()` */ | ||||
|   static readonly ListPackagePath = '/v1/packages'; | ||||
|  | ||||
|   /** | ||||
|    * This method provides access to the full `HttpResponse`, allowing access to response headers. | ||||
|    * To access only the response body, use `listPackage()` instead. | ||||
|    * | ||||
|    * This method doesn't expect any request body. | ||||
|    */ | ||||
|   listPackage$Response( | ||||
|     params?: { | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<StrictHttpResponse<ListPackageRsp>> { | ||||
|     const rb = new RequestBuilder(this.rootUrl, PkgdashServiceService.ListPackagePath, 'get'); | ||||
|     if (params) { | ||||
|     } | ||||
|  | ||||
|     return this.http.request( | ||||
|       rb.build({ responseType: 'json', accept: 'application/json', context }) | ||||
|     ).pipe( | ||||
|       filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse), | ||||
|       map((r: HttpResponse<any>) => { | ||||
|         return r as StrictHttpResponse<ListPackageRsp>; | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This method provides access only to the response body. | ||||
|    * To access the full response (for headers, for example), `listPackage$Response()` instead. | ||||
|    * | ||||
|    * This method doesn't expect any request body. | ||||
|    */ | ||||
|   listPackage( | ||||
|     params?: { | ||||
|     }, | ||||
|     context?: HttpContext | ||||
|   ): Observable<ListPackageRsp> { | ||||
|     return this.listPackage$Response(params, context).pipe( | ||||
|       map((r: StrictHttpResponse<ListPackageRsp>): ListPackageRsp => r.body) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| } | ||||
							
								
								
									
										10
									
								
								ui/src/app/api/strict-http-response.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ui/src/app/api/strict-http-response.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| import { HttpResponse } from '@angular/common/http'; | ||||
|  | ||||
| /** | ||||
|  * Constrains the http response to not have the body defined as `T | null`, but `T` only. | ||||
|  */ | ||||
| export type StrictHttpResponse<T> = HttpResponse<T> & { | ||||
|   readonly body: T; | ||||
| } | ||||
							
								
								
									
										10
									
								
								ui/src/app/app-routing.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ui/src/app/app-routing.module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { RouterModule, Routes } from '@angular/router'; | ||||
|  | ||||
| const routes: Routes = []; | ||||
|  | ||||
| @NgModule({ | ||||
|   imports: [RouterModule.forRoot(routes)], | ||||
|   exports: [RouterModule] | ||||
| }) | ||||
| export class AppRoutingModule { } | ||||
							
								
								
									
										484
									
								
								ui/src/app/app.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										484
									
								
								ui/src/app/app.component.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,484 @@ | ||||
| <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * * The content below * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * Delete the template below * * * * * * * * * * --> | ||||
| <!-- * * * * * * * to get started with your project! * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> | ||||
|  | ||||
| <style> | ||||
|   :host { | ||||
|     font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; | ||||
|     font-size: 14px; | ||||
|     color: #333; | ||||
|     box-sizing: border-box; | ||||
|     -webkit-font-smoothing: antialiased; | ||||
|     -moz-osx-font-smoothing: grayscale; | ||||
|   } | ||||
|  | ||||
|   h1, | ||||
|   h2, | ||||
|   h3, | ||||
|   h4, | ||||
|   h5, | ||||
|   h6 { | ||||
|     margin: 8px 0; | ||||
|   } | ||||
|  | ||||
|   p { | ||||
|     margin: 0; | ||||
|   } | ||||
|  | ||||
|   .spacer { | ||||
|     flex: 1; | ||||
|   } | ||||
|  | ||||
|   .toolbar { | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
|     height: 60px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     background-color: #1976d2; | ||||
|     color: white; | ||||
|     font-weight: 600; | ||||
|   } | ||||
|  | ||||
|   .toolbar img { | ||||
|     margin: 0 16px; | ||||
|   } | ||||
|  | ||||
|   .toolbar #twitter-logo { | ||||
|     height: 40px; | ||||
|     margin: 0 8px; | ||||
|   } | ||||
|  | ||||
|   .toolbar #youtube-logo { | ||||
|     height: 40px; | ||||
|     margin: 0 16px; | ||||
|   } | ||||
|  | ||||
|   .toolbar #twitter-logo:hover, | ||||
|   .toolbar #youtube-logo:hover { | ||||
|     opacity: 0.8; | ||||
|   } | ||||
|  | ||||
|   .content { | ||||
|     display: flex; | ||||
|     margin: 82px auto 32px; | ||||
|     padding: 0 16px; | ||||
|     max-width: 960px; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|   } | ||||
|  | ||||
|   svg.material-icons { | ||||
|     height: 24px; | ||||
|     width: auto; | ||||
|   } | ||||
|  | ||||
|   svg.material-icons:not(:last-child) { | ||||
|     margin-right: 8px; | ||||
|   } | ||||
|  | ||||
|   .card svg.material-icons path { | ||||
|     fill: #888; | ||||
|   } | ||||
|  | ||||
|   .card-container { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|     justify-content: center; | ||||
|     margin-top: 16px; | ||||
|   } | ||||
|  | ||||
|   .card { | ||||
|     all: unset; | ||||
|     border-radius: 4px; | ||||
|     border: 1px solid #eee; | ||||
|     background-color: #fafafa; | ||||
|     height: 40px; | ||||
|     width: 200px; | ||||
|     margin: 0 8px 16px; | ||||
|     padding: 16px; | ||||
|     display: flex; | ||||
|     flex-direction: row; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     transition: all 0.2s ease-in-out; | ||||
|     line-height: 24px; | ||||
|   } | ||||
|  | ||||
|   .card-container .card:not(:last-child) { | ||||
|     margin-right: 0; | ||||
|   } | ||||
|  | ||||
|   .card.card-small { | ||||
|     height: 16px; | ||||
|     width: 168px; | ||||
|   } | ||||
|  | ||||
|   .card-container .card:not(.highlight-card) { | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .card-container .card:not(.highlight-card):hover { | ||||
|     transform: translateY(-3px); | ||||
|     box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35); | ||||
|   } | ||||
|  | ||||
|   .card-container .card:not(.highlight-card):hover .material-icons path { | ||||
|     fill: rgb(105, 103, 103); | ||||
|   } | ||||
|  | ||||
|   .card.highlight-card { | ||||
|     background-color: #1976d2; | ||||
|     color: white; | ||||
|     font-weight: 600; | ||||
|     border: none; | ||||
|     width: auto; | ||||
|     min-width: 30%; | ||||
|     position: relative; | ||||
|   } | ||||
|  | ||||
|   .card.card.highlight-card span { | ||||
|     margin-left: 60px; | ||||
|   } | ||||
|  | ||||
|   svg#rocket { | ||||
|     width: 80px; | ||||
|     position: absolute; | ||||
|     left: -10px; | ||||
|     top: -24px; | ||||
|   } | ||||
|  | ||||
|   svg#rocket-smoke { | ||||
|     height: calc(100vh - 95px); | ||||
|     position: absolute; | ||||
|     top: 10px; | ||||
|     right: 180px; | ||||
|     z-index: -10; | ||||
|   } | ||||
|  | ||||
|   a, | ||||
|   a:visited, | ||||
|   a:hover { | ||||
|     color: #1976d2; | ||||
|     text-decoration: none; | ||||
|   } | ||||
|  | ||||
|   a:hover { | ||||
|     color: #125699; | ||||
|   } | ||||
|  | ||||
|   .terminal { | ||||
|     position: relative; | ||||
|     width: 80%; | ||||
|     max-width: 600px; | ||||
|     border-radius: 6px; | ||||
|     padding-top: 45px; | ||||
|     margin-top: 8px; | ||||
|     overflow: hidden; | ||||
|     background-color: rgb(15, 15, 16); | ||||
|   } | ||||
|  | ||||
|   .terminal::before { | ||||
|     content: "\2022 \2022 \2022"; | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     height: 4px; | ||||
|     background: rgb(58, 58, 58); | ||||
|     color: #c2c3c4; | ||||
|     width: 100%; | ||||
|     font-size: 2rem; | ||||
|     line-height: 0; | ||||
|     padding: 14px 0; | ||||
|     text-indent: 4px; | ||||
|   } | ||||
|  | ||||
|   .terminal pre { | ||||
|     font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace; | ||||
|     color: white; | ||||
|     padding: 0 1rem 1rem; | ||||
|     margin: 0; | ||||
|   } | ||||
|  | ||||
|   .circle-link { | ||||
|     height: 40px; | ||||
|     width: 40px; | ||||
|     border-radius: 40px; | ||||
|     margin: 8px; | ||||
|     background-color: white; | ||||
|     border: 1px solid #eeeeee; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     cursor: pointer; | ||||
|     box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); | ||||
|     transition: 1s ease-out; | ||||
|   } | ||||
|  | ||||
|   .circle-link:hover { | ||||
|     transform: translateY(-0.25rem); | ||||
|     box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2); | ||||
|   } | ||||
|  | ||||
|   footer { | ||||
|     margin-top: 8px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     line-height: 20px; | ||||
|   } | ||||
|  | ||||
|   footer a { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|   } | ||||
|  | ||||
|   .github-star-badge { | ||||
|     color: #24292e; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     font-size: 12px; | ||||
|     padding: 3px 10px; | ||||
|     border: 1px solid rgba(27,31,35,.2); | ||||
|     border-radius: 3px; | ||||
|     background-image: linear-gradient(-180deg,#fafbfc,#eff3f6 90%); | ||||
|     margin-left: 4px; | ||||
|     font-weight: 600; | ||||
|   } | ||||
|  | ||||
|   .github-star-badge:hover { | ||||
|     background-image: linear-gradient(-180deg,#f0f3f6,#e6ebf1 90%); | ||||
|     border-color: rgba(27,31,35,.35); | ||||
|     background-position: -.5em; | ||||
|   } | ||||
|  | ||||
|   .github-star-badge .material-icons { | ||||
|     height: 16px; | ||||
|     width: 16px; | ||||
|     margin-right: 4px; | ||||
|   } | ||||
|  | ||||
|   svg#clouds { | ||||
|     position: fixed; | ||||
|     bottom: -160px; | ||||
|     left: -230px; | ||||
|     z-index: -10; | ||||
|     width: 1920px; | ||||
|   } | ||||
|  | ||||
|   /* Responsive Styles */ | ||||
|   @media screen and (max-width: 767px) { | ||||
|     .card-container > *:not(.circle-link) , | ||||
|     .terminal { | ||||
|       width: 100%; | ||||
|     } | ||||
|  | ||||
|     .card:not(.highlight-card) { | ||||
|       height: 16px; | ||||
|       margin: 8px 0; | ||||
|     } | ||||
|  | ||||
|     .card.highlight-card span { | ||||
|       margin-left: 72px; | ||||
|     } | ||||
|  | ||||
|     svg#rocket-smoke { | ||||
|       right: 120px; | ||||
|       transform: rotate(-5deg); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @media screen and (max-width: 575px) { | ||||
|     svg#rocket-smoke { | ||||
|       display: none; | ||||
|       visibility: hidden; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
|  | ||||
| <!-- Toolbar --> | ||||
| <div class="toolbar" role="banner"> | ||||
|   <img | ||||
|     width="40" | ||||
|     alt="Angular Logo" | ||||
|     src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==" | ||||
|   /> | ||||
|   <span>Welcome</span> | ||||
|     <div class="spacer"></div> | ||||
|     <a aria-label="Angular on twitter" target="_blank" rel="noopener" href="https://twitter.com/angular" title="Twitter"> | ||||
|       <svg id="twitter-logo" height="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"> | ||||
|         <rect width="400" height="400" fill="none"/> | ||||
|         <path d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23" fill="#fff"/> | ||||
|       </svg> | ||||
|     </a> | ||||
|     <a aria-label="Angular on YouTube" target="_blank" rel="noopener" href="https://youtube.com/angular" title="YouTube"> | ||||
|       <svg id="youtube-logo" height="24" width="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff"> | ||||
|         <path d="M0 0h24v24H0V0z" fill="none"/> | ||||
|         <path d="M21.58 7.19c-.23-.86-.91-1.54-1.77-1.77C18.25 5 12 5 12 5s-6.25 0-7.81.42c-.86.23-1.54.91-1.77 1.77C2 8.75 2 12 2 12s0 3.25.42 4.81c.23.86.91 1.54 1.77 1.77C5.75 19 12 19 12 19s6.25 0 7.81-.42c.86-.23 1.54-.91 1.77-1.77C22 15.25 22 12 22 12s0-3.25-.42-4.81zM10 15V9l5.2 3-5.2 3z"/> | ||||
|       </svg> | ||||
|     </a> | ||||
| </div> | ||||
|  | ||||
| <div class="content" role="main"> | ||||
|  | ||||
|   <!-- Highlight Card --> | ||||
|   <div class="card highlight-card card-small"> | ||||
|  | ||||
|     <svg id="rocket" xmlns="http://www.w3.org/2000/svg" width="101.678" height="101.678" viewBox="0 0 101.678 101.678"> | ||||
|       <title>Rocket Ship</title> | ||||
|       <g id="Group_83" data-name="Group 83" transform="translate(-141 -696)"> | ||||
|         <circle id="Ellipse_8" data-name="Ellipse 8" cx="50.839" cy="50.839" r="50.839" transform="translate(141 696)" fill="#dd0031"/> | ||||
|         <g id="Group_47" data-name="Group 47" transform="translate(165.185 720.185)"> | ||||
|           <path id="Path_33" data-name="Path 33" d="M3.4,42.615a3.084,3.084,0,0,0,3.553,3.553,21.419,21.419,0,0,0,12.215-6.107L9.511,30.4A21.419,21.419,0,0,0,3.4,42.615Z" transform="translate(0.371 3.363)" fill="#fff"/> | ||||
|           <path id="Path_34" data-name="Path 34" d="M53.3,3.221A3.09,3.09,0,0,0,50.081,0,48.227,48.227,0,0,0,18.322,13.437c-6-1.666-14.991-1.221-18.322,7.218A33.892,33.892,0,0,1,9.439,25.1l-.333.666a3.013,3.013,0,0,0,.555,3.553L23.985,43.641a2.9,2.9,0,0,0,3.553.555l.666-.333A33.892,33.892,0,0,1,32.647,53.3c8.55-3.664,8.884-12.326,7.218-18.322A48.227,48.227,0,0,0,53.3,3.221ZM34.424,9.772a6.439,6.439,0,1,1,9.106,9.106,6.368,6.368,0,0,1-9.106,0A6.467,6.467,0,0,1,34.424,9.772Z" transform="translate(0 0.005)" fill="#fff"/> | ||||
|         </g> | ||||
|       </g> | ||||
|     </svg> | ||||
|  | ||||
|     <span>{{ title }} app is running!</span> | ||||
|  | ||||
|     <svg id="rocket-smoke" xmlns="http://www.w3.org/2000/svg" width="516.119" height="1083.632" viewBox="0 0 516.119 1083.632"> | ||||
|       <title>Rocket Ship Smoke</title> | ||||
|       <path id="Path_40" data-name="Path 40" d="M644.6,141S143.02,215.537,147.049,870.207s342.774,201.755,342.774,201.755S404.659,847.213,388.815,762.2c-27.116-145.51-11.551-384.124,271.9-609.1C671.15,139.365,644.6,141,644.6,141Z" transform="translate(-147.025 -140.939)" fill="#f5f5f5"/> | ||||
|     </svg> | ||||
|  | ||||
|   </div> | ||||
|  | ||||
|   <!-- Resources --> | ||||
|   <h2>Resources</h2> | ||||
|   <p>Here are some links to help you get started:</p> | ||||
|  | ||||
|   <div class="card-container"> | ||||
|     <a class="card" target="_blank" rel="noopener" href="https://angular.io/tutorial"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z"/></svg> | ||||
|       <span>Learn Angular</span> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>    </a> | ||||
|  | ||||
|     <a class="card" target="_blank" rel="noopener" href="https://angular.io/cli"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg> | ||||
|       <span>CLI Documentation</span> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> | ||||
|     </a> | ||||
|  | ||||
|     <a class="card" target="_blank" rel="noopener" href="https://material.angular.io"> | ||||
|       <svg xmlns="http://www.w3.org/2000/svg" style="margin-right: 8px" width="21.813" height="23.453" viewBox="0 0 21.813 23.453"><path d="M4099.584,972.736h0l-10.882,3.9,1.637,14.4,9.245,5.153,9.245-5.153,1.686-14.4Z" transform="translate(-4088.702 -972.736)" fill="#808080"/><path d="M4181.516,972.736v23.453l9.245-5.153,1.686-14.4Z" transform="translate(-4170.633 -972.736)" fill="#808080"/><path d="M4137.529,1076.127l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1058.315)" fill="#ffe0b2"/><path d="M4137.529,1051.705l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1036.757)" fill="#fff3e0"/><path d="M4137.529,1027.283l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1015.199)" fill="#fff"/></svg> | ||||
|       <span>Angular Material</span> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> | ||||
|     </a> | ||||
|  | ||||
|     <a class="card" target="_blank" rel="noopener" href="https://blog.angular.io/"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"/></svg> | ||||
|       <span>Angular Blog</span> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> | ||||
|     </a> | ||||
|  | ||||
|     <a class="card" target="_blank" rel="noopener" href="https://angular.io/devtools/"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><path d="M14.73,13.31C15.52,12.24,16,10.93,16,9.5C16,5.91,13.09,3,9.5,3S3,5.91,3,9.5C3,13.09,5.91,16,9.5,16 c1.43,0,2.74-0.48,3.81-1.27L19.59,21L21,19.59L14.73,13.31z M9.5,14C7.01,14,5,11.99,5,9.5S7.01,5,9.5,5S14,7.01,14,9.5 S11.99,14,9.5,14z"/><polygon points="10.29,8.44 9.5,6 8.71,8.44 6.25,8.44 8.26,10.03 7.49,12.5 9.5,10.97 11.51,12.5 10.74,10.03 12.75,8.44"/></g></g></svg> | ||||
|       <span>Angular DevTools</span> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> | ||||
|     </a> | ||||
|  | ||||
|   </div> | ||||
|  | ||||
|   <!-- Next Steps --> | ||||
|   <h2>Next Steps</h2> | ||||
|   <p>What do you want to do next with your app?</p> | ||||
|  | ||||
|   <input type="hidden" #selection> | ||||
|  | ||||
|   <div class="card-container"> | ||||
|     <button class="card card-small" (click)="selection.value = 'component'" tabindex="0"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> | ||||
|       <span>New Component</span> | ||||
|     </button> | ||||
|  | ||||
|     <button class="card card-small" (click)="selection.value = 'material'" tabindex="0"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> | ||||
|       <span>Angular Material</span> | ||||
|     </button> | ||||
|  | ||||
|     <button class="card card-small" (click)="selection.value = 'pwa'" tabindex="0"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> | ||||
|       <span>Add PWA Support</span> | ||||
|     </button> | ||||
|  | ||||
|     <button class="card card-small" (click)="selection.value = 'dependency'" tabindex="0"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> | ||||
|       <span>Add Dependency</span> | ||||
|     </button> | ||||
|  | ||||
|     <button class="card card-small" (click)="selection.value = 'test'" tabindex="0"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> | ||||
|       <span>Run and Watch Tests</span> | ||||
|     </button> | ||||
|  | ||||
|     <button class="card card-small" (click)="selection.value = 'build'" tabindex="0"> | ||||
|       <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> | ||||
|       <span>Build for Production</span> | ||||
|     </button> | ||||
|   </div> | ||||
|  | ||||
|   <!-- Terminal --> | ||||
|   <div class="terminal" [ngSwitch]="selection.value"> | ||||
|       <pre *ngSwitchDefault>ng generate component xyz</pre> | ||||
|       <pre *ngSwitchCase="'material'">ng add @angular/material</pre> | ||||
|       <pre *ngSwitchCase="'pwa'">ng add @angular/pwa</pre> | ||||
|       <pre *ngSwitchCase="'dependency'">ng add _____</pre> | ||||
|       <pre *ngSwitchCase="'test'">ng test</pre> | ||||
|       <pre *ngSwitchCase="'build'">ng build</pre> | ||||
|   </div> | ||||
|  | ||||
|   <!-- Links --> | ||||
|   <div class="card-container"> | ||||
|     <a class="circle-link" title="Find a Local Meetup" href="https://www.meetup.com/find/?keywords=angular" target="_blank" rel="noopener"> | ||||
|       <svg xmlns="http://www.w3.org/2000/svg" width="24.607" height="23.447" viewBox="0 0 24.607 23.447"> | ||||
|         <title>Meetup Logo</title> | ||||
|         <path id="logo--mSwarm" d="M21.221,14.95A4.393,4.393,0,0,1,17.6,19.281a4.452,4.452,0,0,1-.8.069c-.09,0-.125.035-.154.117a2.939,2.939,0,0,1-2.506,2.091,2.868,2.868,0,0,1-2.248-.624.168.168,0,0,0-.245-.005,3.926,3.926,0,0,1-2.589.741,4.015,4.015,0,0,1-3.7-3.347,2.7,2.7,0,0,1-.043-.38c0-.106-.042-.146-.143-.166a3.524,3.524,0,0,1-1.516-.69A3.623,3.623,0,0,1,2.23,14.557a3.66,3.66,0,0,1,1.077-3.085.138.138,0,0,0,.026-.2,3.348,3.348,0,0,1-.451-1.821,3.46,3.46,0,0,1,2.749-3.28.44.44,0,0,0,.355-.281,5.072,5.072,0,0,1,3.863-3,5.028,5.028,0,0,1,3.555.666.31.31,0,0,0,.271.03A4.5,4.5,0,0,1,18.3,4.7a4.4,4.4,0,0,1,1.334,2.751,3.658,3.658,0,0,1,.022.706.131.131,0,0,0,.1.157,2.432,2.432,0,0,1,1.574,1.645,2.464,2.464,0,0,1-.7,2.616c-.065.064-.051.1-.014.166A4.321,4.321,0,0,1,21.221,14.95ZM13.4,14.607a2.09,2.09,0,0,0,1.409,1.982,4.7,4.7,0,0,0,1.275.221,1.807,1.807,0,0,0,.9-.151.542.542,0,0,0,.321-.545.558.558,0,0,0-.359-.534,1.2,1.2,0,0,0-.254-.078c-.262-.047-.526-.086-.787-.138a.674.674,0,0,1-.617-.75,3.394,3.394,0,0,1,.218-1.109c.217-.658.509-1.286.79-1.918a15.609,15.609,0,0,0,.745-1.86,1.95,1.95,0,0,0,.06-1.073,1.286,1.286,0,0,0-1.051-1.033,1.977,1.977,0,0,0-1.521.2.339.339,0,0,1-.446-.042c-.1-.092-.2-.189-.307-.284a1.214,1.214,0,0,0-1.643-.061,7.563,7.563,0,0,1-.614.512A.588.588,0,0,1,10.883,8c-.215-.115-.437-.215-.659-.316a2.153,2.153,0,0,0-.695-.248A2.091,2.091,0,0,0,7.541,8.562a9.915,9.915,0,0,0-.405.986c-.559,1.545-1.015,3.123-1.487,4.7a1.528,1.528,0,0,0,.634,1.777,1.755,1.755,0,0,0,1.5.211,1.35,1.35,0,0,0,.824-.858c.543-1.281,1.032-2.584,1.55-3.875.142-.355.28-.712.432-1.064a.548.548,0,0,1,.851-.24.622.622,0,0,1,.185.539,2.161,2.161,0,0,1-.181.621c-.337.852-.68,1.7-1.018,2.552a2.564,2.564,0,0,0-.173.528.624.624,0,0,0,.333.71,1.073,1.073,0,0,0,.814.034,1.22,1.22,0,0,0,.657-.655q.758-1.488,1.511-2.978.35-.687.709-1.37a1.073,1.073,0,0,1,.357-.434.43.43,0,0,1,.463-.016.373.373,0,0,1,.153.387.7.7,0,0,1-.057.236c-.065.157-.127.316-.2.469-.42.883-.846,1.763-1.262,2.648A2.463,2.463,0,0,0,13.4,14.607Zm5.888,6.508a1.09,1.09,0,0,0-2.179.006,1.09,1.09,0,0,0,2.179-.006ZM1.028,12.139a1.038,1.038,0,1,0,.01-2.075,1.038,1.038,0,0,0-.01,2.075ZM13.782.528a1.027,1.027,0,1,0-.011,2.055A1.027,1.027,0,0,0,13.782.528ZM22.21,6.95a.882.882,0,0,0-1.763.011A.882.882,0,0,0,22.21,6.95ZM4.153,4.439a.785.785,0,1,0,.787-.78A.766.766,0,0,0,4.153,4.439Zm8.221,18.22a.676.676,0,1,0-.677.666A.671.671,0,0,0,12.374,22.658ZM22.872,12.2a.674.674,0,0,0-.665.665.656.656,0,0,0,.655.643.634.634,0,0,0,.655-.644A.654.654,0,0,0,22.872,12.2ZM7.171-.123A.546.546,0,0,0,6.613.43a.553.553,0,1,0,1.106,0A.539.539,0,0,0,7.171-.123ZM24.119,9.234a.507.507,0,0,0-.493.488.494.494,0,0,0,.494.494.48.48,0,0,0,.487-.483A.491.491,0,0,0,24.119,9.234Zm-19.454,9.7a.5.5,0,0,0-.488-.488.491.491,0,0,0-.487.5.483.483,0,0,0,.491.479A.49.49,0,0,0,4.665,18.936Z" transform="translate(0 0.123)" fill="#f64060"/> | ||||
|       </svg> | ||||
|     </a> | ||||
|  | ||||
|     <a class="circle-link" title="Join the Conversation on Discord" href="https://discord.gg/angular" target="_blank" rel="noopener"> | ||||
|       <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 245 240"> | ||||
|         <title>Discord Logo</title> | ||||
|         <path d="M104.4 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1.1-6.1-4.5-11.1-10.2-11.1zM140.9 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1s-4.5-11.1-10.2-11.1z"/> | ||||
|         <path d="M189.5 20h-134C44.2 20 35 29.2 35 40.6v135.2c0 11.4 9.2 20.6 20.5 20.6h113.4l-5.3-18.5 12.8 11.9 12.1 11.2 21.5 19V40.6c0-11.4-9.2-20.6-20.5-20.6zm-38.6 130.6s-3.6-4.3-6.6-8.1c13.1-3.7 18.1-11.9 18.1-11.9-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.5-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.7-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.3-1.8-1-2.8-1.7-2.8-1.7s4.8 8 17.5 11.8c-3 3.8-6.7 8.3-6.7 8.3-22.1-.7-30.5-15.2-30.5-15.2 0-32.2 14.4-58.3 14.4-58.3 14.4-10.8 28.1-10.5 28.1-10.5l1 1.2c-18 5.2-26.3 13.1-26.3 13.1s2.2-1.2 5.9-2.9c10.7-4.7 19.2-6 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.6 0 0-7.9-7.5-24.9-12.7l1.4-1.6s13.7-.3 28.1 10.5c0 0 14.4 26.1 14.4 58.3 0 0-8.5 14.5-30.6 15.2z"/> | ||||
|       </svg> | ||||
|     </a> | ||||
|   </div> | ||||
|  | ||||
|   <!-- Footer --> | ||||
|   <footer> | ||||
|       Love Angular?  | ||||
|       <a href="https://github.com/angular/angular" target="_blank" rel="noopener"> Give our repo a star. | ||||
|         <div class="github-star-badge"> | ||||
|             <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg> | ||||
|           Star | ||||
|         </div> | ||||
|       </a> | ||||
|       <a href="https://github.com/angular/angular" target="_blank" rel="noopener"> | ||||
|         <svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" fill="#1976d2"/><path d="M0 0h24v24H0z" fill="none"/></svg> | ||||
|       </a> | ||||
|   </footer> | ||||
|  | ||||
|   <svg id="clouds" xmlns="http://www.w3.org/2000/svg" width="2611.084" height="485.677" viewBox="0 0 2611.084 485.677"> | ||||
|     <title>Gray Clouds Background</title> | ||||
|     <path id="Path_39" data-name="Path 39" d="M2379.709,863.793c10-93-77-171-168-149-52-114-225-105-264,15-75,3-140,59-152,133-30,2.83-66.725,9.829-93.5,26.25-26.771-16.421-63.5-23.42-93.5-26.25-12-74-77-130-152-133-39-120-212-129-264-15-54.084-13.075-106.753,9.173-138.488,48.9-31.734-39.726-84.4-61.974-138.487-48.9-52-114-225-105-264,15a162.027,162.027,0,0,0-103.147,43.044c-30.633-45.365-87.1-72.091-145.206-58.044-52-114-225-105-264,15-75,3-140,59-152,133-53,5-127,23-130,83-2,42,35,72,70,86,49,20,106,18,157,5a165.625,165.625,0,0,0,120,0c47,94,178,113,251,33,61.112,8.015,113.854-5.72,150.492-29.764a165.62,165.62,0,0,0,110.861-3.236c47,94,178,113,251,33,31.385,4.116,60.563,2.495,86.487-3.311,25.924,5.806,55.1,7.427,86.488,3.311,73,80,204,61,251-33a165.625,165.625,0,0,0,120,0c51,13,108,15,157-5a147.188,147.188,0,0,0,33.5-18.694,147.217,147.217,0,0,0,33.5,18.694c49,20,106,18,157,5a165.625,165.625,0,0,0,120,0c47,94,178,113,251,33C2446.709,1093.793,2554.709,922.793,2379.709,863.793Z" transform="translate(142.69 -634.312)" fill="#eee"/> | ||||
|   </svg> | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * * The content above * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * End of Placeholder * * * * * * * * * * * --> | ||||
| <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> | ||||
|  | ||||
| <router-outlet></router-outlet> | ||||
							
								
								
									
										0
									
								
								ui/src/app/app.component.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ui/src/app/app.component.scss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										35
									
								
								ui/src/app/app.component.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ui/src/app/app.component.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| import { TestBed } from '@angular/core/testing'; | ||||
| import { RouterTestingModule } from '@angular/router/testing'; | ||||
| import { AppComponent } from './app.component'; | ||||
|  | ||||
| describe('AppComponent', () => { | ||||
|   beforeEach(async () => { | ||||
|     await TestBed.configureTestingModule({ | ||||
|       imports: [ | ||||
|         RouterTestingModule | ||||
|       ], | ||||
|       declarations: [ | ||||
|         AppComponent | ||||
|       ], | ||||
|     }).compileComponents(); | ||||
|   }); | ||||
|  | ||||
|   it('should create the app', () => { | ||||
|     const fixture = TestBed.createComponent(AppComponent); | ||||
|     const app = fixture.componentInstance; | ||||
|     expect(app).toBeTruthy(); | ||||
|   }); | ||||
|  | ||||
|   it(`should have as title 'ui'`, () => { | ||||
|     const fixture = TestBed.createComponent(AppComponent); | ||||
|     const app = fixture.componentInstance; | ||||
|     expect(app.title).toEqual('ui'); | ||||
|   }); | ||||
|  | ||||
|   it('should render title', () => { | ||||
|     const fixture = TestBed.createComponent(AppComponent); | ||||
|     fixture.detectChanges(); | ||||
|     const compiled = fixture.nativeElement as HTMLElement; | ||||
|     expect(compiled.querySelector('.content span')?.textContent).toContain('ui app is running!'); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										10
									
								
								ui/src/app/app.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ui/src/app/app.component.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| import { Component } from '@angular/core'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-root', | ||||
|   templateUrl: './app.component.html', | ||||
|   styleUrls: ['./app.component.scss'] | ||||
| }) | ||||
| export class AppComponent { | ||||
|   title = 'ui'; | ||||
| } | ||||
							
								
								
									
										18
									
								
								ui/src/app/app.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								ui/src/app/app.module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { BrowserModule } from '@angular/platform-browser'; | ||||
|  | ||||
| import { AppRoutingModule } from './app-routing.module'; | ||||
| import { AppComponent } from './app.component'; | ||||
|  | ||||
| @NgModule({ | ||||
|   declarations: [ | ||||
|     AppComponent | ||||
|   ], | ||||
|   imports: [ | ||||
|     BrowserModule, | ||||
|     AppRoutingModule | ||||
|   ], | ||||
|   providers: [], | ||||
|   bootstrap: [AppComponent] | ||||
| }) | ||||
| export class AppModule { } | ||||
							
								
								
									
										0
									
								
								ui/src/assets/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ui/src/assets/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								ui/src/environments/environment.prod.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ui/src/environments/environment.prod.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| export const environment = { | ||||
|   production: true | ||||
| }; | ||||
							
								
								
									
										16
									
								
								ui/src/environments/environment.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								ui/src/environments/environment.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // This file can be replaced during build by using the `fileReplacements` array. | ||||
| // `ng build` replaces `environment.ts` with `environment.prod.ts`. | ||||
| // The list of file replacements can be found in `angular.json`. | ||||
|  | ||||
| export const environment = { | ||||
|   production: false | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * For easier debugging in development mode, you can import the following file | ||||
|  * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. | ||||
|  * | ||||
|  * This import should be commented out in production mode because it will have a negative impact | ||||
|  * on performance if an error is thrown. | ||||
|  */ | ||||
| // import 'zone.js/plugins/zone-error';  // Included with Angular CLI. | ||||
							
								
								
									
										
											BIN
										
									
								
								ui/src/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ui/src/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 948 B | 
							
								
								
									
										13
									
								
								ui/src/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								ui/src/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| <!doctype html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|   <meta charset="utf-8"> | ||||
|   <title>Ui</title> | ||||
|   <base href="/"> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
|   <link rel="icon" type="image/x-icon" href="favicon.ico"> | ||||
| </head> | ||||
| <body> | ||||
|   <app-root></app-root> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										12
									
								
								ui/src/main.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								ui/src/main.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| import { enableProdMode } from '@angular/core'; | ||||
| import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; | ||||
|  | ||||
| import { AppModule } from './app/app.module'; | ||||
| import { environment } from './environments/environment'; | ||||
|  | ||||
| if (environment.production) { | ||||
|   enableProdMode(); | ||||
| } | ||||
|  | ||||
| platformBrowserDynamic().bootstrapModule(AppModule) | ||||
|   .catch(err => console.error(err)); | ||||
							
								
								
									
										53
									
								
								ui/src/polyfills.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								ui/src/polyfills.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| /** | ||||
|  * This file includes polyfills needed by Angular and is loaded before the app. | ||||
|  * You can add your own extra polyfills to this file. | ||||
|  * | ||||
|  * This file is divided into 2 sections: | ||||
|  *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. | ||||
|  *   2. Application imports. Files imported after ZoneJS that should be loaded before your main | ||||
|  *      file. | ||||
|  * | ||||
|  * The current setup is for so-called "evergreen" browsers; the last versions of browsers that | ||||
|  * automatically update themselves. This includes recent versions of Safari, Chrome (including | ||||
|  * Opera), Edge on the desktop, and iOS and Chrome on mobile. | ||||
|  * | ||||
|  * Learn more in https://angular.io/guide/browser-support | ||||
|  */ | ||||
|  | ||||
| /*************************************************************************************************** | ||||
|  * BROWSER POLYFILLS | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * By default, zone.js will patch all possible macroTask and DomEvents | ||||
|  * user can disable parts of macroTask/DomEvents patch by setting following flags | ||||
|  * because those flags need to be set before `zone.js` being loaded, and webpack | ||||
|  * will put import in the top of bundle, so user need to create a separate file | ||||
|  * in this directory (for example: zone-flags.ts), and put the following flags | ||||
|  * into that file, and then add the following code before importing zone.js. | ||||
|  * import './zone-flags'; | ||||
|  * | ||||
|  * The flags allowed in zone-flags.ts are listed here. | ||||
|  * | ||||
|  * The following flags will work for all browsers. | ||||
|  * | ||||
|  * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame | ||||
|  * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick | ||||
|  * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames | ||||
|  * | ||||
|  *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js | ||||
|  *  with the following flag, it will bypass `zone.js` patch for IE/Edge | ||||
|  * | ||||
|  *  (window as any).__Zone_enable_cross_context_check = true; | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /*************************************************************************************************** | ||||
|  * Zone JS is required by default for Angular itself. | ||||
|  */ | ||||
| import 'zone.js';  // Included with Angular CLI. | ||||
|  | ||||
|  | ||||
| /*************************************************************************************************** | ||||
|  * APPLICATION IMPORTS | ||||
|  */ | ||||
							
								
								
									
										1
									
								
								ui/src/styles.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ui/src/styles.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| /* You can add global styles to this file, and also import other style files */ | ||||
							
								
								
									
										26
									
								
								ui/src/test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								ui/src/test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // This file is required by karma.conf.js and loads recursively all the .spec and framework files | ||||
|  | ||||
| import 'zone.js/testing'; | ||||
| import { getTestBed } from '@angular/core/testing'; | ||||
| import { | ||||
|   BrowserDynamicTestingModule, | ||||
|   platformBrowserDynamicTesting | ||||
| } from '@angular/platform-browser-dynamic/testing'; | ||||
|  | ||||
| declare const require: { | ||||
|   context(path: string, deep?: boolean, filter?: RegExp): { | ||||
|     <T>(id: string): T; | ||||
|     keys(): string[]; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| // First, initialize the Angular testing environment. | ||||
| getTestBed().initTestEnvironment( | ||||
|   BrowserDynamicTestingModule, | ||||
|   platformBrowserDynamicTesting(), | ||||
| ); | ||||
|  | ||||
| // Then we find all the tests. | ||||
| const context = require.context('./', true, /\.spec\.ts$/); | ||||
| // And load the modules. | ||||
| context.keys().map(context); | ||||
							
								
								
									
										15
									
								
								ui/tsconfig.app.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								ui/tsconfig.app.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| /* To learn more about this file see: https://angular.io/config/tsconfig. */ | ||||
| { | ||||
|   "extends": "./tsconfig.json", | ||||
|   "compilerOptions": { | ||||
|     "outDir": "./out-tsc/app", | ||||
|     "types": [] | ||||
|   }, | ||||
|   "files": [ | ||||
|     "src/main.ts", | ||||
|     "src/polyfills.ts" | ||||
|   ], | ||||
|   "include": [ | ||||
|     "src/**/*.d.ts" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										32
									
								
								ui/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ui/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /* To learn more about this file see: https://angular.io/config/tsconfig. */ | ||||
| { | ||||
|   "compileOnSave": false, | ||||
|   "compilerOptions": { | ||||
|     "baseUrl": "./", | ||||
|     "outDir": "./dist/out-tsc", | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "strict": true, | ||||
|     "noImplicitOverride": true, | ||||
|     "noPropertyAccessFromIndexSignature": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "sourceMap": true, | ||||
|     "declaration": false, | ||||
|     "downlevelIteration": true, | ||||
|     "experimentalDecorators": true, | ||||
|     "moduleResolution": "node", | ||||
|     "importHelpers": true, | ||||
|     "target": "es2017", | ||||
|     "module": "es2020", | ||||
|     "lib": [ | ||||
|       "es2020", | ||||
|       "dom" | ||||
|     ] | ||||
|   }, | ||||
|   "angularCompilerOptions": { | ||||
|     "enableI18nLegacyMessageIdFormat": false, | ||||
|     "strictInjectionParameters": true, | ||||
|     "strictInputAccessModifiers": true, | ||||
|     "strictTemplates": true | ||||
|   } | ||||
| } | ||||
							
								
								
									
										18
									
								
								ui/tsconfig.spec.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								ui/tsconfig.spec.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| /* To learn more about this file see: https://angular.io/config/tsconfig. */ | ||||
| { | ||||
|   "extends": "./tsconfig.json", | ||||
|   "compilerOptions": { | ||||
|     "outDir": "./out-tsc/spec", | ||||
|     "types": [ | ||||
|       "jasmine" | ||||
|     ] | ||||
|   }, | ||||
|   "files": [ | ||||
|     "src/test.ts", | ||||
|     "src/polyfills.ts" | ||||
|   ], | ||||
|   "include": [ | ||||
|     "src/**/*.spec.ts", | ||||
|     "src/**/*.d.ts" | ||||
|   ] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user