web_function 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c451f0b269e4441e7982d789b8fb4a4d827543e9d9f8769aa2bc4350a667435b
4
- data.tar.gz: 1fe79584e5f3cd31f5792c63c7fed415cc999ccafbf736bb41f8a024c0c65690
3
+ metadata.gz: c025fe8ca089b9531bc819d3154438bb29eb0b5fa823509b212fb23858403b5f
4
+ data.tar.gz: 6e2efbc2c7a4ebaef81ef95b8485b8822666a01967ebb46a3220ddab2caf26a1
5
5
  SHA512:
6
- metadata.gz: 07f4280c1e265f99898667f4860f1772088ae729fc41080ab27e2f6db1bd88d3611efc5314d2ab6b43c222c38be2f612772fd4167c41f8a5d17db6dd06aefa7c
7
- data.tar.gz: 0b529bea38f2866549209a7d01fa5a8b126b17b79c4791ebf60ebd2407136dfabc7657c82efebea3275bbf9ad9b686943d797ccd3b397e2c6e124aab338a307f
6
+ metadata.gz: acbc56f7b1b5ec89c17eb8f44699197ded36a0c3db4e722b57087bf164c0fe1f2a3c62e15223971e488721008891ce1714d2b2ce8a82dd0267b950694e8b4a46
7
+ data.tar.gz: 9028501396902aa1adb0ebe548eaa4f16bf9065c11e3777512ae5ef31652e9d007dffa5b2bdff60c95c5bb451221145b6a5e08d0bd73a89e34befe73db534597
data/exe/wfn CHANGED
@@ -8,10 +8,17 @@ require "json"
8
8
  # wfn call --auth token endpoint_url key1=value1 [key2=value2 ...]
9
9
 
10
10
  auth_token = nil
11
- auth_idx = ARGV.index("--auth")
12
- if auth_idx
13
- auth_token = ARGV[auth_idx + 1]
14
- ARGV.slice!(auth_idx, 2)
11
+ auth_index = ARGV.index("--auth")
12
+ if auth_index
13
+ auth_token = ARGV[auth_index + 1]
14
+ ARGV.slice!(auth_index, 2)
15
+ end
16
+
17
+ version = nil
18
+ version_index = ARGV.index("--version")
19
+ if version_index
20
+ version = ARGV[version_index + 1]
21
+ ARGV.slice!(version_index, 2)
15
22
  end
16
23
 
17
24
  command = ARGV[0]
@@ -22,7 +29,7 @@ when "call"
22
29
  args = JSON.parse(ARGV[2] || "{}")
23
30
 
24
31
  begin
25
- response = WebFunction::Endpoint.invoke(endpoint_url, bearer_auth: auth_token, args: args)
32
+ response = WebFunction::Request.execute(endpoint_url, bearer_auth: auth_token, version: version, args: args)
26
33
  puts JSON.pretty_generate(response)
27
34
  rescue WebFunction::Error => e
28
35
  puts e
@@ -1,107 +1,135 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebFunction
4
- # # Argument
5
- #
6
- # Arguments used by Web Function endpoints to define its input parameters.
4
+ # Arguments are used to define Web Function {Endpoint} request parameters.
7
5
  #
8
6
  # See the [arguments section][0] on the Web Function website for more details.
9
7
  #
10
8
  # [0]: https://webfunction.org/package#arguments
11
9
  #
12
10
  class Argument
