rider-kick 0.0.13 → 0.0.14
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/README.md +629 -25
- data/lib/generators/rider_kick/USAGE +2 -0
- data/lib/generators/rider_kick/base_generator.rb +190 -0
- data/lib/generators/rider_kick/clean_arch_generator.rb +235 -45
- data/lib/generators/rider_kick/clean_arch_generator_engine_spec.rb +359 -0
- data/lib/generators/rider_kick/clean_arch_generator_factory_bot_spec.rb +131 -0
- data/lib/generators/rider_kick/entity_type_mapping_spec.rb +22 -13
- data/lib/generators/rider_kick/errors.rb +42 -0
- data/lib/generators/rider_kick/factory_generator.rb +238 -0
- data/lib/generators/rider_kick/factory_generator_spec.rb +175 -0
- data/lib/generators/rider_kick/repositories_contract_spec.rb +95 -22
- data/lib/generators/rider_kick/scaffold_generator.rb +377 -62
- data/lib/generators/rider_kick/scaffold_generator_builder_uploaders_spec.rb +119 -14
- data/lib/generators/rider_kick/scaffold_generator_conditional_filtering_spec.rb +820 -0
- data/lib/generators/rider_kick/scaffold_generator_contracts_spec.rb +37 -10
- data/lib/generators/rider_kick/scaffold_generator_contracts_with_scope_spec.rb +40 -11
- data/lib/generators/rider_kick/scaffold_generator_engine_spec.rb +221 -0
- data/lib/generators/rider_kick/scaffold_generator_idempotent_spec.rb +38 -13
- data/lib/generators/rider_kick/scaffold_generator_list_spec_format_spec.rb +153 -0
- data/lib/generators/rider_kick/scaffold_generator_rspec_spec.rb +347 -0
- data/lib/generators/rider_kick/scaffold_generator_success_spec.rb +31 -12
- data/lib/generators/rider_kick/scaffold_generator_with_scope_spec.rb +32 -11
- data/lib/generators/rider_kick/structure_generator.rb +154 -43
- data/lib/generators/rider_kick/structure_generator_comprehensive_spec.rb +598 -0
- data/lib/generators/rider_kick/structure_generator_engine_spec.rb +279 -0
- data/lib/generators/rider_kick/structure_generator_spec.rb +3 -3
- data/lib/generators/rider_kick/structure_generator_success_spec.rb +33 -5
- data/lib/generators/rider_kick/structure_generator_unit_spec.rb +2202 -0
- data/lib/generators/rider_kick/templates/.rubocop.yml +5 -4
- data/lib/generators/rider_kick/templates/config/initializers/version.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/db/migrate/20220613145533_init_database.rb +1 -1
- data/lib/generators/rider_kick/templates/db/structures/example.yaml.tt +140 -66
- data/lib/generators/rider_kick/templates/domains/core/builders/builder.rb.tt +36 -10
- data/lib/generators/rider_kick/templates/domains/core/builders/builder_spec.rb.tt +219 -0
- data/lib/generators/rider_kick/templates/domains/core/builders/error.rb.tt +2 -2
- data/lib/generators/rider_kick/templates/domains/core/builders/pagination.rb.tt +2 -2
- data/lib/generators/rider_kick/templates/domains/core/entities/entity.rb.tt +32 -14
- data/lib/generators/rider_kick/templates/domains/core/entities/error.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/entities/pagination.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/repositories/abstract_repository.rb.tt +4 -4
- data/lib/generators/rider_kick/templates/domains/core/repositories/create.rb.tt +2 -2
- data/lib/generators/rider_kick/templates/domains/core/repositories/create_spec.rb.tt +78 -0
- data/lib/generators/rider_kick/templates/domains/core/repositories/destroy.rb.tt +2 -2
- data/lib/generators/rider_kick/templates/domains/core/repositories/destroy_spec.rb.tt +88 -0
- data/lib/generators/rider_kick/templates/domains/core/repositories/fetch_by_id.rb.tt +3 -3
- data/lib/generators/rider_kick/templates/domains/core/repositories/fetch_by_id_spec.rb.tt +62 -0
- data/lib/generators/rider_kick/templates/domains/core/repositories/list.rb.tt +13 -8
- data/lib/generators/rider_kick/templates/domains/core/repositories/list_spec.rb.tt +190 -0
- data/lib/generators/rider_kick/templates/domains/core/repositories/update.rb.tt +4 -4
- data/lib/generators/rider_kick/templates/domains/core/repositories/update_spec.rb.tt +119 -0
- data/lib/generators/rider_kick/templates/domains/core/use_cases/contract/default.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/contract/pagination.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/create.rb.tt +3 -7
- data/lib/generators/rider_kick/templates/domains/core/use_cases/create_spec.rb.tt +71 -0
- data/lib/generators/rider_kick/templates/domains/core/use_cases/destroy.rb.tt +3 -7
- data/lib/generators/rider_kick/templates/domains/core/use_cases/destroy_spec.rb.tt +62 -0
- data/lib/generators/rider_kick/templates/domains/core/use_cases/fetch_by_id.rb.tt +3 -7
- data/lib/generators/rider_kick/templates/domains/core/use_cases/fetch_by_id_spec.rb.tt +62 -0
- data/lib/generators/rider_kick/templates/domains/core/use_cases/get_version.rb.tt +2 -2
- data/lib/generators/rider_kick/templates/domains/core/use_cases/list.rb.tt +3 -7
- data/lib/generators/rider_kick/templates/domains/core/use_cases/list_spec.rb.tt +64 -0
- data/lib/generators/rider_kick/templates/domains/core/use_cases/update.rb.tt +3 -7
- data/lib/generators/rider_kick/templates/domains/core/use_cases/update_spec.rb.tt +73 -0
- data/lib/generators/rider_kick/templates/domains/core/utils/abstract_utils.rb.tt +3 -3
- data/lib/generators/rider_kick/templates/domains/core/utils/request_methods.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/env.development +1 -1
- data/lib/generators/rider_kick/templates/env.production +1 -1
- data/lib/generators/rider_kick/templates/env.test +1 -1
- data/lib/generators/rider_kick/templates/models/{application_record.rb → application_record.rb.tt} +3 -1
- data/lib/generators/rider_kick/templates/models/model_spec.rb.tt +68 -0
- data/lib/generators/rider_kick/templates/spec/factories/.gitkeep +19 -0
- data/lib/generators/rider_kick/templates/spec/factories/factory.rb.tt +8 -0
- data/lib/generators/rider_kick/templates/spec/rails_helper.rb +2 -0
- data/lib/generators/rider_kick/templates/spec/support/class_stubber.rb +148 -0
- data/lib/generators/rider_kick/templates/spec/support/factory_bot.rb +34 -0
- data/lib/generators/rider_kick/templates/spec/support/faker.rb +61 -0
- data/lib/rider-kick.rb +8 -6
- data/lib/rider_kick/builders/abstract_active_record_entity_builder_spec.rb +644 -0
- data/lib/rider_kick/configuration.rb +238 -0
- data/lib/rider_kick/configuration_engine_spec.rb +377 -0
- data/lib/rider_kick/entities/failure_details.rb +1 -1
- data/lib/rider_kick/entities/failure_details_spec.rb +1 -1
- data/lib/rider_kick/matchers/use_case_result.rb +1 -1
- data/lib/rider_kick/use_cases/abstract_use_case.rb +1 -1
- data/lib/rider_kick/version.rb +1 -1
- metadata +129 -8
- data/CHANGELOG.md +0 -5
|
@@ -1,11 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators'
|
|
4
|
+
require 'active_support/inflector'
|
|
5
|
+
require 'active_support/core_ext/object/blank'
|
|
6
|
+
require 'active_support/core_ext/enumerable'
|
|
7
|
+
require 'hashie'
|
|
8
|
+
require_relative 'base_generator'
|
|
9
|
+
require_relative '../../rider-kick'
|
|
10
|
+
|
|
1
11
|
module RiderKick
|
|
2
|
-
class Structure <
|
|
12
|
+
class Structure < BaseGenerator
|
|
3
13
|
source_root File.expand_path('templates', __dir__)
|
|
4
14
|
|
|
5
15
|
argument :arg_model_name, type: :string, default: '', banner: 'Models::Name'
|
|
6
|
-
argument :arg_settings, type: :hash, default:
|
|
16
|
+
argument :arg_settings, type: :hash, default: {}, banner: 'route_scope:dashboard actor:user uploaders:assets,images,picture,document'
|
|
17
|
+
class_option :engine, type: :string, default: nil, desc: 'Specify engine name (e.g., Core, Admin)'
|
|
18
|
+
class_option :domain, type: :string, default: '', desc: 'Specify domain scope (e.g., core/, admin/, api/v1/)'
|
|
7
19
|
|
|
8
20
|
def generate_use_case
|
|
21
|
+
configure_engine
|
|
9
22
|
validation!
|
|
10
23
|
setup_variables
|
|
11
24
|
generate_files(@scope_path)
|
|
@@ -14,49 +27,116 @@ module RiderKick
|
|
|
14
27
|
private
|
|
15
28
|
|
|
16
29
|
def validation!
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
validate_domains_path!
|
|
31
|
+
|
|
32
|
+
# Pastikan parameter wajib tersedia
|
|
33
|
+
actor = arg_settings['actor'].to_s.strip
|
|
34
|
+
resource_owner = arg_settings['resource_owner'].to_s.strip
|
|
35
|
+
resource_owner_id = arg_settings['resource_owner_id'].to_s.strip
|
|
36
|
+
|
|
37
|
+
if actor.blank?
|
|
38
|
+
raise ValidationError.new(
|
|
39
|
+
"Missing required setting: actor. Contoh: 'actor:user'",
|
|
40
|
+
setting: 'actor',
|
|
41
|
+
provided_settings: arg_settings.keys
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if resource_owner.blank?
|
|
46
|
+
raise ValidationError.new(
|
|
47
|
+
"Missing required setting: resource_owner. Contoh: 'resource_owner:account'",
|
|
48
|
+
setting: 'resource_owner',
|
|
49
|
+
provided_settings: arg_settings.keys
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if resource_owner_id.blank?
|
|
54
|
+
raise ValidationError.new(
|
|
55
|
+
"Missing required setting: resource_owner_id. Contoh: 'resource_owner_id:account_id'",
|
|
56
|
+
setting: 'resource_owner_id',
|
|
57
|
+
provided_settings: arg_settings.keys
|
|
58
|
+
)
|
|
20
59
|
end
|
|
21
60
|
end
|
|
22
61
|
|
|
23
62
|
def setup_variables
|
|
24
|
-
@variable_subject
|
|
63
|
+
@variable_subject = arg_model_name.split('::').last.underscore.downcase
|
|
64
|
+
validate_model_exists!(arg_model_name.camelize)
|
|
25
65
|
@model_class = arg_model_name.camelize.constantize
|
|
26
66
|
@subject_class = arg_model_name.split('::').last
|
|
27
67
|
@scope_path = @subject_class.pluralize.underscore.downcase
|
|
28
68
|
@scope_class = @scope_path.camelize
|
|
29
69
|
@fields = contract_fields
|
|
30
|
-
@uploaders = uploaders
|
|
31
|
-
@actor = arg_settings['actor'].downcase
|
|
70
|
+
@uploaders = uploaders # Ini array string dari argumen
|
|
71
|
+
@actor = arg_settings['actor'].to_s.downcase
|
|
72
|
+
@actor_id = (@actor.present? ? arg_settings['actor'].to_s.downcase + '_id' : '')
|
|
32
73
|
|
|
74
|
+
@resource_owner = arg_settings['resource_owner'].to_s.presence
|
|
33
75
|
@resource_owner_id = arg_settings['resource_owner_id'].to_s.presence
|
|
34
|
-
@
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
@
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
'
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
76
|
+
@columns = columns_meta
|
|
77
|
+
|
|
78
|
+
@type_mapping = RiderKick.configuration.type_mapping
|
|
79
|
+
@entity_type_mapping = RiderKick.configuration.entity_type_mapping
|
|
80
|
+
|
|
81
|
+
@columns_meta_hash = @columns.index_by { |c| c[:name] }
|
|
82
|
+
|
|
83
|
+
@contract_lines_for_create = @fields.map do |field_name|
|
|
84
|
+
column_meta = @columns_meta_hash[field_name]
|
|
85
|
+
next nil if column_meta.nil?
|
|
86
|
+
|
|
87
|
+
predicate = column_meta[:null] ? 'optional' : 'required'
|
|
88
|
+
db_type = get_column_type(field_name).to_s
|
|
89
|
+
validation_type = @type_mapping[db_type]
|
|
90
|
+
|
|
91
|
+
if db_type == 'upload'
|
|
92
|
+
validation_type = 'Types::File'
|
|
93
|
+
elsif validation_type.nil?
|
|
94
|
+
validation_type = ':string'
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
if predicate == 'required'
|
|
98
|
+
"\"required(:#{field_name}).filled(#{validation_type})\""
|
|
99
|
+
else
|
|
100
|
+
"\"optional(:#{field_name}).maybe(#{validation_type})\""
|
|
101
|
+
end
|
|
102
|
+
end.compact
|
|
103
|
+
|
|
104
|
+
@contract_lines_for_update = @fields.map do |field_name|
|
|
105
|
+
column_meta = @columns_meta_hash[field_name]
|
|
106
|
+
next nil if column_meta.nil?
|
|
107
|
+
|
|
108
|
+
db_type = get_column_type(field_name).to_s
|
|
109
|
+
validation_type = @type_mapping[db_type]
|
|
110
|
+
|
|
111
|
+
if db_type == 'upload'
|
|
112
|
+
validation_type = 'Types::File'
|
|
113
|
+
elsif validation_type.nil?
|
|
114
|
+
validation_type = ':string'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
"\"optional(:#{field_name}).maybe(#{validation_type})\""
|
|
118
|
+
end.compact
|
|
119
|
+
|
|
120
|
+
search_able_fields = arg_settings['search_able'].to_s.split(',').map(&:strip).reject(&:blank?)
|
|
121
|
+
|
|
122
|
+
@repository_list_filters = search_able_fields.map do |field|
|
|
123
|
+
"{ field: '#{field}', type: 'search' }"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
@contract_lines_for_list = @repository_list_filters.map do |filter_hash|
|
|
127
|
+
field_name = filter_hash.match(/field: '([^']+)'/)[1]
|
|
128
|
+
"\"optional(:#{field_name}).maybe(:string)\""
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
@entity_db_fields = @fields
|
|
132
|
+
|
|
133
|
+
# 1. Tentukan definisi uploader yang kaya (array of hashes)
|
|
134
|
+
# @uploaders di sini masih array string dari argumen
|
|
135
|
+
@entity_uploader_definitions = @uploaders.map do |uploader_name|
|
|
136
|
+
type = is_singular?(uploader_name) ? 'single' : 'multiple'
|
|
137
|
+
# PERBAIKAN: Ini harus menjadi Hash, BUKAN String
|
|
138
|
+
{ name: uploader_name, type: type }
|
|
139
|
+
end
|
|
60
140
|
end
|
|
61
141
|
|
|
62
142
|
def columns_meta
|
|
@@ -74,37 +154,68 @@ module RiderKick
|
|
|
74
154
|
end
|
|
75
155
|
end
|
|
76
156
|
|
|
77
|
-
# optional: isi jika nanti kamu introspeksi foreign keys
|
|
78
157
|
def fkeys_meta = []
|
|
79
158
|
|
|
80
|
-
# optional: isi jika nanti kamu introspeksi index
|
|
81
159
|
def indexes_meta = []
|
|
82
160
|
|
|
83
|
-
# optional: isi jika pakai AR enum
|
|
84
161
|
def enums_meta = {}
|
|
85
162
|
|
|
86
|
-
|
|
87
|
-
|
|
163
|
+
def contract_lines_for_create
|
|
164
|
+
@contract_lines_for_create || []
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def contract_lines_for_update
|
|
168
|
+
@contract_lines_for_update || []
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def contract_lines_for_list
|
|
172
|
+
@contract_lines_for_list || []
|
|
173
|
+
end
|
|
88
174
|
|
|
89
|
-
def
|
|
175
|
+
def repository_list_filters
|
|
176
|
+
@repository_list_filters || []
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def entity_db_fields
|
|
180
|
+
@entity_db_fields || []
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def entity_uploader_definitions
|
|
184
|
+
@entity_uploader_definitions || []
|
|
185
|
+
end
|
|
90
186
|
|
|
91
187
|
def is_singular?(str)
|
|
92
188
|
str.singularize == str
|
|
93
189
|
end
|
|
94
190
|
|
|
95
191
|
def generate_files(action)
|
|
96
|
-
|
|
192
|
+
structure_path = if RiderKick.configuration.engine_name.present?
|
|
193
|
+
# For engines, generate structure file in engine's db/structures directory
|
|
194
|
+
engine_name = RiderKick.configuration.engine_name.downcase
|
|
195
|
+
"engines/#{engine_name}/db/structures/#{action}_structure.yaml"
|
|
196
|
+
else
|
|
197
|
+
# For main app, generate in host's db/structures directory
|
|
198
|
+
"db/structures/#{action}_structure.yaml"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
template 'db/structures/example.yaml.tt', structure_path
|
|
97
202
|
end
|
|
98
203
|
|
|
99
204
|
def contract_fields
|
|
100
|
-
|
|
205
|
+
# Metode ini sekarang hanya digunakan oleh setup_variables untuk @fields
|
|
206
|
+
@model_class.columns.reject { |column|
|
|
207
|
+
(uploaders + ['id', 'created_at', 'updated_at', 'type']).include?(column.name.to_s)
|
|
208
|
+
}.map(&:name).map(&:to_s)
|
|
101
209
|
end
|
|
102
210
|
|
|
103
211
|
def get_column_type(field)
|
|
104
|
-
uploaders
|
|
212
|
+
# uploaders di sini masih array string
|
|
213
|
+
uploaders.include?(field) ?
|
|
214
|
+
'upload' : @model_class.columns_hash[field].type
|
|
105
215
|
end
|
|
106
216
|
|
|
107
217
|
def uploaders
|
|
218
|
+
# Ini adalah array string mentah dari argumen
|
|
108
219
|
return [] unless arg_settings['uploaders'].present?
|
|
109
220
|
arg_settings['uploaders'].split(',').map(&:strip)
|
|
110
221
|
end
|