haveapi-go-client 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/README.md +64 -0
- data/bin/haveapi-go-client +3 -0
- data/haveapi-go-client.gemspec +25 -0
- data/lib/haveapi/go_client/action.rb +128 -0
- data/lib/haveapi/go_client/api_version.rb +21 -0
- data/lib/haveapi/go_client/authentication/base.rb +13 -0
- data/lib/haveapi/go_client/authentication/basic.rb +21 -0
- data/lib/haveapi/go_client/authentication/token.rb +56 -0
- data/lib/haveapi/go_client/authentication/unsupported.rb +13 -0
- data/lib/haveapi/go_client/authentication_methods.rb +24 -0
- data/lib/haveapi/go_client/cli.rb +39 -0
- data/lib/haveapi/go_client/erb_template.rb +46 -0
- data/lib/haveapi/go_client/generator.rb +65 -0
- data/lib/haveapi/go_client/input_output.rb +48 -0
- data/lib/haveapi/go_client/metadata.rb +63 -0
- data/lib/haveapi/go_client/parameter.rb +27 -0
- data/lib/haveapi/go_client/parameters/association.rb +54 -0
- data/lib/haveapi/go_client/parameters/base.rb +66 -0
- data/lib/haveapi/go_client/parameters/global_meta_includes.rb +17 -0
- data/lib/haveapi/go_client/parameters/resource.rb +20 -0
- data/lib/haveapi/go_client/parameters/typed.rb +30 -0
- data/lib/haveapi/go_client/resource.rb +133 -0
- data/lib/haveapi/go_client/utils.rb +10 -0
- data/lib/haveapi/go_client/version.rb +5 -0
- data/lib/haveapi/go_client.rb +21 -0
- data/shell.nix +23 -0
- data/template/action.go.erb +475 -0
- data/template/authentication/basic.go.erb +22 -0
- data/template/authentication/token.go.erb +164 -0
- data/template/authentication.go.erb +10 -0
- data/template/client.go.erb +26 -0
- data/template/go.mod.erb +1 -0
- data/template/request.go.erb +96 -0
- data/template/resource.go.erb +36 -0
- data/template/response.go.erb +13 -0
- data/template/types.go.erb +41 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d9a94df4ba98576591129b131154972fd9a42960b0fb85269f20dbb178d5d57c
|
4
|
+
data.tar.gz: 285063beca2e245611104a43a283893bf3bf1182e7b0275a93b876e7783717d9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 93767bf1ec0dc97ea788080d327899a6883f620f65e123c4f548c8e9d2e20494fc58011da1688128e2a34ea9299b7a63a4d7189240d6ed7e675d00e9c51daf3c
|
7
|
+
data.tar.gz: d41fb0d6f3b0786c1e3d58c8edcb66ad1ac24a0f7771586fb3474a8e62801e565e6d41d9685093657dab5a6c511632104b7f52b6ac5f75d01ab18f77d53ce9dd
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.gems
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
HaveAPI Client Generator For Go
|
2
|
+
-------------------------------
|
3
|
+
HaveAPI-Go-Client generates a client library for accessing selected APIs built
|
4
|
+
with the [HaveAPI framework](https://github.com/vpsfreecz/haveapi).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
$ gem install 'haveapi-go-client'
|
9
|
+
|
10
|
+
## CLI
|
11
|
+
The generator is run against an API server that the resulting client should be
|
12
|
+
able to work with. The generated client uses one selected API version. When
|
13
|
+
the API server changes, the client has to be regenerated.
|
14
|
+
|
15
|
+
```
|
16
|
+
$ haveapi-go-client -h
|
17
|
+
Usage: haveapi-go-client [options] <api url> <destination>
|
18
|
+
--version VERSION Use specified API version
|
19
|
+
--module MODULE Name of the generated Go module
|
20
|
+
--package PKG Name of the generated Go package
|
21
|
+
```
|
22
|
+
|
23
|
+
For example:
|
24
|
+
|
25
|
+
```
|
26
|
+
$ haveapi-go-client https://api.vpsfree.cz ~/go/src/foo/client
|
27
|
+
```
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
The generated library can then be imported in your projects. For example,
|
31
|
+
in a project with the following `go.mod`:
|
32
|
+
|
33
|
+
```
|
34
|
+
module foo
|
35
|
+
```
|
36
|
+
|
37
|
+
The client could be imported and used as:
|
38
|
+
|
39
|
+
```go
|
40
|
+
package main
|
41
|
+
|
42
|
+
import (
|
43
|
+
"fmt"
|
44
|
+
"foo/client"
|
45
|
+
)
|
46
|
+
|
47
|
+
func main() {
|
48
|
+
api := client.New("https://api.vpsfree.cz")
|
49
|
+
api.SetBasicAuthentication("admin", "secret")
|
50
|
+
|
51
|
+
action := api.Cluster.PublicStats.Prepare()
|
52
|
+
resp, err := action.Call()
|
53
|
+
|
54
|
+
if err != nil {
|
55
|
+
fmt.Println(err)
|
56
|
+
return
|
57
|
+
}
|
58
|
+
|
59
|
+
fmt.Printf("%+v\n", resp)
|
60
|
+
fmt.Printf("%+v\n", resp.Response)
|
61
|
+
fmt.Printf("%+v\n", resp.Response.Cluster)
|
62
|
+
fmt.Printf("%+v\n", resp.Output)
|
63
|
+
}
|
64
|
+
```
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'haveapi/go_client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'haveapi-go-client'
|
8
|
+
spec.version = HaveAPI::GoClient::VERSION
|
9
|
+
spec.authors = ['Jakub Skokan']
|
10
|
+
spec.email = ['jakub.skokan@vpsfree.cz']
|
11
|
+
spec.summary =
|
12
|
+
spec.description = 'Go client generator'
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
|
24
|
+
spec.add_runtime_dependency 'haveapi-client', '~> 0.13.0'
|
25
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'haveapi/go_client/utils'
|
2
|
+
|
3
|
+
module HaveAPI::GoClient
|
4
|
+
class Action
|
5
|
+
include Utils
|
6
|
+
|
7
|
+
# @return [Resource]
|
8
|
+
attr_reader :resource
|
9
|
+
|
10
|
+
# Name as returned by the API
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
# Name aliases as returned by the API
|
15
|
+
# @return [Array<String>]
|
16
|
+
attr_reader :aliases
|
17
|
+
|
18
|
+
# Full action name, including resource
|
19
|
+
# @return [String]
|
20
|
+
attr_reader :full_dot_name
|
21
|
+
|
22
|
+
# Name for usage in Go
|
23
|
+
# @return [String]
|
24
|
+
attr_reader :go_name
|
25
|
+
|
26
|
+
# Data type for Go
|
27
|
+
# @return [String]
|
28
|
+
attr_reader :go_type
|
29
|
+
|
30
|
+
# @return [Metadata]
|
31
|
+
attr_reader :metadata
|
32
|
+
|
33
|
+
# @return [InputOutput]
|
34
|
+
attr_reader :input
|
35
|
+
|
36
|
+
# @return [InputOutput]
|
37
|
+
attr_reader :output
|
38
|
+
|
39
|
+
# @return [String]
|
40
|
+
attr_reader :http_method
|
41
|
+
|
42
|
+
# @return [String]
|
43
|
+
attr_reader :path
|
44
|
+
|
45
|
+
# Go type for invocation struct
|
46
|
+
# @return [String]
|
47
|
+
attr_reader :go_invocation_type
|
48
|
+
|
49
|
+
# Go type for request struct
|
50
|
+
# @return [String]
|
51
|
+
attr_reader :go_request_type
|
52
|
+
|
53
|
+
# Go type for response struct
|
54
|
+
# @return [String]
|
55
|
+
attr_reader :go_response_type
|
56
|
+
|
57
|
+
def initialize(resource, name, desc, prefix: nil)
|
58
|
+
@resource = resource
|
59
|
+
@name = name.to_s
|
60
|
+
@prefix = prefix
|
61
|
+
@aliases = desc[:aliases]
|
62
|
+
@full_dot_name = resource.full_dot_name + '#' + @name.capitalize
|
63
|
+
@go_name = camelize(name)
|
64
|
+
@go_type = full_go_type
|
65
|
+
@go_invocation_type = go_type + 'Invocation'
|
66
|
+
@go_request_type = go_type + 'Request'
|
67
|
+
@go_response_type = go_type + 'Response'
|
68
|
+
@input = desc[:input] && InputOutput.new(self, :io, :input, desc[:input])
|
69
|
+
@output = desc[:output] && InputOutput.new(self, :io, :output, desc[:output])
|
70
|
+
@http_method = desc[:method]
|
71
|
+
@path = desc[:path]
|
72
|
+
@metadata = desc[:meta] && Metadata.new(self, desc[:meta])
|
73
|
+
@blocking = desc[:blocking]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return action name with all aliases, camelized
|
77
|
+
# @return [Array<String>]
|
78
|
+
def all_names
|
79
|
+
yield(go_name)
|
80
|
+
aliases.each { |v| yield(camelize(v)) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Boolean]
|
84
|
+
def has_path_params?
|
85
|
+
path =~ /\{[a-zA-Z\-_]+\}/
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Boolean]
|
89
|
+
def has_input?
|
90
|
+
input && input.parameters.any?
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Boolean]
|
94
|
+
def has_output?
|
95
|
+
output && output.parameters.any?
|
96
|
+
end
|
97
|
+
|
98
|
+
def input_output
|
99
|
+
%i(input output).select do |v|
|
100
|
+
send(v) && send(v).parameters.any?
|
101
|
+
end.map { |v| send(v) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def blocking?
|
105
|
+
@blocking
|
106
|
+
end
|
107
|
+
|
108
|
+
def resolve_associations
|
109
|
+
input_output.each do |io|
|
110
|
+
io.resolve_associations
|
111
|
+
end
|
112
|
+
|
113
|
+
metadata && metadata.resolve_associations
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
attr_reader :prefix
|
118
|
+
|
119
|
+
def full_go_type
|
120
|
+
names = []
|
121
|
+
names << camelize(prefix) if prefix
|
122
|
+
names << 'Action'
|
123
|
+
names.concat(resource.resource_path.map(&:go_name))
|
124
|
+
names << go_name
|
125
|
+
names.join('')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module HaveAPI::GoClient
|
2
|
+
class ApiVersion
|
3
|
+
# @return [Array<Authentication::Base>]
|
4
|
+
attr_reader :auth_methods
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :metadata_namespace
|
8
|
+
|
9
|
+
# @return [Array<Resource>]
|
10
|
+
attr_reader :resources
|
11
|
+
|
12
|
+
def initialize(desc)
|
13
|
+
@resources = desc[:resources].map { |k, v| Resource.new(self, k, v) }
|
14
|
+
@resources.each { |r| r.resolve_associations }
|
15
|
+
@auth_methods = desc[:authentication].map do |k, v|
|
16
|
+
AuthenticationMethods.new(self, k, v)
|
17
|
+
end
|
18
|
+
@metadata_namespace = desc[:meta][:namespace]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'haveapi/go_client/authentication/base'
|
2
|
+
|
3
|
+
module HaveAPI::GoClient
|
4
|
+
class Authentication::Basic < Authentication::Base
|
5
|
+
register :basic
|
6
|
+
|
7
|
+
def initialize(api_version, name, desc)
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate(gen)
|
12
|
+
ErbTemplate.render_to_if_changed(
|
13
|
+
'authentication/basic.go',
|
14
|
+
{
|
15
|
+
package: gen.package,
|
16
|
+
},
|
17
|
+
File.join(gen.dst, 'auth_basic.go')
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'haveapi/go_client/authentication/base'
|
2
|
+
|
3
|
+
module HaveAPI::GoClient
|
4
|
+
class Authentication::Token < Authentication::Base
|
5
|
+
register :token
|
6
|
+
|
7
|
+
# HTTP header the token is sent in
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :http_header
|
10
|
+
|
11
|
+
# Query parameter the token is sent in
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :query_parameter
|
14
|
+
|
15
|
+
# Resource for token manipulation
|
16
|
+
# @return [Resource]
|
17
|
+
attr_reader :resource
|
18
|
+
|
19
|
+
def initialize(api_version, name, desc)
|
20
|
+
@http_header = desc[:http_header]
|
21
|
+
@query_parameter = desc[:query_parameter]
|
22
|
+
@resource = Resource.new(
|
23
|
+
api_version,
|
24
|
+
:token,
|
25
|
+
desc[:resources][:token],
|
26
|
+
prefix: 'auth_token',
|
27
|
+
)
|
28
|
+
resource.resolve_associations
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate(gen)
|
32
|
+
ErbTemplate.render_to_if_changed(
|
33
|
+
'authentication/token.go',
|
34
|
+
{
|
35
|
+
package: gen.package,
|
36
|
+
auth: self,
|
37
|
+
},
|
38
|
+
File.join(gen.dst, 'auth_token.go')
|
39
|
+
)
|
40
|
+
|
41
|
+
resource.generate(gen)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Action]
|
45
|
+
def request_action
|
46
|
+
@request_action ||= resource.actions.detect { |a| a.name == 'request' }
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Array<Action>]
|
50
|
+
def custom_actions
|
51
|
+
@custom_actions ||= resource.actions.reject do |a|
|
52
|
+
%w(request renew revoke).include?(a.name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'haveapi/go_client/authentication/base'
|
2
|
+
|
3
|
+
module HaveAPI::GoClient
|
4
|
+
class Authentication::Unsupported < Authentication::Base
|
5
|
+
def initialize(api_version, name, desc)
|
6
|
+
warn "Ignoring unsupported authentication method #{name}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate(gen)
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HaveAPI::GoClient
|
2
|
+
module Authentication ; end
|
3
|
+
|
4
|
+
module AuthenticationMethods
|
5
|
+
# @param name [Symbol]
|
6
|
+
# @param klass [Class]
|
7
|
+
def self.register(name, klass)
|
8
|
+
@methods ||= {}
|
9
|
+
@methods[name] = klass
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param name [String]
|
13
|
+
def self.get(name)
|
14
|
+
@methods[name.to_sym]
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param api_version [ApiVersion]
|
18
|
+
# @param name [String]
|
19
|
+
def self.new(api_version, name, *args)
|
20
|
+
klass = get(name) || Authentication::Unsupported
|
21
|
+
klass.new(api_version, name, *args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'haveapi/go_client'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module HaveAPI::GoClient
|
5
|
+
class Cli
|
6
|
+
def self.run
|
7
|
+
options = {
|
8
|
+
package: 'client',
|
9
|
+
}
|
10
|
+
|
11
|
+
parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: #{$0} [options] <api url> <destination>"
|
13
|
+
|
14
|
+
opts.on('--version VERSION', 'Use specified API version') do |v|
|
15
|
+
options[:version] = v
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on('--module MODULE', 'Name of the generated Go module') do |v|
|
19
|
+
options[:module] = v
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('--package PKG', 'Name of the generated Go package') do |v|
|
23
|
+
options[:package] = v
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
parser.parse!
|
28
|
+
|
29
|
+
if ARGV.length != 2
|
30
|
+
warn 'Invalid arguments'
|
31
|
+
puts @global_opt.help
|
32
|
+
exit(false)
|
33
|
+
end
|
34
|
+
|
35
|
+
g = Generator.new(ARGV[0], ARGV[1], options)
|
36
|
+
g.generate
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module HaveAPI::GoClient
|
5
|
+
class ErbTemplate
|
6
|
+
def self.render(name, vars)
|
7
|
+
t = new(name, vars)
|
8
|
+
t.render
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.render_to(name, vars, path)
|
12
|
+
File.write("#{path}.new", render(name, vars))
|
13
|
+
File.rename("#{path}.new", path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.render_to_if_changed(name, vars, path)
|
17
|
+
tmp_path = "#{path}.new"
|
18
|
+
File.write(tmp_path, render(name, vars))
|
19
|
+
|
20
|
+
if !File.exist?(path) || !FileUtils.identical?(path, tmp_path)
|
21
|
+
File.rename(tmp_path, path)
|
22
|
+
|
23
|
+
else
|
24
|
+
File.unlink(tmp_path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(name, vars)
|
29
|
+
@_tpl = ERB.new(File.new(HaveAPI::GoClient.tpl(name)).read, 0, '-')
|
30
|
+
|
31
|
+
vars.each do |k, v|
|
32
|
+
if v.is_a?(Proc)
|
33
|
+
define_singleton_method(k, &v)
|
34
|
+
elsif v.is_a?(Method)
|
35
|
+
define_singleton_method(k) { |*args| v.call(*args) }
|
36
|
+
else
|
37
|
+
define_singleton_method(k) { v }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def render
|
43
|
+
@_tpl.result(binding)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'haveapi/client'
|
3
|
+
|
4
|
+
module HaveAPI::GoClient
|
5
|
+
class Generator
|
6
|
+
# Destination directory
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :dst
|
9
|
+
|
10
|
+
# Go module name
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :module
|
13
|
+
|
14
|
+
# Go package name
|
15
|
+
# @return [String]
|
16
|
+
attr_reader :package
|
17
|
+
|
18
|
+
# @param url [String] API URL
|
19
|
+
# @param dst [String] destination directory
|
20
|
+
# @param opts [Hash]
|
21
|
+
# @option opts [String] :version
|
22
|
+
# @option opts [String] :module
|
23
|
+
# @option opts [String] :package
|
24
|
+
def initialize(url, dst, opts)
|
25
|
+
@dst = dst
|
26
|
+
@module = opts[:module]
|
27
|
+
@package = opts[:package]
|
28
|
+
|
29
|
+
conn = HaveAPI::Client::Communicator.new(url)
|
30
|
+
@api = ApiVersion.new(conn.describe_api(opts[:version]))
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate
|
34
|
+
FileUtils.mkpath(dst)
|
35
|
+
|
36
|
+
if self.module
|
37
|
+
ErbTemplate.render_to_if_changed(
|
38
|
+
'go.mod',
|
39
|
+
{mod: self.module},
|
40
|
+
File.join(dst, 'go.mod')
|
41
|
+
)
|
42
|
+
|
43
|
+
@dst = File.join(dst, package)
|
44
|
+
FileUtils.mkpath(dst)
|
45
|
+
end
|
46
|
+
|
47
|
+
%w(client authentication request response types).each do |v|
|
48
|
+
ErbTemplate.render_to_if_changed(
|
49
|
+
"#{v}.go",
|
50
|
+
{
|
51
|
+
package: package,
|
52
|
+
api: api,
|
53
|
+
},
|
54
|
+
File.join(dst, "#{v}.go")
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
api.resources.each { |r| r.generate(self) }
|
59
|
+
api.auth_methods.each { |v| v.generate(self) }
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
attr_reader :api
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'haveapi/go_client/utils'
|
2
|
+
|
3
|
+
module HaveAPI::GoClient
|
4
|
+
class InputOutput
|
5
|
+
include Utils
|
6
|
+
|
7
|
+
# @return [Action]
|
8
|
+
attr_reader :action
|
9
|
+
|
10
|
+
# @return [Symbol]
|
11
|
+
attr_reader :role
|
12
|
+
|
13
|
+
# @return [Symbol]
|
14
|
+
attr_reader :direction
|
15
|
+
|
16
|
+
# @return [String]
|
17
|
+
attr_reader :layout
|
18
|
+
|
19
|
+
# @return [String]
|
20
|
+
attr_reader :namespace
|
21
|
+
|
22
|
+
# @return [Array<Parameter>]
|
23
|
+
attr_reader :parameters
|
24
|
+
|
25
|
+
# @return [String]
|
26
|
+
attr_reader :go_type
|
27
|
+
|
28
|
+
# @return [String]
|
29
|
+
attr_reader :go_namespace
|
30
|
+
|
31
|
+
def initialize(action, role, direction, desc, prefix: nil)
|
32
|
+
@action = action
|
33
|
+
@role = role
|
34
|
+
@direction = direction
|
35
|
+
@layout = desc[:layout]
|
36
|
+
@namespace = desc[:namespace]
|
37
|
+
@parameters = desc[:parameters].map do |k, v|
|
38
|
+
Parameter.new(role, direction, self, k.to_s, v)
|
39
|
+
end.compact
|
40
|
+
@go_type = action.go_type + (prefix ? prefix : '') + direction.to_s.capitalize
|
41
|
+
@go_namespace = camelize(desc[:namespace])
|
42
|
+
end
|
43
|
+
|
44
|
+
def resolve_associations
|
45
|
+
parameters.each { |p| p.resolve }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module HaveAPI::GoClient
|
2
|
+
class Metadata
|
3
|
+
class Type
|
4
|
+
# @return [InputOutput, nil]
|
5
|
+
attr_reader :input
|
6
|
+
|
7
|
+
# @return [InputOutput, nil]
|
8
|
+
attr_reader :output
|
9
|
+
|
10
|
+
def initialize(action, type, desc)
|
11
|
+
@input = desc[:input] && InputOutput.new(
|
12
|
+
action,
|
13
|
+
:"#{type}_meta",
|
14
|
+
:input,
|
15
|
+
desc[:input],
|
16
|
+
prefix: "Meta#{type.to_s.capitalize}"
|
17
|
+
)
|
18
|
+
@output = desc[:output] && InputOutput.new(
|
19
|
+
action,
|
20
|
+
:"#{type}_meta",
|
21
|
+
:output,
|
22
|
+
desc[:output],
|
23
|
+
prefix: "Meta#{type.to_s.capitalize}"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def resolve_associations
|
28
|
+
input && input.resolve_associations
|
29
|
+
output && output.resolve_associations
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Type, nil]
|
34
|
+
attr_reader :global
|
35
|
+
|
36
|
+
# @return [Type, nil]
|
37
|
+
attr_reader :object
|
38
|
+
|
39
|
+
def initialize(action, desc)
|
40
|
+
@global = desc[:global] && Type.new(action, :global, desc[:global])
|
41
|
+
@object = desc[:object] && Type.new(action, :object, desc[:object])
|
42
|
+
end
|
43
|
+
|
44
|
+
def resolve_associations
|
45
|
+
global && global.resolve_associations
|
46
|
+
object && object.resolve_associations
|
47
|
+
end
|
48
|
+
|
49
|
+
%i(global object).each do |type|
|
50
|
+
%i(input output).each do |dir|
|
51
|
+
define_method(:"has_#{type}_#{dir}?") do
|
52
|
+
t = send(type)
|
53
|
+
next(false) unless t
|
54
|
+
|
55
|
+
io = t.send(dir)
|
56
|
+
next(false) unless io
|
57
|
+
|
58
|
+
io.parameters.any?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module HaveAPI::GoClient
|
2
|
+
module Parameters ; end
|
3
|
+
|
4
|
+
module Parameter
|
5
|
+
# @param klass [Class]
|
6
|
+
# @param block [Proc]
|
7
|
+
def self.register(klass, block)
|
8
|
+
@handlers ||= []
|
9
|
+
@handlers << [klass, block]
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param role [Symbol]
|
13
|
+
# @param direction [Symbol]
|
14
|
+
# @param io [InputOutput]
|
15
|
+
# @param name [String]
|
16
|
+
# @param desc [Hash]
|
17
|
+
# @return [Parameters::Base, nil]
|
18
|
+
def self.new(role, direction, io, name, desc)
|
19
|
+
klass, _ =
|
20
|
+
@handlers.select do |klass, block|
|
21
|
+
block.call(role, direction, name, desc)
|
22
|
+
end.first
|
23
|
+
|
24
|
+
klass ? klass.new(io, name, desc) : nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|