13
- def initialize(argument)
14
- @argument = argument
11
+ include Flaggable
12
+
13
+ def initialize(name:, type:, hint: nil, group: nil, choices: [], flags: [], docs: nil)
14
+ @name = name
15
+ @type = type
16
+ @hint = hint
17
+ @group = group
18
+ @choices = choices
19
+ @flags = flags
20
+ @docs = docs.to_s
21
+ end
22
+
23
+ class << self
24
+ # Instantiate a new Argument from a hash, typically coming from a {Package}.
25
+ #
26
+ # @param argument [Hash]
27
+ #
28
+ # @return [Argument, nil]
29
+ #
30
+ def from_hash(argument)
31
+ unless argument.is_a?(Hash)
32
+ return
33
+ end
34
+
35
+ unless argument["name"]
36
+ return
37
+ end
38
+
39
+ unless argument["type"]
40
+ return
41
+ end
42
+
43
+ new(
44
+ name: argument["name"],
45
+ type: argument["type"],
46
+ hint: argument["hint"],
47
+ group: argument["group"],
48
+ choices: [*argument["choices"]],
49
+ flags: Utils.normalize_array_of_strings(argument["flags"]),
50
+ docs: argument["docs"],
51
+ )
52
+ end
53
+
54
+ # Instantiate a collection of Argument from an array of hash, typically coming from a {Package}. Uses
55
+ # {Argument#from_hash} under the hood.
56
+ #
57
+ # @param arguments [Array<Hash>]
58
+ #
59
+ # @return [Array<Argument>]
60
+ #
61
+ def from_array(arguments)
62
+ Utils.normalize_array arguments do |argument|
63
+ from_hash(argument)
64
+ end
65
+ end
15
66
  end
16
67
 
17
- # ## Name
18
- #
19
68
  # The name of the argument.
20
69
  #
21
70
  # @return [String]
22
71
  #
23
- def name
24
- @argument["name"]
25
- end
72
+ attr_reader :name
26
73
 
27
- # ## Type
28
- #
29
74
  # The type of the argument. It must be one of:
30
- # - object
31
- # - array
32
- # - string
33
- # - number
34
- # - boolean
75
+ #
76
+ # - object
77
+ # - array
78
+ # - string
79
+ # - number
80
+ # - boolean
35
81
  #
36
82
  # @return [String]
37
83
  #
38
- def type
39
- @argument["type"]
40
- end
84
+ attr_reader :type
41
85
 
42
- # ## Hint
86
+ # A hint that further defines what kind of value to expect for an argument.
43
87
  #
44
- # The hint of the argument
45
- #
46
- # See the [hints section][1] on the Web Function website for the full list
47
- # of possible hints.
88
+ # See the [hints section][1] on the Web Function website for the full list of possible hints.
48
89
  #
49
90
  # @return [String]
50
91
  #
51
92
  # [1]: https://webfunction.org/package#hints
52
93
  #
53
- def hint
54
- @argument["hint"]
55
- end
94
+ attr_reader :hint
56
95
 
57
- # ## Group
58
- #
59
- # A name used to categorize or group similar arguments together. This
60
- # should be used by documentation tools to organize related arguments.
96
+ # A name used to categorize or group similar arguments together. This should be used by documentation tools to
97
+ # organize related arguments.
61
98
  #
62
99
  # @return [String]
63
100
  #
64
- def group
65
- @argument["group"]
66
- end
101
+ attr_reader :group
67
102
 
68
- # ## Choices
69
- #
70
- # An array specifying the exact, case-sensitive values that are permitted
71
- # for this argument. Each value in the choices array must conform to the
72
- # data type specified in the argument's type key.
103
+ # An array specifying the exact, case-sensitive values that are permitted for this argument. Each value in the
104
+ # choices array must conform to the data type specified in the argument's type key.
73
105
  #
74
- # Note that if the argument type is array, choices may contain strings or
75
- # numbers representing the allowed values that can be included in the array.
106
+ # Note that if the argument type is array, choices may contain strings or numbers representing the allowed values
107
+ # that can be included in the array.
76
108
  #
77
109
  # @return [Array]
78
110
  #
79
- def choices
80
- [*@argument["choices"]]
81
- end
111
+ attr_reader :choices
82
112
 
83
- # ## Flags
113
+ # Description of the argument. It must be formatted as markdown.
84
114
  #
