forest_admin_rpc_agent 1.18.1 → 1.18.2
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/forest_admin_rpc_agent/agent.rb +37 -162
- data/lib/forest_admin_rpc_agent/version.rb +1 -1
- data/lib/forest_admin_rpc_agent.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85145674f5df7ae4706d7664df0afa3d9d6d175fdc4da0135076062f375c5520
|
|
4
|
+
data.tar.gz: 5bdcfb2db9533cb53a4502f1cd2665ef7cbcff47e28e693d6a5335d872b493b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a87cb0be55321842a0f6cb0ced398ac1a4c5a4942fc176d1fbbca17456aad5bc4de51498cbced0884fb57d80feda95f6c0485a6721683af9aeb34132fbdd613a
|
|
7
|
+
data.tar.gz: baa517eef52210a9389f8fc1842daf579326a64aa0982b7cc1cb976b355f51b9948eda5d068681d6c7685d890c4d30f4f85aeebc5a97cd38147f6c058e67448e
|
|
@@ -2,7 +2,7 @@ require 'digest'
|
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
|
|
4
4
|
module ForestAdminRpcAgent
|
|
5
|
-
class Agent < ForestAdminAgent::Builder::AgentFactory
|
|
5
|
+
class Agent < ForestAdminAgent::Builder::AgentFactory
|
|
6
6
|
include ForestAdminAgent::Http::Exceptions
|
|
7
7
|
|
|
8
8
|
attr_reader :rpc_collections, :cached_schema, :cached_schema_hash
|
|
@@ -17,35 +17,23 @@ module ForestAdminRpcAgent
|
|
|
17
17
|
def send_schema(force: false)
|
|
18
18
|
if should_skip_schema_update? && !force
|
|
19
19
|
log_schema_skip
|
|
20
|
-
load_and_cache_schema
|
|
21
20
|
return
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if ForestAdminRpcAgent::Facades::Container.cache(:is_production)
|
|
27
|
-
unless schema_path && File.exist?(schema_path)
|
|
28
|
-
raise InternalServerError.new(
|
|
29
|
-
'Schema file not found in production',
|
|
30
|
-
details: { schema_path: schema_path }
|
|
31
|
-
)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
load_and_cache_schema_from_file(schema_path)
|
|
23
|
+
datasource = @container.resolve(:datasource)
|
|
35
24
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
else
|
|
41
|
-
generate_and_cache_schema(schema_path)
|
|
25
|
+
# Build and cache RPC schema from live datasource
|
|
26
|
+
@cached_schema = build_rpc_schema_from_datasource(datasource)
|
|
27
|
+
compute_and_cache_hash
|
|
42
28
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
)
|
|
47
|
-
end
|
|
29
|
+
# Write schema file for reference (only in development mode)
|
|
30
|
+
# Uses the same serialization as the /rpc-schema route
|
|
31
|
+
write_schema_file_for_reference unless ForestAdminRpcAgent::Facades::Container.cache(:is_production)
|
|
48
32
|
|
|
33
|
+
ForestAdminRpcAgent::Facades::Container.logger.log(
|
|
34
|
+
'Info',
|
|
35
|
+
'RPC agent schema computed from datasource and cached.'
|
|
36
|
+
)
|
|
49
37
|
ForestAdminRpcAgent::Facades::Container.logger.log(
|
|
50
38
|
'Info',
|
|
51
39
|
'RPC agent does not send schema to Forest Admin servers.'
|
|
@@ -62,7 +50,7 @@ module ForestAdminRpcAgent
|
|
|
62
50
|
def rpc_schema
|
|
63
51
|
return @cached_schema if @cached_schema
|
|
64
52
|
|
|
65
|
-
|
|
53
|
+
build_and_cache_rpc_schema_from_datasource
|
|
66
54
|
@cached_schema
|
|
67
55
|
end
|
|
68
56
|
|
|
@@ -82,50 +70,21 @@ module ForestAdminRpcAgent
|
|
|
82
70
|
def log_schema_skip
|
|
83
71
|
logger = ForestAdminRpcAgent::Facades::Container.logger
|
|
84
72
|
logger.log('Warn', '[ForestAdmin] Schema update skipped (skip_schema_update flag is true)')
|
|
85
|
-
environment = ForestAdminRpcAgent::Facades::Container.cache(:is_production) ? 'production' : 'development'
|
|
86
|
-
logger.log('Info', "[ForestAdmin] RPC agent running in #{environment} mode")
|
|
87
73
|
end
|
|
88
74
|
|
|
89
|
-
def
|
|
75
|
+
def write_schema_file_for_reference
|
|
90
76
|
schema_path = ForestAdminRpcAgent::Facades::Container.cache(:schema_path)
|
|
91
|
-
|
|
92
|
-
if ForestAdminRpcAgent::Facades::Container.cache(:is_production) && schema_path && File.exist?(schema_path)
|
|
93
|
-
load_and_cache_schema_from_file(schema_path)
|
|
94
|
-
else
|
|
95
|
-
# In development with skip_schema_update, still build from datasource
|
|
96
|
-
build_and_cache_schema_from_datasource
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def load_and_cache_schema_from_file(_schema_path)
|
|
101
|
-
# File exists but RPC schema needs internal format - build from datasource
|
|
102
|
-
# The file is kept for reference/frontend but RPC always uses internal format
|
|
103
|
-
datasource = @container.resolve(:datasource)
|
|
104
|
-
@cached_schema = build_rpc_schema_from_datasource(datasource)
|
|
105
|
-
compute_and_cache_hash
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def generate_and_cache_schema(schema_path)
|
|
109
|
-
datasource = @container.resolve(:datasource)
|
|
110
|
-
|
|
111
|
-
# Generate frontend schema for file (used by Forest Admin)
|
|
112
|
-
generated = ForestAdminAgent::Utils::Schema::SchemaEmitter.generate(datasource)
|
|
113
|
-
meta = ForestAdminAgent::Utils::Schema::SchemaEmitter.meta
|
|
114
|
-
|
|
115
|
-
schema = {
|
|
116
|
-
meta: meta,
|
|
117
|
-
collections: generated
|
|
118
|
-
}
|
|
119
|
-
|
|
120
77
|
FileUtils.mkdir_p(File.dirname(schema_path))
|
|
121
|
-
|
|
78
|
+
# Use the same serialization as the /rpc-schema route (.to_json)
|
|
79
|
+
File.write(schema_path, JSON.pretty_generate(JSON.parse(@cached_schema.to_json)))
|
|
122
80
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
81
|
+
ForestAdminRpcAgent::Facades::Container.logger.log(
|
|
82
|
+
'Info',
|
|
83
|
+
"RPC agent schema file saved to #{schema_path}"
|
|
84
|
+
)
|
|
126
85
|
end
|
|
127
86
|
|
|
128
|
-
def
|
|
87
|
+
def build_and_cache_rpc_schema_from_datasource
|
|
129
88
|
datasource = @container.resolve(:datasource)
|
|
130
89
|
|
|
131
90
|
@cached_schema = build_rpc_schema_from_datasource(datasource)
|
|
@@ -135,114 +94,30 @@ module ForestAdminRpcAgent
|
|
|
135
94
|
def build_rpc_schema_from_datasource(datasource)
|
|
136
95
|
schema = customizer.schema
|
|
137
96
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
97
|
+
schema[:collections] = datasource.collections
|
|
98
|
+
.map { |_name, collection| serialize_collection_schema(collection) }
|
|
99
|
+
.sort_by { |c| c[:name] }
|
|
141
100
|
|
|
142
|
-
|
|
143
|
-
|
|
101
|
+
schema[:native_query_connections] = datasource.live_query_connections.keys
|
|
102
|
+
.map { |connection_name| { name: connection_name } }
|
|
144
103
|
|
|
145
104
|
schema
|
|
146
105
|
end
|
|
147
106
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
charts: collection.schema[:charts] || [],
|
|
155
|
-
actions: serialize_actions_for_rpc(collection.schema[:actions] || {}),
|
|
156
|
-
fields: serialize_fields_for_rpc(collection.schema[:fields] || {})
|
|
157
|
-
}
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def serialize_fields_for_rpc(fields)
|
|
161
|
-
fields.transform_values do |field_schema|
|
|
162
|
-
serialize_field_schema(field_schema)
|
|
163
|
-
end
|
|
107
|
+
# Serialize collection schema, converting field objects to plain hashes
|
|
108
|
+
def serialize_collection_schema(collection)
|
|
109
|
+
schema = collection.schema.dup
|
|
110
|
+
schema[:name] = collection.name
|
|
111
|
+
schema[:fields] = schema[:fields].transform_values { |field| object_to_hash(field) }
|
|
112
|
+
schema
|
|
164
113
|
end
|
|
165
114
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
{
|
|
170
|
-
type: 'Column',
|
|
171
|
-
column_type: field_schema.column_type,
|
|
172
|
-
filter_operators: field_schema.filter_operators,
|
|
173
|
-
is_primary_key: field_schema.is_primary_key,
|
|
174
|
-
is_read_only: field_schema.is_read_only,
|
|
175
|
-
is_sortable: field_schema.is_sortable,
|
|
176
|
-
default_value: field_schema.default_value,
|
|
177
|
-
enum_values: field_schema.enum_values,
|
|
178
|
-
validation: field_schema.validation
|
|
179
|
-
}
|
|
180
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema
|
|
181
|
-
{
|
|
182
|
-
type: 'ManyToOne',
|
|
183
|
-
foreign_collection: field_schema.foreign_collection,
|
|
184
|
-
foreign_key: field_schema.foreign_key,
|
|
185
|
-
foreign_key_target: field_schema.foreign_key_target
|
|
186
|
-
}
|
|
187
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::OneToOneSchema
|
|
188
|
-
{
|
|
189
|
-
type: 'OneToOne',
|
|
190
|
-
foreign_collection: field_schema.foreign_collection,
|
|
191
|
-
origin_key: field_schema.origin_key,
|
|
192
|
-
origin_key_target: field_schema.origin_key_target
|
|
193
|
-
}
|
|
194
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::OneToManySchema
|
|
195
|
-
{
|
|
196
|
-
type: 'OneToMany',
|
|
197
|
-
foreign_collection: field_schema.foreign_collection,
|
|
198
|
-
origin_key: field_schema.origin_key,
|
|
199
|
-
origin_key_target: field_schema.origin_key_target
|
|
200
|
-
}
|
|
201
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::ManyToManySchema
|
|
202
|
-
{
|
|
203
|
-
type: 'ManyToMany',
|
|
204
|
-
foreign_collection: field_schema.foreign_collection,
|
|
205
|
-
foreign_key: field_schema.foreign_key,
|
|
206
|
-
foreign_key_target: field_schema.foreign_key_target,
|
|
207
|
-
origin_key: field_schema.origin_key,
|
|
208
|
-
origin_key_target: field_schema.origin_key_target,
|
|
209
|
-
through_collection: field_schema.through_collection
|
|
210
|
-
}
|
|
211
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicManyToOneSchema
|
|
212
|
-
{
|
|
213
|
-
type: 'PolymorphicManyToOne',
|
|
214
|
-
foreign_collections: field_schema.foreign_collections,
|
|
215
|
-
foreign_key: field_schema.foreign_key,
|
|
216
|
-
foreign_key_type_field: field_schema.foreign_key_type_field,
|
|
217
|
-
foreign_key_targets: field_schema.foreign_key_targets
|
|
218
|
-
}
|
|
219
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicOneToOneSchema
|
|
220
|
-
{
|
|
221
|
-
type: 'PolymorphicOneToOne',
|
|
222
|
-
foreign_collection: field_schema.foreign_collection,
|
|
223
|
-
origin_key: field_schema.origin_key,
|
|
224
|
-
origin_key_target: field_schema.origin_key_target,
|
|
225
|
-
origin_type_field: field_schema.origin_type_field,
|
|
226
|
-
origin_type_value: field_schema.origin_type_value
|
|
227
|
-
}
|
|
228
|
-
when ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicOneToManySchema
|
|
229
|
-
{
|
|
230
|
-
type: 'PolymorphicOneToMany',
|
|
231
|
-
foreign_collection: field_schema.foreign_collection,
|
|
232
|
-
origin_key: field_schema.origin_key,
|
|
233
|
-
origin_key_target: field_schema.origin_key_target,
|
|
234
|
-
origin_type_field: field_schema.origin_type_field,
|
|
235
|
-
origin_type_value: field_schema.origin_type_value
|
|
236
|
-
}
|
|
237
|
-
else
|
|
238
|
-
# Fallback: try to convert to hash if possible
|
|
239
|
-
field_schema.respond_to?(:to_h) ? field_schema.to_h : field_schema
|
|
240
|
-
end
|
|
241
|
-
end
|
|
115
|
+
# Convert any object to a hash using its instance variables
|
|
116
|
+
def object_to_hash(obj)
|
|
117
|
+
return obj if obj.is_a?(Hash) || obj.is_a?(Array) || obj.is_a?(String) || obj.is_a?(Numeric) || obj.nil?
|
|
242
118
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
action.respond_to?(:to_h) ? action.to_h : action
|
|
119
|
+
obj.instance_variables.to_h do |var|
|
|
120
|
+
[var.to_s.delete('@').to_sym, obj.instance_variable_get(var)]
|
|
246
121
|
end
|
|
247
122
|
end
|
|
248
123
|
|
|
@@ -20,7 +20,7 @@ module ForestAdminRpcAgent
|
|
|
20
20
|
setting :prefix, default: nil
|
|
21
21
|
setting :cache_dir, default: :'tmp/cache/forest_admin'
|
|
22
22
|
setting :project_dir, default: Dir.pwd
|
|
23
|
-
setting :schema_path, default: File.join(Dir.pwd, '.forestadmin-schema.json')
|
|
23
|
+
setting :schema_path, default: File.join(Dir.pwd, '.forestadmin-rpc-schema.json')
|
|
24
24
|
setting :skip_schema_update, default: false
|
|
25
25
|
setting :logger_level, default: 'info'
|
|
26
26
|
setting :logger, default: nil
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forest_admin_rpc_agent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.18.
|
|
4
|
+
version: 1.18.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthieu
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2025-12-
|
|
12
|
+
date: 2025-12-12 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: base64
|