api_maker 0.0.2 → 0.0.3
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/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
|
-
}
|