inigorb 0.27.7 → 0.28.1
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 +4 -4
- data/lib/{ffimod.rb → inigorb/ffimod.rb} +6 -2
- data/lib/{inigo-darwin-amd64.dylib → inigorb/inigo-darwin-amd64.dylib} +0 -0
- data/lib/{inigo-darwin-arm64.dylib → inigorb/inigo-darwin-arm64.dylib} +0 -0
- data/lib/{inigo-linux-amd64.so → inigorb/inigo-linux-amd64.so} +0 -0
- data/lib/{inigo-linux-arm64.so → inigorb/inigo-linux-arm64.so} +0 -0
- data/lib/{inigo-windows-amd64.dll → inigorb/inigo-windows-amd64.dll} +0 -0
- data/lib/{inigo-windows-arm64.dll → inigorb/inigo-windows-arm64.dll} +0 -0
- data/lib/{query.rb → inigorb/query.rb} +32 -13
- data/lib/inigorb/tracer.rb +261 -0
- data/lib/inigorb.rb +17 -13
- metadata +31 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8dd4aa6b5a222647cdeaca8bc0a812fff7ca4afa6402c3da8a182d5b87a1db1
|
|
4
|
+
data.tar.gz: 79e2b7554361eb3e170d63b7c07afa2d58870322b3790452b3ede1120b46732f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cec390d985f84492c6a72f2232382f6f8a93043b9c067f3d30d71f7896bcaf12c6ec47b91afab59c8e1dbd4ac78d84d141a5ba1ce982e865a0012f9b0d00cfd3
|
|
7
|
+
data.tar.gz: a2a42ca4d67b9e6ad518cf2d748dd09a8123815c3c327aaf382cc8e3bbfee5f6cb9454c8e3a66c80392f5c63dad0d4276cadeeda552f695071e8a23e845fc9ff
|
|
@@ -56,11 +56,14 @@ module Inigo
|
|
|
56
56
|
|
|
57
57
|
class Config < FFI::Struct
|
|
58
58
|
layout :debug, :bool,
|
|
59
|
-
:
|
|
59
|
+
:name, :pointer,
|
|
60
60
|
:service, :pointer,
|
|
61
61
|
:token, :pointer,
|
|
62
62
|
:schema, :pointer,
|
|
63
|
-
:
|
|
63
|
+
:runtime, :pointer,
|
|
64
|
+
:egress_url, :pointer,
|
|
65
|
+
:gateway, :u_int64_t,
|
|
66
|
+
:disable_response_data, :bool
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
attach_function :create, [:u_int64_t], :u_int64_t
|
|
@@ -81,6 +84,7 @@ module Inigo
|
|
|
81
84
|
attach_function :disposeHandle, [:u_int64_t], :void
|
|
82
85
|
attach_function :disposeMemory, [:pointer], :void
|
|
83
86
|
attach_function :check_lasterror, [], :string
|
|
87
|
+
attach_function :copy_querydata, [:u_int64_t], :u_int64_t
|
|
84
88
|
rescue LoadError => e
|
|
85
89
|
raise ::RuntimeError, "Unable to open Inigo shared library.\n\nPlease get in touch with us for support:\nemail: support@inigo.io\nslack: https://slack.inigo.io\n\nPlease share the below info with us:\nerror: #{e.to_s}\nuname: #{RbConfig::CONFIG['host_os']}\narch: #{RbConfig::CONFIG['host_cpu']}"
|
|
86
90
|
end
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
require 'json'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
require 'inigorb/ffimod'
|
|
3
4
|
|
|
4
5
|
module Inigo
|
|
6
|
+
# made to simplify user experience. just prepend Inigo::Data to your channel and it will work.
|
|
7
|
+
module Data
|
|
8
|
+
attr_accessor :querydata
|
|
9
|
+
|
|
10
|
+
def unsubscribed
|
|
11
|
+
if @querydata
|
|
12
|
+
Inigo.disposeHandle(@querydata.handle)
|
|
13
|
+
end
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
5
18
|
class Query
|
|
19
|
+
attr_reader :handle
|
|
20
|
+
|
|
6
21
|
def initialize(instance, request)
|
|
7
22
|
@handle = 0
|
|
8
23
|
@instance = instance
|
|
@@ -50,31 +65,35 @@ module Inigo
|
|
|
50
65
|
[resp_dict, req_dict]
|
|
51
66
|
end
|
|
52
67
|
|
|
53
|
-
def process_response(resp_body)
|
|
68
|
+
def process_response(resp_body, is_initial_subscription: false, copy: false)
|
|
54
69
|
return nil if @handle.zero?
|
|
55
70
|
|
|
56
71
|
output_ptr = FFI::MemoryPointer.new(:pointer)
|
|
57
72
|
output_len = FFI::MemoryPointer.new(:int)
|
|
58
73
|
|
|
74
|
+
handle = @handle
|
|
75
|
+
if copy
|
|
76
|
+
# if it is subscription and not initial request - reuse existing querydata
|
|
77
|
+
handle = Inigo.copy_querydata(@handle)
|
|
78
|
+
end
|
|
79
|
+
|
|
59
80
|
Inigo.process_response(
|
|
60
81
|
@instance,
|
|
61
|
-
|
|
82
|
+
handle,
|
|
62
83
|
FFI::MemoryPointer.from_string(resp_body), resp_body.length,
|
|
63
84
|
output_ptr, output_len
|
|
64
85
|
)
|
|
65
86
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
output_len_value = output_len.read_int
|
|
69
|
-
if output_len_value > 0
|
|
70
|
-
output_data = output_ptr.read_pointer.read_string(output_len_value)
|
|
71
|
-
output_dict = JSON.parse(output_data)
|
|
72
|
-
end
|
|
87
|
+
output_data = output_ptr.read_pointer.read_string(output_len.read_int)
|
|
73
88
|
|
|
74
89
|
Inigo.disposeMemory(output_ptr.read_pointer)
|
|
75
|
-
Inigo.disposeHandle(@handle)
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
# if it is initial subscription request - do not dispose handle
|
|
92
|
+
if !is_initial_subscription
|
|
93
|
+
Inigo.disposeHandle(handle)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
output_data
|
|
78
97
|
end
|
|
79
98
|
end
|
|
80
|
-
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'ffi'
|
|
3
|
+
require 'graphql'
|
|
4
|
+
|
|
5
|
+
require 'inigorb/ffimod'
|
|
6
|
+
require 'inigorb/query'
|
|
7
|
+
|
|
8
|
+
module Inigo
|
|
9
|
+
class Tracer < GraphQL::Tracing::PlatformTracing
|
|
10
|
+
@@instance = nil
|
|
11
|
+
|
|
12
|
+
def self.instance
|
|
13
|
+
@@instance
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.instance=(value)
|
|
17
|
+
@@instance = value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(options = {})
|
|
21
|
+
super(options)
|
|
22
|
+
# add options like logger logic
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.use(schema, **kwargs)
|
|
26
|
+
@@schema = schema
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
self.platform_keys = {
|
|
31
|
+
'lex' => 'lex',
|
|
32
|
+
'parse' => 'parse',
|
|
33
|
+
'validate' => 'validate',
|
|
34
|
+
'analyze_query' => 'analyze_query',
|
|
35
|
+
'analyze_multiplex' => 'analyze_multiplex',
|
|
36
|
+
'execute_multiplex' => 'execute_multiplex',
|
|
37
|
+
'execute_query' => 'execute_query',
|
|
38
|
+
'execute_query_lazy' => 'execute_query_lazy'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
def platform_trace(platform_key, key, data)
|
|
42
|
+
# Ignore execution if Inigo is not initialized
|
|
43
|
+
if self.class.instance == 0
|
|
44
|
+
return yield
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if platform_key != "execute_multiplex"
|
|
48
|
+
return yield
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if !data[:multiplex] || !data[:multiplex].queries || data[:multiplex].queries.length == 0
|
|
52
|
+
return yield
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
queries = []
|
|
56
|
+
subscription_queries = {}
|
|
57
|
+
initial_subscriptions = {}
|
|
58
|
+
modified_responses = {}
|
|
59
|
+
cached_queries = {}
|
|
60
|
+
|
|
61
|
+
data[:multiplex].queries.each_with_index do |query, index|
|
|
62
|
+
is_subscription = query.context[:channel] != nil
|
|
63
|
+
is_init_subscription = is_subscription && !query.context[:subscription_id]
|
|
64
|
+
|
|
65
|
+
if is_subscription && !is_init_subscription
|
|
66
|
+
# retrieve querydata stored after initial subscription request
|
|
67
|
+
subscription_queries[index] = query.context[:channel].querydata
|
|
68
|
+
queries.append(query.context[:channel].querydata)
|
|
69
|
+
# no need to process request again, it will be copied
|
|
70
|
+
next
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
gReq = {
|
|
74
|
+
'query' => query.query_string,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
gReq['operationName'] = query.operation_name if query.operation_name && query.operation_name != ''
|
|
78
|
+
gReq['variables'] = query.variables.to_h if query.variables
|
|
79
|
+
|
|
80
|
+
q = Query.new(self.class.instance, JSON.dump(gReq))
|
|
81
|
+
|
|
82
|
+
incoming_request = query.context['request']
|
|
83
|
+
if is_subscription
|
|
84
|
+
incoming_request = ActionDispatch::Request.new(query.context[:channel].connection.env)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
resp, req = q.process_request(headers(incoming_request))
|
|
88
|
+
|
|
89
|
+
# Introspection or blocked query
|
|
90
|
+
if resp.any?
|
|
91
|
+
modified_responses[index] = resp
|
|
92
|
+
cached_queries[index] = query
|
|
93
|
+
|
|
94
|
+
# trick not to execute actual query. we can't remove query from multiplex at all but we can fool it by modifying the query executed on the schema.
|
|
95
|
+
modified_query = GraphQL::Query.new(query.schema, 'query IntrospectionQuery { __schema { queryType { name } } }', context: query.context, operation_name: 'IntrospectionQuery')
|
|
96
|
+
modified_query.multiplex = query.multiplex
|
|
97
|
+
# TODO - verify works in all the cases. During the testing it works, simulate multiple queries at the same time to verify.
|
|
98
|
+
data[:multiplex].queries[index] = modified_query
|
|
99
|
+
|
|
100
|
+
queries.append(q)
|
|
101
|
+
next
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Modify query if required
|
|
105
|
+
if req.any?
|
|
106
|
+
modified_query = GraphQL::Query.new(query.schema, req['query'], context: query.context, operation_name: req['operationName'], variables: req['variables'])
|
|
107
|
+
modified_query.multiplex = query.multiplex
|
|
108
|
+
# TODO - verify works in all the cases. During the testing it works, simulate multiple queries at the same time to verify.
|
|
109
|
+
data[:multiplex].queries[index] = modified_query
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
if is_subscription
|
|
113
|
+
query.context[:channel].querydata = q
|
|
114
|
+
initial_subscriptions[index] = true
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
queries.append(q)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
responses = yield
|
|
121
|
+
|
|
122
|
+
responses.each_with_index do |response, index|
|
|
123
|
+
if modified_responses[index]
|
|
124
|
+
# process_response is not called in this case
|
|
125
|
+
responses[index] = GraphQL::Query::Result.new(query: cached_queries[index], values: modified_responses[index])
|
|
126
|
+
next
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# take a copy of the initial subscription request if it is subscription
|
|
130
|
+
needs_copy = subscription_queries[index] != nil
|
|
131
|
+
is_initial_subscription = initial_subscriptions[index] != nil
|
|
132
|
+
resp = {
|
|
133
|
+
'errors' => response['errors'],
|
|
134
|
+
'response_size' => 0,
|
|
135
|
+
'response_body_counts' => count_response_fields(response.to_h)
|
|
136
|
+
}
|
|
137
|
+
processed_response = queries[index].process_response(JSON.dump(resp), is_initial_subscription: is_initial_subscription, copy: needs_copy)
|
|
138
|
+
responses[index] = GraphQL::Query::Result.new(query: data[:multiplex].queries[index], values: mod_response(response.to_h, JSON.parse(processed_response)))
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
responses
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# compat
|
|
145
|
+
def platform_authorized_key(type)
|
|
146
|
+
"#{type.graphql_name}.authorized.graphql"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# compat
|
|
150
|
+
def platform_resolve_type_key(type)
|
|
151
|
+
"#{type.graphql_name}.resolve_type.graphql"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# compat
|
|
155
|
+
def platform_field_key(type, field)
|
|
156
|
+
"graphql.#{type.name}.#{field.name}"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def count_response_fields(resp)
|
|
160
|
+
counts = {}
|
|
161
|
+
|
|
162
|
+
if resp['data']
|
|
163
|
+
count_response_fields_recursive(counts, 'data', resp['data'])
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
counts['data'] ||= 1
|
|
167
|
+
counts['errors'] = resp['errors'] ? resp['errors'].length : 0
|
|
168
|
+
counts
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def count_response_fields_recursive(hm, prefix, val)
|
|
172
|
+
return unless val.is_a?(Hash) || val.is_a?(Array)
|
|
173
|
+
|
|
174
|
+
incr = lambda do |key, value|
|
|
175
|
+
unless count_response_fields_recursive(hm, key, value)
|
|
176
|
+
hm[key] = (hm[key] || 0) + 1
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
if val.is_a?(Array)
|
|
181
|
+
val.each do |item|
|
|
182
|
+
incr.call(prefix, item)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
return true
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
val.each do |k, v|
|
|
189
|
+
incr.call("#{prefix}.#{k}", v)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
return false
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
private
|
|
196
|
+
|
|
197
|
+
def self.initialize_tracer(schema)
|
|
198
|
+
@@schema = schema
|
|
199
|
+
|
|
200
|
+
# get all the inigo settings from env
|
|
201
|
+
settings = ENV.select { |k, v| k.start_with?('INIGO') }
|
|
202
|
+
|
|
203
|
+
if settings.fetch("INIGO_ENABLE", "").to_s.downcase == "false"
|
|
204
|
+
@@initialized = true #not to get to this method ever again
|
|
205
|
+
puts 'Inigo is disabled. Skipping middleware.'
|
|
206
|
+
return
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
config = Inigo::Config.new
|
|
210
|
+
|
|
211
|
+
config[:disable_response_data] = false
|
|
212
|
+
config[:debug] = settings.fetch("INIGO_DEBUG", "false").to_s.downcase == "true"
|
|
213
|
+
config[:token] = FFI::MemoryPointer.from_string(settings.fetch('INIGO_SERVICE_TOKEN', '').to_s.encode('UTF-8'))
|
|
214
|
+
config[:schema] = FFI::MemoryPointer.from_string(schema.to_s.encode('UTF-8'))
|
|
215
|
+
config[:name] = FFI::MemoryPointer.from_string("inigo-rb".to_s.encode('UTF-8'))
|
|
216
|
+
config[:runtime] = FFI::MemoryPointer.from_string("ruby".concat(RUBY_VERSION[/\d+\.\d+/]).to_s.encode('UTF-8'))
|
|
217
|
+
|
|
218
|
+
# Create Inigo instance
|
|
219
|
+
@@instance = Inigo.create(config.pointer.address)
|
|
220
|
+
|
|
221
|
+
error = Inigo.check_lasterror
|
|
222
|
+
if error.length != 0
|
|
223
|
+
puts "INIGO: #{error}"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
if error.length == 0 && @@instance == 0
|
|
227
|
+
puts 'INIGO: error, instance cannot be created'
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def headers(request)
|
|
232
|
+
headers = {}
|
|
233
|
+
|
|
234
|
+
request.env.each do |key, value|
|
|
235
|
+
if key.start_with?('HTTP_')
|
|
236
|
+
header_name = key[5..].split('_').map(&:capitalize).join('-')
|
|
237
|
+
headers[header_name] = value.split(',').map(&:strip)
|
|
238
|
+
elsif key == 'CONTENT_TYPE' || key == 'REMOTE_ADDR'
|
|
239
|
+
headers[key] = value.split(',').map(&:strip)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
JSON.dump(headers)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def mod_response(response, extended)
|
|
247
|
+
if extended['extensions']
|
|
248
|
+
response['extensions'] ||= {}
|
|
249
|
+
response['extensions'].merge!(extended['extensions'])
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
if extended['errors']
|
|
253
|
+
response['errors'] ||= []
|
|
254
|
+
response['errors'].concat(extended['errors'])
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
response
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
end
|
|
261
|
+
end
|
data/lib/inigorb.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
require 'json'
|
|
2
2
|
require 'ffi'
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
|
|
4
|
+
require 'inigorb/ffimod'
|
|
5
|
+
require 'inigorb/query'
|
|
6
|
+
require 'inigorb/tracer'
|
|
5
7
|
|
|
6
8
|
module Inigo
|
|
7
9
|
class Middleware
|
|
@@ -86,7 +88,7 @@ module Inigo
|
|
|
86
88
|
# Read request from body
|
|
87
89
|
request.body.each { |chunk| gReq += chunk }
|
|
88
90
|
|
|
89
|
-
if self.class.operation_store.present? && has_operation_id?(gReq)
|
|
91
|
+
if self.class.operation_store.present? && has_operation_id?(gReq) && !has_query?(gReq)
|
|
90
92
|
parsed = JSON.parse(gReq)
|
|
91
93
|
operationId = get_operation_id(parsed)
|
|
92
94
|
|
|
@@ -124,7 +126,7 @@ module Inigo
|
|
|
124
126
|
request.body.rewind
|
|
125
127
|
elsif request.get?
|
|
126
128
|
operation_id = get_operation_id(request.params)
|
|
127
|
-
if operation_id && self.class.operation_store
|
|
129
|
+
if operation_id && self.class.operation_store && !request.params['query']
|
|
128
130
|
parts = operation_id.split('/')
|
|
129
131
|
# Query can't be resolved
|
|
130
132
|
if parts.length != 2
|
|
@@ -181,14 +183,10 @@ module Inigo
|
|
|
181
183
|
|
|
182
184
|
# Forward to request handler
|
|
183
185
|
status, headers, response = @app.call(env)
|
|
184
|
-
|
|
186
|
+
headers.delete("Content-Length")
|
|
185
187
|
# Inigo: process response
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return respond(status, headers, processed_response)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
response
|
|
188
|
+
response = q.process_response(response.body.to_s)
|
|
189
|
+
[status, headers, [response]]
|
|
192
190
|
end
|
|
193
191
|
|
|
194
192
|
private
|
|
@@ -214,6 +212,9 @@ module Inigo
|
|
|
214
212
|
end
|
|
215
213
|
|
|
216
214
|
config = Inigo::Config.new
|
|
215
|
+
config[:disable_response_data] = false
|
|
216
|
+
config[:name] = FFI::MemoryPointer.from_string("inigo-rb".to_s.encode('UTF-8'))
|
|
217
|
+
config[:runtime] = FFI::MemoryPointer.from_string("ruby".concat(RUBY_VERSION[/\d+\.\d+/]).to_s.encode('UTF-8'))
|
|
217
218
|
|
|
218
219
|
if settings.fetch("INIGO_DEBUG", "false").to_s.downcase == "true"
|
|
219
220
|
config[:debug] = true
|
|
@@ -282,6 +283,10 @@ module Inigo
|
|
|
282
283
|
str_data.include?('operationId')
|
|
283
284
|
end
|
|
284
285
|
|
|
286
|
+
def has_query?(str_data)
|
|
287
|
+
return str_data.include?('"query":') && str_data.match(/"query"\s*:\s*"\S+"/)
|
|
288
|
+
end
|
|
289
|
+
|
|
285
290
|
# extracts operation id from parsed body hash
|
|
286
291
|
def get_operation_id(json_data)
|
|
287
292
|
# Relay / Apollo 1.x
|
|
@@ -294,6 +299,5 @@ module Inigo
|
|
|
294
299
|
nil
|
|
295
300
|
end
|
|
296
301
|
end
|
|
297
|
-
|
|
298
|
-
end
|
|
302
|
+
end
|
|
299
303
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inigorb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.28.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Inigo
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jwt
|
|
@@ -50,6 +50,26 @@ dependencies:
|
|
|
50
50
|
- - ">="
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
52
|
version: 1.15.5
|
|
53
|
+
- !ruby/object:Gem::Dependency
|
|
54
|
+
name: graphql
|
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "~>"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: 2.0.24
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: 2.0.24
|
|
63
|
+
type: :runtime
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - "~>"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 2.0.24
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: 2.0.24
|
|
53
73
|
description:
|
|
54
74
|
email: eitan@inigo.io
|
|
55
75
|
executables: []
|
|
@@ -57,15 +77,16 @@ extensions: []
|
|
|
57
77
|
extra_rdoc_files: []
|
|
58
78
|
files:
|
|
59
79
|
- README.md
|
|
60
|
-
- lib/ffimod.rb
|
|
61
|
-
- lib/inigo-darwin-amd64.dylib
|
|
62
|
-
- lib/inigo-darwin-arm64.dylib
|
|
63
|
-
- lib/inigo-linux-amd64.so
|
|
64
|
-
- lib/inigo-linux-arm64.so
|
|
65
|
-
- lib/inigo-windows-amd64.dll
|
|
66
|
-
- lib/inigo-windows-arm64.dll
|
|
67
80
|
- lib/inigorb.rb
|
|
68
|
-
- lib/
|
|
81
|
+
- lib/inigorb/ffimod.rb
|
|
82
|
+
- lib/inigorb/inigo-darwin-amd64.dylib
|
|
83
|
+
- lib/inigorb/inigo-darwin-arm64.dylib
|
|
84
|
+
- lib/inigorb/inigo-linux-amd64.so
|
|
85
|
+
- lib/inigorb/inigo-linux-arm64.so
|
|
86
|
+
- lib/inigorb/inigo-windows-amd64.dll
|
|
87
|
+
- lib/inigorb/inigo-windows-arm64.dll
|
|
88
|
+
- lib/inigorb/query.rb
|
|
89
|
+
- lib/inigorb/tracer.rb
|
|
69
90
|
homepage: https://inigo.io
|
|
70
91
|
licenses:
|
|
71
92
|
- MIT
|