haveapi-go-client 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|