85
- # List of argument flags. See the [available flags section][2] on the Web
86
- # Function website for a complete list of flags available at the
87
- # argument level.
115
+ # @return [String]
88
116
  #
89
- # @return [Array<String>]
117
+ attr_reader :docs
118
+
119
+ # Whether the argument is required.
90
120
  #
91
- # [2]: https://webfunction.org/package#available-flags
121
+ # @return [Boolean]
92
122
  #
93
- def flags
94
- [*@argument["flags"]].map { |flag| flag.to_s }
123
+ def required?
124
+ flag?("required")
95
125
  end
96
126
 
97
- # ## Docs
127
+ # Whether the argument is optional.
98
128
  #
99
- # Description of the argument. It must be formatted as markdown.
100
- #
101
- # @return [String]
129
+ # @return [Boolean]
102
130
  #
103
- def docs
104
- @argument["docs"].to_s
131
+ def optional?
132
+ !required?
105
133
  end
106
134
  end
107
135
  end
@@ -1,100 +1,124 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebFunction
4
- # # Attribute
4
+ # Attributes define output fields that may be produced and returned by a Web Function {Endpoint} when the type of the
5
+ # return is `object`.
5
6
  #
6
- # An Attribute defines an output field that may be produced and returned by a
7
- # Web Function endpoint.
8
- #
9
- # See the [attributes section][0] on the Web Function website for more
10
- # details about attribute definitions, recognized keys, and usage.
7
+ # See the [attributes section][0] on the Web Function website for more details about attribute definitions,
8
+ # recognized keys, and usage.
11
9
  #
12
10
  # [0]: https://webfunction.org/package#attributes
13
11
  #
14
12
  class Attribute
15
- def initialize(attribute)
16
- @attribute = attribute
13
+ include Flaggable
14
+
15
+ def initialize(name:, type:, hint: nil, values: [], flags: [], docs: nil)
16
+ @name = name
17
+ @type = type
18
+ @hint = hint
19
+ @values = values
20
+ @flags = flags
21
+ @docs = docs.to_s
22
+ end
23
+
24
+ class << self
25
+ # Creates a new Attribute from a hash. Typically coming from a {Package}.
26
+ #
27
+ # @param attribute [Hash] The attribute hash
28
+ #
29
+ # @return [Attribute] A new Attribute instance
30
+ #
31
+ def from_hash(attribute)
32
+ unless attribute.is_a?(Hash)
33
+ return
34
+ end
35
+
36
+ unless attribute["name"]
37
+ return
38
+ end
39
+
40
+ unless attribute["type"]
41
+ return
42
+ end
43
+
44
+ new(
45
+ name: attribute["name"],
46
+ type: attribute["type"],
47
+ hint: attribute["hint"],
48
+ values: [*attribute["values"]],
49
+ flags: Utils.normalize_array_of_strings(attribute["flags"]),
50
+ docs: attribute["docs"],
51
+ )
52
+ end
53
+
54
+ # Creates a new Attribute from an array of hashes. Typically coming from a {Package}. Uses {Attribute#from_hash}
55
+ # under the hood.
56
+ #
57
+ # @param attributes [Array<Hash>] The attribute array of hashes
58
+ #
59
+ # @return [Array<Attribute>] A new array of Attribute instances
60
+ #
61
+ def from_array(attributes)
62
+ Utils.normalize_array attributes do |attribute|
63
+ from_hash(attribute)
64
+ end
65
+ end
17
66
  end
18
67
 
19
- # ## Name
20
- #
21
68
  # The name of the attribute as it will appear in the endpoint's output
22
69
  # object.
23
70
  #
71
+ # This is required for the argument to be valid.
72
+ #
24
73
  # @return [String]
25
74
  #
26
- def name
27
- @attribute["name"]
28
- end
75
+ attr_reader :name
29
76
 
30
- # ## Type
31
- #
32
77
  # The type of value returned for this attribute. Must be one of:
