discourse_zendesk_api 1.0.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/LICENSE +176 -0
- data/lib/zendesk_api/actions.rb +334 -0
- data/lib/zendesk_api/association.rb +195 -0
- data/lib/zendesk_api/associations.rb +212 -0
- data/lib/zendesk_api/client.rb +243 -0
- data/lib/zendesk_api/collection.rb +474 -0
- data/lib/zendesk_api/configuration.rb +79 -0
- data/lib/zendesk_api/core_ext/inflection.rb +3 -0
- data/lib/zendesk_api/delegator.rb +5 -0
- data/lib/zendesk_api/error.rb +49 -0
- data/lib/zendesk_api/helpers.rb +24 -0
- data/lib/zendesk_api/lru_cache.rb +39 -0
- data/lib/zendesk_api/middleware/request/encode_json.rb +26 -0
- data/lib/zendesk_api/middleware/request/etag_cache.rb +52 -0
- data/lib/zendesk_api/middleware/request/raise_rate_limited.rb +31 -0
- data/lib/zendesk_api/middleware/request/retry.rb +59 -0
- data/lib/zendesk_api/middleware/request/upload.rb +86 -0
- data/lib/zendesk_api/middleware/request/url_based_access_token.rb +26 -0
- data/lib/zendesk_api/middleware/response/callback.rb +21 -0
- data/lib/zendesk_api/middleware/response/deflate.rb +17 -0
- data/lib/zendesk_api/middleware/response/gzip.rb +19 -0
- data/lib/zendesk_api/middleware/response/logger.rb +44 -0
- data/lib/zendesk_api/middleware/response/parse_iso_dates.rb +30 -0
- data/lib/zendesk_api/middleware/response/parse_json.rb +23 -0
- data/lib/zendesk_api/middleware/response/raise_error.rb +26 -0
- data/lib/zendesk_api/middleware/response/sanitize_response.rb +11 -0
- data/lib/zendesk_api/resource.rb +208 -0
- data/lib/zendesk_api/resources.rb +971 -0
- data/lib/zendesk_api/sideloading.rb +58 -0
- data/lib/zendesk_api/silent_mash.rb +8 -0
- data/lib/zendesk_api/track_changes.rb +85 -0
- data/lib/zendesk_api/trackie.rb +13 -0
- data/lib/zendesk_api/verbs.rb +65 -0
- data/lib/zendesk_api/version.rb +3 -0
- data/lib/zendesk_api.rb +4 -0
- data/util/resource_handler.rb +74 -0
- data/util/verb_handler.rb +16 -0
- metadata +166 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
# @private
|
3
|
+
module Sideloading
|
4
|
+
def self.included(klass)
|
5
|
+
klass.send(:attr_reader, :included)
|
6
|
+
end
|
7
|
+
|
8
|
+
def set_includes(resource_or_resources, includes, body)
|
9
|
+
@included = {}
|
10
|
+
|
11
|
+
includes.each do |side_load|
|
12
|
+
unless body.key?(side_load.to_s)
|
13
|
+
@client.config.logger.warn "Missing #{side_load} key in response -- cannot side load"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
resources = to_array(resource_or_resources)
|
18
|
+
resource_class = resources.first.class
|
19
|
+
|
20
|
+
return if resources.empty?
|
21
|
+
|
22
|
+
body.keys.each do |name|
|
23
|
+
@included[name] = body[name]
|
24
|
+
_side_load(name, resource_class, resources)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Traverses the resource looking for associations
|
31
|
+
# then descends into those associations and checks for applicable
|
32
|
+
# resources to side load
|
33
|
+
def _side_load(name, klass, resources)
|
34
|
+
associations = klass.associated_with(name)
|
35
|
+
|
36
|
+
associations.each do |association|
|
37
|
+
association.side_load(resources, @included[name])
|
38
|
+
end
|
39
|
+
|
40
|
+
resources.each do |resource|
|
41
|
+
loaded_associations = resource.loaded_associations
|
42
|
+
loaded_associations.each do |association|
|
43
|
+
loaded = resource.send(association[:name])
|
44
|
+
next unless loaded
|
45
|
+
_side_load(name, association[:class], to_array(loaded))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_array(item)
|
51
|
+
if item.is_a?(Collection)
|
52
|
+
item
|
53
|
+
else
|
54
|
+
[item].flatten.compact
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
# Shamelessly stolen and modified from https://github.com/archan937/dirty_hashy
|
3
|
+
# @private
|
4
|
+
module TrackChanges
|
5
|
+
def self.included(base)
|
6
|
+
base.method_defined?(:regular_writer).tap do |defined|
|
7
|
+
base.send :include, InstanceMethods
|
8
|
+
unless defined
|
9
|
+
base.send :alias_method, :_store, :store
|
10
|
+
base.send :alias_method, :store, :regular_writer
|
11
|
+
base.send :alias_method, :[]=, :store
|
12
|
+
base.send :define_method, :update do |other|
|
13
|
+
other.each { |key, value| store key, value }
|
14
|
+
end
|
15
|
+
base.send :alias_method, :merge!, :update
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @private
|
21
|
+
module InstanceMethods
|
22
|
+
def clear_changes
|
23
|
+
each do |k, v|
|
24
|
+
if v.respond_to?(:clear_changes)
|
25
|
+
v.clear_changes
|
26
|
+
elsif v.is_a?(Array)
|
27
|
+
v.each do |val|
|
28
|
+
if val.respond_to?(:clear_changes)
|
29
|
+
val.clear_changes
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
changes.clear
|
36
|
+
end
|
37
|
+
|
38
|
+
def replace(other)
|
39
|
+
clear
|
40
|
+
merge! other
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear
|
44
|
+
keys.each { |key| delete key }
|
45
|
+
end
|
46
|
+
|
47
|
+
def regular_writer(key, value)
|
48
|
+
if has_key?(key) && self[key] == value
|
49
|
+
value
|
50
|
+
else
|
51
|
+
changes[key] = value
|
52
|
+
defined?(_store) ? _store(key, value) : super(key, value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def delete(key)
|
57
|
+
super.tap do |value|
|
58
|
+
changes[key] = nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def changes
|
63
|
+
(@changes ||= self.class.superclass.new).tap do |changes|
|
64
|
+
each do |k, v|
|
65
|
+
if v.respond_to?(:changed?) && v.changed?
|
66
|
+
changes[k] = v.changes
|
67
|
+
elsif v.is_a?(Array) && v.any? { |val| val.respond_to?(:changed?) && val.changed? }
|
68
|
+
changes[k] = v
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def changed?(key = nil)
|
75
|
+
if key.nil?
|
76
|
+
!changes.empty? || any? { |_, v| v.respond_to?(:changed?) && v.changed? }
|
77
|
+
else
|
78
|
+
changes.key?(key)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
alias :dirty? :changed?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
# Creates put, post, delete class methods for custom resource methods.
|
3
|
+
module Verbs
|
4
|
+
class << self
|
5
|
+
private
|
6
|
+
|
7
|
+
# @macro [attach] container.create_verb
|
8
|
+
# @method $1(method)
|
9
|
+
# Executes a $1 using the passed in method as a path.
|
10
|
+
# Reloads the resource's attributes if any are in the response body.
|
11
|
+
#
|
12
|
+
# Created method takes an optional options hash. Valid options to be passed in to the created method: reload (for caching, default: false)
|
13
|
+
def create_verb(method_verb)
|
14
|
+
define_method method_verb do |method|
|
15
|
+
define_method "#{method}!" do |*method_args|
|
16
|
+
opts = method_args.last.is_a?(Hash) ? method_args.pop : {}
|
17
|
+
|
18
|
+
if method_verb == :any
|
19
|
+
verb = opts.delete(:verb)
|
20
|
+
raise(ArgumentError, ":verb required for method defined as :any") unless verb
|
21
|
+
else
|
22
|
+
verb = method_verb
|
23
|
+
end
|
24
|
+
|
25
|
+
@response = @client.connection.send(verb, "#{path}/#{method}") do |req|
|
26
|
+
req.body = opts
|
27
|
+
end
|
28
|
+
|
29
|
+
return false unless @response.success?
|
30
|
+
return false unless @response.body
|
31
|
+
|
32
|
+
resource = nil
|
33
|
+
|
34
|
+
if @response.body.is_a?(Hash)
|
35
|
+
resource = @response.body[self.class.singular_resource_name]
|
36
|
+
resource ||= @response.body.fetch(self.class.resource_name, []).detect { |res| res["id"] == id }
|
37
|
+
end
|
38
|
+
|
39
|
+
@attributes.replace @attributes.deep_merge(resource || {})
|
40
|
+
@attributes.clear_changes
|
41
|
+
clear_associations
|
42
|
+
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
define_method method do |*method_args|
|
47
|
+
begin
|
48
|
+
send("#{method}!", *method_args)
|
49
|
+
rescue ZendeskAPI::Error::RecordInvalid => e
|
50
|
+
@errors = e.errors
|
51
|
+
false
|
52
|
+
rescue ZendeskAPI::Error::ClientError
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
create_verb :put
|
61
|
+
create_verb :post
|
62
|
+
create_verb :delete
|
63
|
+
create_verb :any
|
64
|
+
end
|
65
|
+
end
|
data/lib/zendesk_api.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'zendesk_api'
|
2
|
+
|
3
|
+
class ResourceHandler < YARD::Handlers::Ruby::Base
|
4
|
+
handles method_call(:has), method_call(:has_many)
|
5
|
+
|
6
|
+
def process
|
7
|
+
many = statement.jump(:ident).source == "has_many"
|
8
|
+
|
9
|
+
klass = get_klass(statement)
|
10
|
+
|
11
|
+
if klass
|
12
|
+
begin
|
13
|
+
klass = klass.split("::").inject(ZendeskAPI) do |p, k|
|
14
|
+
p.const_get(k)
|
15
|
+
end
|
16
|
+
rescue NameError
|
17
|
+
parent = walk_namespace(namespace)
|
18
|
+
klass = parent.const_get(klass)
|
19
|
+
end
|
20
|
+
|
21
|
+
name = statement.parameters.first.jump(:ident).source
|
22
|
+
else
|
23
|
+
klass = statement.parameters.first.source
|
24
|
+
|
25
|
+
begin
|
26
|
+
klass = ZendeskAPI.const_get(klass)
|
27
|
+
rescue NameError
|
28
|
+
parent = walk_namespace(namespace)
|
29
|
+
klass = parent.const_get(klass)
|
30
|
+
end
|
31
|
+
|
32
|
+
name = many ? klass.resource_name : klass.singular_resource_name
|
33
|
+
end
|
34
|
+
|
35
|
+
reader = YARD::CodeObjects::MethodObject.new(namespace, name)
|
36
|
+
register(reader)
|
37
|
+
reader.dynamic = true
|
38
|
+
reader.docstring.add_tag(YARD::Tags::Tag.new(:return, "The associated object", klass.name))
|
39
|
+
|
40
|
+
if many
|
41
|
+
reader.signature = "def #{name}=(options = {})"
|
42
|
+
reader.parameters = [['options', {}]]
|
43
|
+
reader.docstring.add_tag(YARD::Tags::Tag.new(:param, "Options to pass to the collection object", "Hash", "options"))
|
44
|
+
end
|
45
|
+
|
46
|
+
writer = YARD::CodeObjects::MethodObject.new(namespace, "#{name}=")
|
47
|
+
register(writer)
|
48
|
+
writer.signature = "def #{name}=(value)"
|
49
|
+
writer.parameters = [['value', nil]]
|
50
|
+
writer.dynamic = true
|
51
|
+
writer.docstring.add_tag(YARD::Tags::Tag.new(:return, "The associated object", klass.name))
|
52
|
+
writer.docstring.add_tag(YARD::Tags::Tag.new(:param, "The associated object or its attributes", "Hash or #{klass.name}", "value"))
|
53
|
+
end
|
54
|
+
|
55
|
+
def walk_namespace(namespace)
|
56
|
+
namespace.to_s.split('::').inject(ZendeskAPI) do |klass, namespace|
|
57
|
+
klass.const_get(namespace)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_klass(statement)
|
62
|
+
statement.traverse do |node|
|
63
|
+
if node.type == :assoc && node.jump(:kw).source == "class"
|
64
|
+
node.traverse do |value|
|
65
|
+
if value.type == :const_path_ref || value.type == :var_ref
|
66
|
+
return value.source
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class VerbHandler < YARD::Handlers::Ruby::Base
|
2
|
+
handles method_call(:put), method_call(:post), method_call(:get)
|
3
|
+
|
4
|
+
def process
|
5
|
+
name = statement.parameters.first.jump(:ident).source
|
6
|
+
|
7
|
+
verb = YARD::CodeObjects::MethodObject.new(namespace, name)
|
8
|
+
register(verb)
|
9
|
+
verb.dynamic = true
|
10
|
+
verb.docstring.add_tag(YARD::Tags::Tag.new(:return, "Success of this call", "Boolean"))
|
11
|
+
|
12
|
+
verb.signature = "def #{name}=(options = {})"
|
13
|
+
verb.parameters = [['options', {}]]
|
14
|
+
verb.docstring.add_tag(YARD::Tags::Tag.new(:param, "Options to pass to the request", "Hash", "options"))
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: discourse_zendesk_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Discourse
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.9.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: hashie
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 3.5.2
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 5.0.0
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 3.5.2
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 5.0.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: inflection
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
type: :runtime
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: multipart-post
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '2.0'
|
74
|
+
type: :runtime
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '2.0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: mini_mime
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
description: Ruby wrapper for the REST API at https://www.zendesk.com. Documentation
|
96
|
+
at https://developer.zendesk.com.
|
97
|
+
email:
|
98
|
+
- isaac.janzen@discourse.org
|
99
|
+
- sam.saffron@discourse.org
|
100
|
+
- robin.ward@discourse.org
|
101
|
+
- team@discourse.org
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- LICENSE
|
107
|
+
- lib/zendesk_api.rb
|
108
|
+
- lib/zendesk_api/actions.rb
|
109
|
+
- lib/zendesk_api/association.rb
|
110
|
+
- lib/zendesk_api/associations.rb
|
111
|
+
- lib/zendesk_api/client.rb
|
112
|
+
- lib/zendesk_api/collection.rb
|
113
|
+
- lib/zendesk_api/configuration.rb
|
114
|
+
- lib/zendesk_api/core_ext/inflection.rb
|
115
|
+
- lib/zendesk_api/delegator.rb
|
116
|
+
- lib/zendesk_api/error.rb
|
117
|
+
- lib/zendesk_api/helpers.rb
|
118
|
+
- lib/zendesk_api/lru_cache.rb
|
119
|
+
- lib/zendesk_api/middleware/request/encode_json.rb
|
120
|
+
- lib/zendesk_api/middleware/request/etag_cache.rb
|
121
|
+
- lib/zendesk_api/middleware/request/raise_rate_limited.rb
|
122
|
+
- lib/zendesk_api/middleware/request/retry.rb
|
123
|
+
- lib/zendesk_api/middleware/request/upload.rb
|
124
|
+
- lib/zendesk_api/middleware/request/url_based_access_token.rb
|
125
|
+
- lib/zendesk_api/middleware/response/callback.rb
|
126
|
+
- lib/zendesk_api/middleware/response/deflate.rb
|
127
|
+
- lib/zendesk_api/middleware/response/gzip.rb
|
128
|
+
- lib/zendesk_api/middleware/response/logger.rb
|
129
|
+
- lib/zendesk_api/middleware/response/parse_iso_dates.rb
|
130
|
+
- lib/zendesk_api/middleware/response/parse_json.rb
|
131
|
+
- lib/zendesk_api/middleware/response/raise_error.rb
|
132
|
+
- lib/zendesk_api/middleware/response/sanitize_response.rb
|
133
|
+
- lib/zendesk_api/resource.rb
|
134
|
+
- lib/zendesk_api/resources.rb
|
135
|
+
- lib/zendesk_api/sideloading.rb
|
136
|
+
- lib/zendesk_api/silent_mash.rb
|
137
|
+
- lib/zendesk_api/track_changes.rb
|
138
|
+
- lib/zendesk_api/trackie.rb
|
139
|
+
- lib/zendesk_api/verbs.rb
|
140
|
+
- lib/zendesk_api/version.rb
|
141
|
+
- util/resource_handler.rb
|
142
|
+
- util/verb_handler.rb
|
143
|
+
homepage: https://developer.zendesk.com
|
144
|
+
licenses:
|
145
|
+
- Apache-2.0
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '2.3'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 1.3.6
|
161
|
+
requirements: []
|
162
|
+
rubygems_version: 3.2.3
|
163
|
+
signing_key:
|
164
|
+
specification_version: 4
|
165
|
+
summary: Discourse Zendesk REST API Client
|
166
|
+
test_files: []
|