api_maker 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/channels/api_maker/subscriptions_channel.rb +58 -11
- data/app/services/api_maker/collection_loader.rb +2 -1
- data/app/services/api_maker/model_classes_java_script_generator_service.rb +8 -28
- data/app/services/api_maker/model_content_generator_service.rb +73 -48
- data/app/services/api_maker/models_finder_service.rb +1 -1
- data/app/services/api_maker/models_generator_service.rb +0 -30
- data/app/services/api_maker/translated_collections.rb +66 -0
- data/lib/api_maker/loader.rb +13 -5
- data/lib/api_maker/model_extensions.rb +23 -3
- data/lib/api_maker/spec_helper.rb +5 -1
- data/lib/api_maker/version.rb +1 -1
- metadata +21 -8
- data/lib/api_maker/javascript/model-template.js.erb +0 -124
- data/lib/api_maker/javascript/models.js.erb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aef63f4583ab87d088709072259692eafee02e7715816a9495b9c7b7faeb913f
|
4
|
+
data.tar.gz: 01f5a369a20712666808bc579cf6f0ad80c8e12bf90035af737a0fb5eface293
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71f93fcd6f1311186b0c919761ab5a4ac60a6ec91a93827e321eb02c80d99ee8973fa43b06559a51631fc9d5e0352e6c74f7b51f6f4de8bb0ba50d40ed9d9765
|
7
|
+
data.tar.gz: 988fbd78d4a84db08f17ada016083969b93cefaf505789d74d288bc7fb4cb110af5bac3d2aaccd09d85fddcd09e04e3d5f911ad065c0724d48d4c12ef1c06f1a
|
@@ -26,7 +26,16 @@ class ApiMaker::SubscriptionsChannel < ApplicationCable::Channel
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def connect_creates(model_name)
|
29
|
+
ability_name = :create_events
|
29
30
|
model_class = model_for_resource_name(model_name)
|
31
|
+
|
32
|
+
unless model_class.respond_to?(:api_maker_broadcast_create_channel_name)
|
33
|
+
error_message = "The model #{model_class.name} doesn't support the static method 'api_maker_broadcast_create_channel_name'. " \
|
34
|
+
"Maybe API maker extensions haven't been included?"
|
35
|
+
|
36
|
+
raise error_message
|
37
|
+
end
|
38
|
+
|
30
39
|
channel_name = model_class.api_maker_broadcast_create_channel_name
|
31
40
|
stream_from(channel_name, coder: ActiveSupport::JSON) do |data|
|
32
41
|
ApiMaker::Configuration.current.before_create_event_callbacks.each do |callback|
|
@@ -37,36 +46,57 @@ private
|
|
37
46
|
model_class = data.fetch("mcn").safe_constantize
|
38
47
|
|
39
48
|
Rails.logger.debug { "API maker: ConnectCreates for #{model_class.name}" }
|
40
|
-
|
49
|
+
model_exists = model_class
|
50
|
+
.accessible_by(current_ability, ability_name)
|
51
|
+
.exists?(model_class.primary_key => data.fetch("mi"))
|
41
52
|
|
42
53
|
# Transmit the data to JS if its found (and thereby allowed)
|
43
|
-
|
54
|
+
if model_exists
|
55
|
+
transmit data
|
56
|
+
else
|
57
|
+
Rails.logger.warn { "API maker: No access to connect to #{model_class.name} #{ability_name}" }
|
58
|
+
end
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
47
62
|
def connect_destroys(model_name, model_ids)
|
63
|
+
ability_name = :destroy_events
|
48
64
|
model_class = model_for_resource_name(model_name)
|
65
|
+
|
49
66
|
Rails.logger.debug { "API maker: ConnectDestroys for #{model_class.name}" }
|
50
|
-
|
51
|
-
|
52
|
-
|
67
|
+
accessible_model_ids = model_class
|
68
|
+
.accessible_by(current_ability, ability_name)
|
69
|
+
.where(model_class.primary_key => model_ids)
|
70
|
+
.ids
|
71
|
+
|
72
|
+
accessible_model_ids.each do |accessible_model_id|
|
73
|
+
channel_name = model_class.api_maker_broadcast_destroy_channel_name(accessible_model_id)
|
53
74
|
stream_from(channel_name, coder: ActiveSupport::JSON) do |data|
|
54
75
|
transmit data
|
55
76
|
end
|
56
77
|
end
|
78
|
+
|
79
|
+
report_unaccessible_model_ids(model_class, model_ids, accessible_model_ids, ability_name)
|
57
80
|
end
|
58
81
|
|
59
82
|
def connect_event(model_name, model_ids, event_name)
|
60
83
|
ability_name = "event_#{event_name}".to_sym
|
61
84
|
model_class = model_for_resource_name(model_name)
|
85
|
+
|
62
86
|
Rails.logger.debug { "API maker: ConnectEvents for #{model_class.name} #{event_name}" }
|
63
|
-
|
64
|
-
|
65
|
-
|
87
|
+
accessible_model_ids = model_class
|
88
|
+
.accessible_by(current_ability, ability_name)
|
89
|
+
.where(model_class.primary_key => model_ids)
|
90
|
+
.ids
|
91
|
+
|
92
|
+
accessible_model_ids.each do |accessible_model_id|
|
93
|
+
channel_name = model_class.api_maker_event_channel_name(accessible_model_id, event_name)
|
66
94
|
stream_from(channel_name, coder: ActiveSupport::JSON) do |data|
|
67
95
|
transmit data
|
68
96
|
end
|
69
97
|
end
|
98
|
+
|
99
|
+
report_unaccessible_model_ids(model_class, model_ids, accessible_model_ids, ability_name)
|
70
100
|
end
|
71
101
|
|
72
102
|
def connect_model_class_event(model_name, event_name)
|
@@ -86,22 +116,39 @@ private
|
|
86
116
|
end
|
87
117
|
|
88
118
|
def connect_updates(model_name, model_ids)
|
119
|
+
ability_name = :update_events
|
89
120
|
model_class = model_for_resource_name(model_name)
|
121
|
+
|
90
122
|
Rails.logger.debug { "API maker: ConnectUpdates for #{model_class.name}" }
|
123
|
+
accessible_model_ids = model_class
|
124
|
+
.accessible_by(current_ability, ability_name)
|
125
|
+
.where(model_class.primary_key => model_ids)
|
126
|
+
.ids
|
91
127
|
|
92
|
-
|
93
|
-
|
94
|
-
channel_name = model.api_maker_broadcast_update_channel_name
|
128
|
+
accessible_model_ids.each do |accessible_model_id|
|
129
|
+
channel_name = model_class.api_maker_broadcast_update_channel_name(accessible_model_id)
|
95
130
|
stream_from(channel_name, coder: ActiveSupport::JSON) do |data|
|
96
131
|
transmit data
|
97
132
|
end
|
98
133
|
end
|
134
|
+
|
135
|
+
report_unaccessible_model_ids(model_class, model_ids, accessible_model_ids, ability_name)
|
99
136
|
end
|
100
137
|
|
101
138
|
def model_for_resource_name(resource_name)
|
102
139
|
resource_for_resource_name(resource_name).model_class
|
103
140
|
end
|
104
141
|
|
142
|
+
def report_unaccessible_model_ids(model_class, model_ids, accessible_model_ids, ability_name)
|
143
|
+
model_ids = model_ids.map(&:to_s)
|
144
|
+
accessible_model_ids = accessible_model_ids.map(&:to_s)
|
145
|
+
unaccessible_model_ids = model_ids - accessible_model_ids
|
146
|
+
|
147
|
+
if unaccessible_model_ids.any?
|
148
|
+
Rails.logger.warn { "API maker: No access to connect to #{model_class.name} #{ability_name} for IDs: #{unaccessible_model_ids.join(", ")}" }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
105
152
|
def resource_for_resource_name(resource_name)
|
106
153
|
resource = "Resources::#{resource_name}Resource".safe_constantize
|
107
154
|
raise "Cannot find resource by resource name: #{resource_name}" unless resource
|
@@ -99,7 +99,8 @@ class ApiMaker::CollectionLoader < ApiMaker::ApplicationService
|
|
99
99
|
|
100
100
|
return if through_model.nil?
|
101
101
|
|
102
|
-
|
102
|
+
reflection = through_model_class.reflections.fetch(params[:through][:reflection])
|
103
|
+
association = ActiveRecord::Associations::Association.new(through_model, reflection)
|
103
104
|
|
104
105
|
query_through = association.scope
|
105
106
|
query_through = query_through.accessible_by(ability)
|
@@ -1,37 +1,17 @@
|
|
1
1
|
class ApiMaker::ModelClassesJavaScriptGeneratorService < ApiMaker::ApplicationService
|
2
2
|
def perform
|
3
|
-
|
4
|
-
|
3
|
+
result = {
|
4
|
+
models: {}
|
5
|
+
}
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
javascript_code << ApiMaker::ModelContentGeneratorService.execute!(model: model)
|
10
|
-
javascript_code << "\n\n"
|
11
|
-
|
12
|
-
resource = resource_for_model(model)
|
13
|
-
resource_names << resource.short_name
|
7
|
+
resources.each do |resource|
|
8
|
+
result[:models][resource.short_name] = ApiMaker::ModelContentGeneratorService.execute!(resource: resource)
|
14
9
|
end
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
succeed! javascript_code
|
19
|
-
end
|
20
|
-
|
21
|
-
def ignore_model?(model)
|
22
|
-
model.name.end_with?("::Translation", "::ApplicationRecord")
|
23
|
-
end
|
24
|
-
|
25
|
-
def models
|
26
|
-
@models ||= ApiMaker::ModelsFinderService.execute!
|
27
|
-
end
|
28
|
-
|
29
|
-
def model_file(model)
|
30
|
-
resource_class = ApiMaker::MemoryStorage.current.resource_for_model(model)
|
31
|
-
api_maker_root_path.join("models", "#{resource_class.short_name.underscore.dasherize}.js")
|
11
|
+
succeed! result
|
32
12
|
end
|
33
13
|
|
34
|
-
def
|
35
|
-
ApiMaker::
|
14
|
+
def resources
|
15
|
+
@resources ||= ApiMaker::ModelsFinderService.execute!
|
36
16
|
end
|
37
17
|
end
|
@@ -1,87 +1,116 @@
|
|
1
1
|
class ApiMaker::ModelContentGeneratorService < ApiMaker::ApplicationService
|
2
|
-
attr_reader :
|
2
|
+
attr_reader :resource
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
delegate :model_class, to: :resource
|
5
|
+
|
6
|
+
def initialize(resource:)
|
7
|
+
@resource = resource
|
6
8
|
end
|
7
9
|
|
8
10
|
def perform
|
9
|
-
|
10
|
-
succeed! model_content
|
11
|
-
else
|
12
|
-
fail! "No resource defined for #{model.name}"
|
13
|
-
end
|
11
|
+
succeed! model_content
|
14
12
|
end
|
15
13
|
|
16
14
|
private
|
17
15
|
|
18
16
|
def attributes
|
17
|
+
attributes = {}
|
19
18
|
resource._attributes.map do |attribute, _data|
|
20
|
-
{name: attribute}
|
19
|
+
attributes[attribute] = {name: attribute}
|
21
20
|
end
|
21
|
+
attributes
|
22
22
|
end
|
23
23
|
|
24
24
|
def collection_commands
|
25
|
-
ApiMaker::Loader.
|
26
|
-
|
25
|
+
ApiMaker::Loader.load_resources
|
26
|
+
|
27
|
+
result = {}
|
28
|
+
collection_commands = ApiMaker::MemoryStorage.current.storage_for(resource, :collection_commands)
|
29
|
+
collection_commands.each_key do |collection_command_name|
|
30
|
+
result[collection_command_name] = {name: collection_command_name}
|
31
|
+
end
|
32
|
+
|
33
|
+
result
|
27
34
|
end
|
28
35
|
|
29
36
|
def member_commands
|
30
|
-
ApiMaker::Loader.
|
31
|
-
|
37
|
+
ApiMaker::Loader.load_resources
|
38
|
+
|
39
|
+
result = {}
|
40
|
+
member_commands = ApiMaker::MemoryStorage.current.storage_for(resource, :member_commands)
|
41
|
+
member_commands.each_key do |member_command_name|
|
42
|
+
result[member_command_name] = {name: member_command_name}
|
43
|
+
end
|
44
|
+
|
45
|
+
result
|
32
46
|
end
|
33
47
|
|
34
48
|
def model_content
|
35
|
-
|
36
|
-
|
37
|
-
|
49
|
+
{
|
50
|
+
attributes: attributes,
|
51
|
+
collection_commands: collection_commands,
|
52
|
+
member_commands: member_commands,
|
53
|
+
model_class_data: model_class_data,
|
54
|
+
monetized_attributes: monetized_attributes,
|
55
|
+
relationships: relationships
|
56
|
+
}
|
38
57
|
end
|
39
58
|
|
40
|
-
def
|
41
|
-
|
59
|
+
def model_class_data
|
60
|
+
{
|
61
|
+
attributes: attributes,
|
62
|
+
className: model_class.name,
|
63
|
+
collectionKey: model_class.model_name.collection,
|
64
|
+
collectionName: resource.collection_name,
|
65
|
+
i18nKey: model_class.model_name.i18n_key,
|
66
|
+
name: resource.short_name,
|
67
|
+
pluralName: model_class.model_name.plural,
|
68
|
+
relationships: reflections_for_model_class_data,
|
69
|
+
paramKey: model_class.model_name.param_key,
|
70
|
+
primaryKey: model_class.primary_key
|
71
|
+
}
|
42
72
|
end
|
43
73
|
|
44
74
|
def monetized_attributes
|
45
|
-
@monetized_attributes ||=
|
75
|
+
@monetized_attributes ||= model_class.try(:monetized_attributes).try(:map) { |attribute| {name: attribute[0]} } || []
|
46
76
|
end
|
47
77
|
|
48
78
|
def reflections
|
49
79
|
@reflections ||= resource._relationships.map do |name, _data|
|
50
|
-
reflection =
|
80
|
+
reflection = model_class.reflections.values.find { |reflection_i| reflection_i.name == name }
|
51
81
|
|
52
82
|
unless reflection
|
53
|
-
raise "Couldnt find reflection by that name: #{name} on the model: #{
|
83
|
+
raise "Couldnt find reflection by that name: #{name} on the model: #{model_class.name}. Reflections found: #{model_class.reflections.keys.join(", ")}"
|
54
84
|
end
|
55
85
|
|
56
86
|
reflection
|
57
87
|
end
|
58
88
|
end
|
59
89
|
|
60
|
-
def
|
61
|
-
{
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
90
|
+
def relationships
|
91
|
+
relationships = {}
|
92
|
+
reflections.each do |reflection|
|
93
|
+
relationships[reflection.name] = {
|
94
|
+
active_record: {
|
95
|
+
name: reflection.active_record.name,
|
96
|
+
primary_key: reflection.active_record.primary_key
|
97
|
+
},
|
98
|
+
class_name: reflection.class_name,
|
99
|
+
foreign_key: reflection.foreign_key,
|
100
|
+
klass: {
|
101
|
+
primary_key: reflection.klass.primary_key
|
102
|
+
},
|
103
|
+
options: {
|
104
|
+
as: reflection.options[:as],
|
105
|
+
primary_key: reflection.options[:primary_key],
|
106
|
+
through: reflection.options[:through]
|
107
|
+
},
|
108
|
+
resource_name: ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name,
|
109
|
+
type: reflection.macro
|
79
110
|
}
|
80
|
-
else
|
81
|
-
ransack = {"#{reflection.foreign_key}_eq" => "{{id}}"}
|
82
|
-
ransack["#{reflection.options[:as]}_type_eq"] = reflection.active_record.name if reflection.options[:as]
|
83
|
-
{ransack: ransack}
|
84
111
|
end
|
112
|
+
|
113
|
+
relationships
|
85
114
|
end
|
86
115
|
|
87
116
|
def reflections_for_model_class_data
|
@@ -97,8 +126,4 @@ private
|
|
97
126
|
}
|
98
127
|
end
|
99
128
|
end
|
100
|
-
|
101
|
-
def resource
|
102
|
-
@resource ||= ApiMaker::MemoryStorage.current.resource_for_model(@model)
|
103
|
-
end
|
104
129
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
class ApiMaker::ModelsGeneratorService < ApiMaker::ApplicationService
|
2
2
|
def perform
|
3
|
-
create_base_structure
|
4
|
-
copy_base_model
|
5
|
-
|
6
3
|
ApiMaker::GenerateReactNativeApiService.execute! if ApiMaker::Configuration.current.react_native_path.present?
|
7
4
|
succeed!
|
8
5
|
end
|
@@ -11,28 +8,8 @@ class ApiMaker::ModelsGeneratorService < ApiMaker::ApplicationService
|
|
11
8
|
model.name.end_with?("::Translation", "::ApplicationRecord")
|
12
9
|
end
|
13
10
|
|
14
|
-
def models
|
15
|
-
ApiMaker::ModelsFinderService.execute!
|
16
|
-
end
|
17
|
-
|
18
11
|
private
|
19
12
|
|
20
|
-
def api_maker_root_path
|
21
|
-
Rails.root.join("app/javascript/api-maker")
|
22
|
-
end
|
23
|
-
|
24
|
-
def controller_path
|
25
|
-
Rails.root.join("app/controllers/api_maker")
|
26
|
-
end
|
27
|
-
|
28
|
-
def copy_base_model
|
29
|
-
files = %w[models.js.erb]
|
30
|
-
path = File.join(__dir__, "..", "..", "..", "lib", "api_maker", "javascript")
|
31
|
-
target_path = api_maker_root_path
|
32
|
-
|
33
|
-
copy_base_files(files, path, target_path)
|
34
|
-
end
|
35
|
-
|
36
13
|
def copy_base_files(files, path, target_path)
|
37
14
|
files.each do |file|
|
38
15
|
base_model_source_path = File.join(path, file)
|
@@ -57,11 +34,4 @@ private
|
|
57
34
|
end
|
58
35
|
end
|
59
36
|
end
|
60
|
-
|
61
|
-
def create_base_structure
|
62
|
-
# Dont remove all the files. It messes up running Webpack Dev Servers which forces you to restart all the time.
|
63
|
-
# FileUtils.rm_rf(api_maker_root_path) if File.exist?(api_maker_root_path)
|
64
|
-
|
65
|
-
FileUtils.mkdir_p(controller_path) unless File.exist?(controller_path)
|
66
|
-
end
|
67
37
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class ApiMaker::TranslatedCollections
|
2
|
+
def self.add(blk:, collection_name:, model_class:)
|
3
|
+
@translated_collections ||= {}
|
4
|
+
collections = {}
|
5
|
+
model_class_name = model_class.name
|
6
|
+
collection_values = nil
|
7
|
+
|
8
|
+
I18n.available_locales.each do |locale|
|
9
|
+
I18n.with_locale(locale) do
|
10
|
+
collection = blk.call.freeze
|
11
|
+
collections[locale.to_s] = {
|
12
|
+
collection: collection,
|
13
|
+
collection_array: collection.map { |translation, value| [translation: translation, value: value] }.flatten,
|
14
|
+
inverted_collection: collection.invert
|
15
|
+
}
|
16
|
+
collection_values = collection.values.clone.freeze if collection_values.nil?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@translated_collections[model_class_name] ||= {}
|
21
|
+
@translated_collections[model_class_name][collection_name] ||= collections
|
22
|
+
|
23
|
+
plural_name = collection_name.to_s.pluralize
|
24
|
+
inverted_translated_collection_name = "translated_#{plural_name}_inverted"
|
25
|
+
|
26
|
+
add_translated_collection_method(model_class, plural_name, collections)
|
27
|
+
add_translated_inverted_collection_method(model_class, inverted_translated_collection_name, collections)
|
28
|
+
add_collection_values_method(model_class, plural_name, collection_values)
|
29
|
+
add_translated_method(model_class, collection_name, inverted_translated_collection_name)
|
30
|
+
|
31
|
+
model_class.validates collection_name, inclusion: {in: collection_values}
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.add_translated_collection_method(model_class, plural_name, collections)
|
35
|
+
model_class.define_singleton_method("translated_#{plural_name}") do
|
36
|
+
collections.fetch(I18n.locale.to_s).fetch(:collection)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.add_translated_inverted_collection_method(model_class, inverted_translated_collection_name, collections)
|
41
|
+
model_class.define_singleton_method(inverted_translated_collection_name) do
|
42
|
+
collections.fetch(I18n.locale.to_s).fetch(:inverted_collection)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.add_collection_values_method(model_class, plural_name, collection_values)
|
47
|
+
model_class.define_singleton_method(plural_name) do
|
48
|
+
collection_values
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.add_translated_method(model_class, collection_name, inverted_translated_collection_name)
|
53
|
+
model_class.define_method("translated_#{collection_name}") do
|
54
|
+
current_value = __send__(collection_name)
|
55
|
+
inverted_translated_collection = self.class.__send__(inverted_translated_collection_name)
|
56
|
+
inverted_translated_collection.fetch(current_value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.translated_collections
|
61
|
+
ApiMaker::Loader.load_models
|
62
|
+
|
63
|
+
@translated_collections ||= {}
|
64
|
+
@translated_collections
|
65
|
+
end
|
66
|
+
end
|
data/lib/api_maker/loader.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
class ApiMaker::Loader
|
2
|
-
def self.
|
3
|
-
|
2
|
+
def self.load_resources
|
3
|
+
load_dir(Rails.root.join("app/api_maker/resources"))
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.load_models
|
7
|
+
load_dir(Rails.root.join("app/models"))
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.load_dir(dir)
|
11
|
+
@dirs_loaded ||= {}
|
4
12
|
|
5
|
-
|
13
|
+
return if @dirs_loaded.key?(dir)
|
6
14
|
|
7
|
-
|
8
|
-
files = Dir.glob("#{resources_dir}/**/*.rb")
|
15
|
+
@dirs_loaded[dir] = true
|
9
16
|
|
17
|
+
files = Dir.glob("#{dir}/**/*.rb")
|
10
18
|
files.each do |file|
|
11
19
|
require file
|
12
20
|
end
|
@@ -14,6 +14,18 @@ module ApiMaker::ModelExtensions
|
|
14
14
|
@api_maker_broadcast_create_channel_name ||= "api_maker_creates_#{api_maker_resource.short_name}"
|
15
15
|
end
|
16
16
|
|
17
|
+
def api_maker_broadcast_destroy_channel_name(id)
|
18
|
+
"api_maker_destroys_#{api_maker_resource.short_name}_#{id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def api_maker_event_channel_name(id, event_name)
|
22
|
+
"api_maker_events_#{api_maker_resource.short_name}_#{id}_#{event_name}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def api_maker_broadcast_update_channel_name(id)
|
26
|
+
"api_maker_updates_#{api_maker_resource.short_name}_#{id}"
|
27
|
+
end
|
28
|
+
|
17
29
|
def api_maker_broadcast_updates
|
18
30
|
after_commit on: :update do |model| # rubocop:disable Style/SymbolProc
|
19
31
|
model.api_maker_broadcast_update
|
@@ -45,6 +57,14 @@ module ApiMaker::ModelExtensions
|
|
45
57
|
def api_maker_resource
|
46
58
|
@api_maker_resource ||= ApiMaker::MemoryStorage.current.resource_for_model(self)
|
47
59
|
end
|
60
|
+
|
61
|
+
def translated_collection(collection_name, &blk)
|
62
|
+
ApiMaker::TranslatedCollections.add(
|
63
|
+
blk: blk,
|
64
|
+
collection_name: collection_name,
|
65
|
+
model_class: self
|
66
|
+
)
|
67
|
+
end
|
48
68
|
end
|
49
69
|
|
50
70
|
def api_maker_event(event_name, args = {})
|
@@ -61,7 +81,7 @@ module ApiMaker::ModelExtensions
|
|
61
81
|
end
|
62
82
|
|
63
83
|
def api_maker_event_channel_name(event_name)
|
64
|
-
|
84
|
+
self.class.api_maker_event_channel_name(id, event_name)
|
65
85
|
end
|
66
86
|
|
67
87
|
def api_maker_broadcast_create
|
@@ -88,7 +108,7 @@ module ApiMaker::ModelExtensions
|
|
88
108
|
end
|
89
109
|
|
90
110
|
def api_maker_broadcast_destroy_channel_name
|
91
|
-
@api_maker_broadcast_destroy_channel_name ||=
|
111
|
+
@api_maker_broadcast_destroy_channel_name ||= self.class.api_maker_broadcast_destroy_channel_name(id)
|
92
112
|
end
|
93
113
|
|
94
114
|
def api_maker_broadcast_update
|
@@ -103,7 +123,7 @@ module ApiMaker::ModelExtensions
|
|
103
123
|
end
|
104
124
|
|
105
125
|
def api_maker_broadcast_update_channel_name
|
106
|
-
|
126
|
+
self.class.api_maker_broadcast_update_channel_name(id)
|
107
127
|
end
|
108
128
|
|
109
129
|
def api_maker_resource
|
@@ -81,6 +81,10 @@ module ApiMaker::SpecHelper # rubocop:disable Metrics/ModuleLength
|
|
81
81
|
page.execute_script("document.querySelector(#{element_id.to_json}).value = #{with.to_json}")
|
82
82
|
end
|
83
83
|
|
84
|
+
def model_column_selector(model, identifier)
|
85
|
+
".#{model.model_name.singular.dasherize}-row[data-model-id='#{model.id}'] .live-table-column[data-identifier='#{identifier}']"
|
86
|
+
end
|
87
|
+
|
84
88
|
def model_row_selector(model)
|
85
89
|
".#{model.model_name.singular.dasherize}-row[data-model-id='#{model.id}']"
|
86
90
|
end
|
@@ -117,7 +121,7 @@ module ApiMaker::SpecHelper # rubocop:disable Metrics/ModuleLength
|
|
117
121
|
|
118
122
|
tr_selector = ".component-api-maker-attribute-row"
|
119
123
|
tr_selector << "[data-attribute='#{attribute.camelize(:lower)}']" if attribute
|
120
|
-
tr_selector << "[data-identifier='#{identifier
|
124
|
+
tr_selector << "[data-identifier='#{identifier}']" if identifier
|
121
125
|
|
122
126
|
wait_for_selector "#{tr_selector} > .attribute-row-label", exact_text: label, **opts if label
|
123
127
|
wait_for_selector "#{tr_selector} > .attribute-row-value", exact_text: value, **opts if value
|
data/lib/api_maker/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_maker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kaspernj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: awesome_translations
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.0.60
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.0.60
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: best_practice_project
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -406,16 +420,16 @@ dependencies:
|
|
406
420
|
name: selenium-webdriver
|
407
421
|
requirement: !ruby/object:Gem::Requirement
|
408
422
|
requirements:
|
409
|
-
- - "
|
423
|
+
- - "<="
|
410
424
|
- !ruby/object:Gem::Version
|
411
|
-
version:
|
425
|
+
version: 4.1.1
|
412
426
|
type: :development
|
413
427
|
prerelease: false
|
414
428
|
version_requirements: !ruby/object:Gem::Requirement
|
415
429
|
requirements:
|
416
|
-
- - "
|
430
|
+
- - "<="
|
417
431
|
- !ruby/object:Gem::Version
|
418
|
-
version:
|
432
|
+
version: 4.1.1
|
419
433
|
- !ruby/object:Gem::Dependency
|
420
434
|
name: sqlite3
|
421
435
|
requirement: !ruby/object:Gem::Requirement
|
@@ -527,6 +541,7 @@ files:
|
|
527
541
|
- app/services/api_maker/service_command.rb
|
528
542
|
- app/services/api_maker/service_command_service.rb
|
529
543
|
- app/services/api_maker/simple_model_errors.rb
|
544
|
+
- app/services/api_maker/translated_collections.rb
|
530
545
|
- app/services/api_maker/update_command.rb
|
531
546
|
- app/services/api_maker/update_command_service.rb
|
532
547
|
- app/services/api_maker/valid_command.rb
|
@@ -548,8 +563,6 @@ files:
|
|
548
563
|
- lib/api_maker/engine.rb
|
549
564
|
- lib/api_maker/expect_to_able_to_helper.rb
|
550
565
|
- lib/api_maker/individual_command.rb
|
551
|
-
- lib/api_maker/javascript/model-template.js.erb
|
552
|
-
- lib/api_maker/javascript/models.js.erb
|
553
566
|
- lib/api_maker/loader.rb
|
554
567
|
- lib/api_maker/memory_storage.rb
|
555
568
|
- lib/api_maker/model_extensions.rb
|
@@ -1,124 +0,0 @@
|
|
1
|
-
class <%= resource.short_name %> extends BaseModel {
|
2
|
-
static modelClassData() {
|
3
|
-
return <%= {
|
4
|
-
attributes: attributes,
|
5
|
-
className: model.name,
|
6
|
-
collectionKey: model.model_name.collection,
|
7
|
-
collectionName: resource.collection_name,
|
8
|
-
i18nKey: model.model_name.i18n_key,
|
9
|
-
name: resource.short_name,
|
10
|
-
pluralName: model.model_name.plural,
|
11
|
-
relationships: reflections_for_model_class_data,
|
12
|
-
paramKey: model.model_name.param_key,
|
13
|
-
path: "/api_maker/#{model.model_name.route_key}",
|
14
|
-
primaryKey: model.primary_key
|
15
|
-
}.to_json %>
|
16
|
-
}
|
17
|
-
|
18
|
-
<% reflections.each do |reflection| %>
|
19
|
-
<% if reflection.macro == :belongs_to %>
|
20
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: "load_#{reflection.name}") %>() {
|
21
|
-
const id = this.<%= ApiMaker::JsMethodNamerService.execute!(name: reflection.foreign_key) %>()
|
22
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
23
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
24
|
-
return this._loadBelongsToReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>, <%= api_maker_json("ransack" => {"#{reflection.options[:primary_key] || reflection.klass.primary_key}_eq" => "{{id}}"}) %>)
|
25
|
-
}
|
26
|
-
|
27
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: reflection.name) %>() {
|
28
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
29
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
30
|
-
return this._readBelongsToReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>)
|
31
|
-
}
|
32
|
-
<% elsif reflection.macro == :has_many %>
|
33
|
-
<% if reflection.options[:through] %>
|
34
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: "load_#{reflection.name}") %>() {
|
35
|
-
const id = this.<%= reflection.active_record.primary_key %>()
|
36
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
37
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
38
|
-
return this._loadHasManyReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>, <%= api_maker_json("params": {"through" => {"model" => model.model_name, "id" => "{{id}}", "reflection" => reflection.name}}) %>)
|
39
|
-
}
|
40
|
-
<% else %>
|
41
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: "load_#{reflection.name}") %>() {
|
42
|
-
const id = this.<%= reflection.active_record.primary_key %>()
|
43
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
44
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
45
|
-
return this._loadHasManyReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>, <%= api_maker_json("ransack" => {"#{reflection.foreign_key}_eq" => "{{id}}"}) %>)
|
46
|
-
}
|
47
|
-
<% end %>
|
48
|
-
|
49
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: reflection.name) %>() {
|
50
|
-
const id = this.<%= ApiMaker::JsMethodNamerService.execute!(name: reflection.options[:primary_key] || reflection.active_record.primary_key) %>()
|
51
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
52
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
53
|
-
return new Collection(<%= api_maker_json(reflection_has_many_parameters(reflection)) %>, <%= api_maker_json(reflection_has_many_parameters_query(reflection)) %>)
|
54
|
-
}
|
55
|
-
<% elsif reflection.macro == :has_one && reflection.options[:through] %>
|
56
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: "load_#{reflection.name}") %>() {
|
57
|
-
const id = this.<%= reflection.active_record.primary_key %>()
|
58
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
59
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
60
|
-
return this._loadHasOneReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>, <%= api_maker_json("params": {"through" => {"model" => model.model_name, "id" => "{{id}}", "reflection" => reflection.name}}) %>)
|
61
|
-
}
|
62
|
-
|
63
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: reflection.name) %>() {
|
64
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
65
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
66
|
-
return this._readHasOneReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>)
|
67
|
-
}
|
68
|
-
<% elsif reflection.macro == :has_one %>
|
69
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: "load_#{reflection.name}") %>() {
|
70
|
-
const id = this.<%= reflection.active_record.primary_key %>()
|
71
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
72
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
73
|
-
return this._loadHasOneReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>, <%= api_maker_json("ransack" => {"#{reflection.foreign_key}_eq" => "{{id}}"}) %>)
|
74
|
-
}
|
75
|
-
|
76
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: reflection.name) %>() {
|
77
|
-
const resourceName = "<%= ApiMaker::MemoryStorage.current.resource_for_model(reflection.klass).short_name %>"
|
78
|
-
const modelClass = digg(require("api-maker/models"), resourceName)
|
79
|
-
return this._readHasOneReflection(<%= api_maker_json("reflectionName" => reflection.name, "model" => "{{this}}", "modelClass" => "{{modelClass}}") %>)
|
80
|
-
}
|
81
|
-
<% end %>
|
82
|
-
<% end %>
|
83
|
-
|
84
|
-
<% attributes.each do |attribute_data| %>
|
85
|
-
<% methodName = ApiMaker::JsMethodNamerService.execute!(name: attribute_data.fetch(:name)) %>
|
86
|
-
<%= methodName %>() {
|
87
|
-
return this.readAttributeUnderscore("<%= attribute_data.fetch(:name) %>")
|
88
|
-
}
|
89
|
-
|
90
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: "has_#{attribute_data.fetch(:name)}") %>() {
|
91
|
-
const value = this.<%= methodName %>()
|
92
|
-
return this._isPresent(value)
|
93
|
-
}
|
94
|
-
<% end %>
|
95
|
-
|
96
|
-
<% collection_commands.each do |collection_command, data| %>
|
97
|
-
static <%= ApiMaker::JsMethodNamerService.execute!(name: collection_command) %>(args, commandArgs = {}) {
|
98
|
-
return this._callCollectionCommand(
|
99
|
-
{
|
100
|
-
args: args,
|
101
|
-
command: "<%= collection_command %>",
|
102
|
-
collectionName: this.modelClassData().collectionName,
|
103
|
-
type: "collection"
|
104
|
-
},
|
105
|
-
commandArgs
|
106
|
-
)
|
107
|
-
}
|
108
|
-
<% end %>
|
109
|
-
|
110
|
-
<% member_commands.each do |member_command, data| %>
|
111
|
-
<%= ApiMaker::JsMethodNamerService.execute!(name: member_command) %>(args, commandArgs = {}) {
|
112
|
-
return this._callMemberCommand(
|
113
|
-
{
|
114
|
-
args: args,
|
115
|
-
command: "<%= member_command %>",
|
116
|
-
primaryKey: this.primaryKey(),
|
117
|
-
collectionName: this.modelClassData().collectionName,
|
118
|
-
type: "member"
|
119
|
-
},
|
120
|
-
commandArgs
|
121
|
-
)
|
122
|
-
}
|
123
|
-
<% end %>
|
124
|
-
}
|