33
- # - object
34
- # - array
35
- # - string
36
- # - number
37
- # - boolean
38
78
  #
39
- # This is a required string.
79
+ # - object
80
+ # - array
81
+ # - string
82
+ # - number
83
+ # - boolean
84
+ #
85
+ # This is required for the argument to be valid.
40
86
  #
41
87
  # @return [String]
42
88
  #
43
- def type
44
- @attribute["type"]
45
- end
89
+ attr_reader :type
46
90
 
47
- # ## Hint
48
- #
49
- # A string hinting about the semantics of this attribute. See the
50
- # [hints section][1] for possible values and documentation tooling guidance.
91
+ # A string hinting about the semantics of this attribute. See the [hints section][1] for possible values and
92
+ # documentation tooling guidance.
51
93
  #
52
94
  # [1]: https://webfunction.org/package#hints
53
95
  #
54
96
  # @return [String, nil]
55
97
  #
56
- def hint
57
- @attribute["hint"]
58
- end
98
+ attr_reader :hint
59
99
 
60
- # ## Values
61
- #
62
- # An array specifying the exact, case-sensitive values that may be returned
63
- # for this attribute. Each value in the values array must conform to the
64
- # data type specified in the "type" key.
100
+ # An array specifying the exact, case-sensitive values that may be returned for this attribute. Each value in the
101
+ # values array must conform to the data type specified in the "type" key.
65
102
  #
66
- # This is useful for attributes that can only take a select set of values
67
- # (enums or constants).
103
+ # This is useful for attributes that can only take a select set of values (enums or constants).
68
104
  #
69
105
  # @return [Array]
70
106
  #
71
- def values
72
- [*@attribute["values"]]
73
- end
107
+ attr_reader :values
74
108
 
75
- # ## Flags
109
+ # A markdown string describing this attribute and its purpose in the output object. Used by documentation tools,
110
+ # and highly recommended.
76
111
  #
77
- # An array of attribute flags. Flags describe special characteristics or
78
- # behaviors of attributes. See the [available flags section][2] for
79
- # complete list and documentation.
80
- #
81
- # [2]: https://webfunction.org/package#available-flags
82
- #
83
- # @return [Array<String>]
112
+ # @return [String]
84
113
  #
85
- def flags
86
- [*@attribute["flags"]].map(&:to_s)
87
- end
114
+ attr_reader :docs
88
115
 
89
- # ## Docs
90
- #
91
- # A markdown string describing this attribute and its purpose in the output
92
- # object. Used by documentation tools, and highly recommended.
116
+ # Whether the attribute can be null.
93
117
  #
94
- # @return [String]
118
+ # @return [Boolean]
95
119
  #
96
- def docs
97
- @attribute["docs"].to_s
120
+ def nullable?
121
+ flag?("nullable")
98
122
  end
99
123
  end
100
124
  end
@@ -1,72 +1,116 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebFunction
4
- # # Client
5
- #
6
- # A Client is a wrapper around a Web Function package that provides a
7
- # convenient interface for invoking endpoints.
4
+ # A {Client} is a wrapper around a Web Function {Package} that provides a convenient interface for invoking endpoints.
8
5
  #
9
6
  # @example
10
7
  # client = WebFunction::Client.from_package_endpoint("https://api.webfunction.com/package")
11
8
  # client.list_items(a: "b") # => { "c" => "d" }
12
9
  #
13
10
  class Client < BasicObject
14
- def initialize(package, bearer_auth: nil, pipeline: nil)
11
+ def initialize(base_url:, endpoints: [], package: nil, bearer_auth: nil, version: nil, pipeline: nil)
15
12
  @package = package
16
- @endpoints = package.endpoints.to_h { |e| [e.name.gsub("-", "_").to_sym, e] }
13
+ @base_url = base_url
14
+ @endpoints = endpoints.to_h { |e| [e.gsub("-", "_").to_sym, e] }
17
15
  @bearer_auth = bearer_auth
16
+ @version = version
18
17
  @pipeline = pipeline
19
18
  end
20
19
 
21
- attr_reader :package
20
+ class << self
21
+ # Creates a new {Client} from an url.
22
+ #
23
+ # @param url [String] The URL of the package endpoint
24
+ # @param bearer_auth [String] The bearer authentication token
25
+ # @param version [String] The API version to use
26
+ # @param pipelined [Boolean] Whether to have the client use call pipelining
27
+ #
28
+ # @return [Client]
29
+ #
30
+ def from_package_endpoint(url, bearer_auth: nil, version: nil, pipelined: false)
31
+ response = ::WebFunction::Request.execute(url, bearer_auth: bearer_auth, version: version)
32
+ package = ::WebFunction::Package.from_hash(response)
22
33
 
23
- # ## Instantiates a new Client from a package endpoint
24
- #
25
- # Creates a new Client from a package endpoint.
34
+ from_package(package, bearer_auth: bearer_auth, version: version, pipelined: pipelined)
35
+ end
36
+
37
+ # Creates a new {Client} from a {Package}.
38
+ #
39
+ # @param package [Package] A package
40
+ # @param bearer_auth [String] The bearer authentication token
41
+ # @param version [String] The API version to use
42
+ # @param pipelined [Boolean] Whether to have the client use call pipelining
43
+ #
44
+ # @return [Client]
45
+ #
46
+ def from_package(package, bearer_auth: nil, version: nil, pipelined: nil)
47
+ pipeline = nil
48
+
49
+ if pipelined
50
+ pipeline = package.pipeline
51
+ end
52
+
53
+ client = new(
54
+ package: package,
55
+ base_url: package.base_url,
56
+ endpoints: package.endpoints.map(&:name),
57
+ bearer_auth: bearer_auth,
58
+ version: version,
59
+ pipeline: pipeline,
60
+ )
61
+
62
+ package.endpoints.each do |endpoint|
63
+ endpoint.client = client
64
+ end
65
+
66
+ client
67
+ end
68
+ end
69
+
70
+ # Call an endpoint by name with the given arguments.
26
71
  #
27
- # @param url [String] The URL of the package endpoint
28
- # @param bearer_auth [String] The bearer authentication token
29
- # @param pipeline_url [String] The URL of the pipeline endpoint
30
- # @param pipeline [Pipeline] The pipeline to use
72
+ # @param endpoint_name [String] The name of the endpoint to call
73
+ # @param args [Hash] The arguments to send to the endpoint
31
74
  #
32
- # @return [Client] A new Client instance
75
+ # @return [Object] The decoded response returned by the endpoint
33
76
  #
34
- def self.from_package_endpoint(url, bearer_auth: nil, pipeline_url: nil, pipeline: nil)
35
- response = ::WebFunction::Endpoint.invoke(url, bearer_auth: bearer_auth)
36
- package = ::WebFunction::Package.new(response)
77
+ def call(endpoint_name, args = {})
78
+ url = ::URI.join(@base_url, endpoint_name).to_s
79
+ request = ::WebFunction::Request.new(url,
80
+ bearer_auth: @bearer_auth,
81
+ version: @version,
82
+ args: args,
83
+ )
37
84
 
38
- if pipeline_url.is_a?(::String)
39
- pipeline = ::WebFunction::Pipeline.new(pipeline_url)
85
+ if @pipeline
86
+ @pipeline.add_step(request.as_pipeline_step)
87
+ else
88
+ request.execute
40
89
  end
41
-
42
- new(package, bearer_auth: bearer_auth, pipeline: pipeline)
43
90
  end
44
91
 
45
- def methods #:nodoc:
46
- super + @endpoints.keys
92
+ # The package that this client is wrapping.
93
+ #
94
+ # @return [Package]
95
+ #
96
+ attr_reader :package
97
+
98
+ def methods # :nodoc:
99
+ @endpoints.keys
47
100
  end
48
101
 
49
- def respond_to_missing?(method_name, include_private = false) #:nodoc:
50
- @endpoints[method_name] || super
102
+ def respond_to_missing?(method_name, include_private = false) # :nodoc:
103
+ @endpoints[method_name]
51
104
  end
52
105
 
53
- def method_missing(method_name, *args) #:nodoc:
54
- endpoint = @endpoints[method_name]
106
+ def method_missing(method_name, *args) # :nodoc:
107
+ endpoint_name = @endpoints[method_name]
55
108
 
56
- unless endpoint
109
+ unless endpoint_name
57
110
  super
58
111
  end
59
112
 
60
- url = ::URI.join(@package.base_url, endpoint.name).to_s
61
- args = args.first
62
-
63
- if @pipeline
64
- step = ::WebFunction::Endpoint.step(url, bearer_auth: @bearer_auth, args: args)
65
- promise = @pipeline.add_step(step)
66
- return promise
67
- end
68
-
69
- ::WebFunction::Endpoint.invoke(url, bearer_auth: @bearer_auth, args: args)
113
+ call(endpoint_name, args.first)
70
114
  end
71
115
  end
72
116
  end
@@ -1,39 +1,67 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WebFunction
2
- # # DocumentedError
3
- #
4
4
  # Represents an error definition as described in a Web Function package.
5
5
  #
6
- # An error definition documents the possible errors that an endpoint might return,
7
- # including a machine-readable error code and a human-readable description.
6
+ # An error definition documents the possible errors that an endpoint might return, including a machine-readable error
7
+ # code and a human-readable description.
8
8
  #
9
- # See the [error definition documentation][0] on the Web Function website for more details,
10
- # including recognized keys and usage recommendations.
9
+ # See the [error definition documentation][0] on the Web Function website for more details, including recognized keys
10
+ # and usage recommendations.
11
11
  #
12
12
  # [0]: https://webfunction.org/package#error-definition
13
13
  #
14
14
  class DocumentedError
15
- def initialize(error)
16
- @error = error
15
+ def initialize(code:, docs: nil)
16
+ @code = code
17
+ @docs = docs.to_s
17
18
  end
18
19
 
19
- # ## Code
20
- #
21
- # The code of the error.
20
+ class << self
21
+ # Creates a new DocumentedError from a hash.
22
+ #
23
+ # @param error [Hash] The error hash
24
+ #
25
+ # @return [DocumentedError] A new DocumentedError instance
26
+ #
27
+ def from_hash(error)
28
+ unless error.is_a?(Hash)
29
+ return
30
+ end
31
+
32
+ unless error["code"]
33
+ return
34
+ end
35
+
36
+ new(
37
+ code: error["code"],
38
+ docs: error["docs"],
39
+ )
40
+ end
41
+
42
+ # Creates a new DocumentedError from an array of hashes. Uses {DocumentedError#from_hash} under the hood.
43
+ #
44
+ # @param errors [Array<Hash>] The error array of hashes
45
+ #
46
+ # @return [Array<DocumentedError>] A new array of DocumentedError instances
47
+ #
48
+ def from_array(errors)
49
+ Utils.normalize_array errors do |error|
50
+ from_hash(error)
51
+ end
52
+ end
53
+ end
54
+
55
+ # The machine-readable code of the error.
22
56
  #
23
57
  # @return [String]
24
58
  #
25
- def code
26
- @error["code"]
27
- end
59
+ attr_reader :code
28
60
 
29
- # ## Docs
30
- #
31
61
  # The documentation of the error.
32
62
  #
33
63
  # @return [String]
34
64
  #
35
- def docs
36
- @error["docs"].to_s
37
- end
65
+ attr_reader :docs
38
66
  end
39
67
  end