eworld 1.2.2 → 2.0.0
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/core/aws_profile.rb +41 -0
- data/lib/eworld.rb +11 -33
- data/lib/routes/generate.rb +127 -0
- data/lib/routes/scan.rb +42 -6
- data/lib/rules/js/rule_js_parameters.rb +1 -2
- data/lib/scanners/controller_scanner.rb +137 -0
- data/lib/scanners/entity_scanner.rb +15 -0
- data/lib/scanners/permission_scanner.rb +15 -0
- data/lib/scanners/queue_scanner.rb +15 -0
- data/lib/scanners/route_scanner.rb +239 -0
- data/lib/version.rb +1 -1
- data/lib/writers/api_docs_writer.rb +32 -0
- data/lib/writers/base_writer.rb +21 -0
- data/lib/writers/controller_writer.rb +115 -0
- data/lib/writers/entity_writer.rb +15 -0
- data/lib/writers/js_docs_writer.rb +32 -0
- data/lib/writers/permission_writer.rb +15 -0
- data/lib/writers/queue_writer.rb +14 -0
- data/lib/writers/route_writer.rb +56 -0
- data/lib/writers/service_writer.rb +106 -0
- data/opt/config/schema.yml +7 -0
- data/opt/schema/controllers.yml +32 -0
- data/opt/schema/database.yml +0 -0
- data/opt/schema/routes.yml +77 -0
- metadata +24 -7
- data/lib/routes/generate_api_entities.rb +0 -35
- data/lib/routes/generate_ui_routes.rb +0 -41
@@ -0,0 +1,239 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class RouteScanner
|
4
|
+
|
5
|
+
SCHEMA_FILE = "#{EWorld::Opt::get_base_path}#{EWorld::Opt::OPT_PATH}/schema/routes.yml"
|
6
|
+
ROUTES = 'Routes'
|
7
|
+
FULLPATH = 'fullpath'
|
8
|
+
CODE = 'code'
|
9
|
+
PATH = 'path'
|
10
|
+
NAME = 'name'
|
11
|
+
META = 'meta'
|
12
|
+
COMPONENT = 'component'
|
13
|
+
TITLE = 'title'
|
14
|
+
TAB_PARENT = 'tabParent'
|
15
|
+
DISABLED = 'disabled'
|
16
|
+
ICON = 'icon'
|
17
|
+
INVISIBLE = 'invisible'
|
18
|
+
CHILDREN = 'children'
|
19
|
+
HAS_PAGE = 'hasPage'
|
20
|
+
|
21
|
+
# Responsible for scanning the .codegen/routes/routes.yml file.
|
22
|
+
# @return Array
|
23
|
+
def self.scan(project)
|
24
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{project[Blufin::Projects::TYPE]}" unless project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
|
25
|
+
@errors = []
|
26
|
+
@codes = []
|
27
|
+
@files = [] # Holds short version of file name.
|
28
|
+
@files_expected = [] # Holds full-path to file.
|
29
|
+
@files_to_write = [] # Holds list of files that need to be created/stubbed.
|
30
|
+
begin
|
31
|
+
@td = project[Blufin::Projects::TRANSIENT_DATA]
|
32
|
+
@path_root = Blufin::Strings::remove_surrounding_slashes(@td[Blufin::Projects::CG_QUASAR_ROOT])
|
33
|
+
@path_routes_file = Blufin::Strings::remove_surrounding_slashes(@td[Blufin::Projects::CG_QUASAR_ROUTES_FILE])
|
34
|
+
@path_pages = Blufin::Strings::remove_surrounding_slashes(@td[Blufin::Projects::CG_QUASAR_PAGES])
|
35
|
+
@path_pages_ignore = @td[Blufin::Projects::CG_QUASAR_PAGES_IGNORE]
|
36
|
+
@project_path = Blufin::Projects::get_project_path(project[Blufin::Projects::PROJECT_ID])
|
37
|
+
@project_path_inner = Blufin::Projects::get_project_path(project[Blufin::Projects::PROJECT_ID], true)
|
38
|
+
routes_file = "#{@project_path_inner}/#{@path_routes_file}"
|
39
|
+
# Make sure file exists.
|
40
|
+
unless Blufin::Files::file_exists(routes_file)
|
41
|
+
@errors << Blufin::ScannerError::add_error(nil, "File not found: #{Blufin::Terminal::format_invalid(routes_file)}")
|
42
|
+
return {}, @errors
|
43
|
+
end
|
44
|
+
# Extract routes file content so we can parse/validate it.
|
45
|
+
routes_content = []
|
46
|
+
Blufin::Files::read_file(routes_file).each do |line|
|
47
|
+
line = line.gsub("\n", '').gsub(/^\s*const\s*routes\s*=\s*\[/, '{ Routes: [')
|
48
|
+
# Handle component/import lines.
|
49
|
+
if line =~ /^\s*component:\s*\(\)\s*=>\s*import\s*\(['"]\s*@/
|
50
|
+
line = line.gsub(/component:\s*\(\)\s*=>\s*import\s*\(['"]\s*@/, '')
|
51
|
+
line = line.gsub(/['"]\s*\)\s*/, '')
|
52
|
+
comma = (line == line.gsub(/,?\s*$/, '')) ? '' : ','
|
53
|
+
routes_content << "#{line.split('/')[0]}component: '#{line.gsub(/,?\s*$/, '').strip}'#{comma}"
|
54
|
+
next
|
55
|
+
end
|
56
|
+
break if line =~ /^\s*if\s*\(/
|
57
|
+
routes_content << line unless line.strip == ''
|
58
|
+
end
|
59
|
+
# Remove trailing semi-colon.
|
60
|
+
routes_content[routes_content.length - 1] = routes_content[routes_content.length - 1].gsub(/;*\s*$/, '')
|
61
|
+
routes_content << '}'
|
62
|
+
hash = {}
|
63
|
+
eval("hash = #{Blufin::Arrays::convert_line_array_to_string(routes_content)}")
|
64
|
+
json = JSON.parse(hash.to_json)
|
65
|
+
# Create tmp file so we can read it. There might be a better way but no time.
|
66
|
+
tmp_filename = "/tmp/routes-content-#{Blufin::Strings::random_string(2)}.yaml"
|
67
|
+
# Write tmp file.
|
68
|
+
Blufin::Files::write_file(tmp_filename, Blufin::Arrays::convert_string_to_line_array(json.to_yaml))
|
69
|
+
@routes_yml = Blufin::Yml::read_file(tmp_filename, SCHEMA_FILE)
|
70
|
+
@routes_yml[ROUTES].each do |parent|
|
71
|
+
parent_path = parent[PATH]
|
72
|
+
parent_title = parent.has_key?(META) ? parent[META][TITLE] : nil
|
73
|
+
parent_icon = parent.has_key?(META) ? parent[META][ICON] : nil
|
74
|
+
parent_has_page = parent.has_key?(META) ? (parent[META][HAS_PAGE] ? true : false) : false
|
75
|
+
parent_invisible = parent.has_key?(META) ? parent[META][INVISIBLE] : nil
|
76
|
+
error_prefix = "Parent path: #{parent_path} \xe2\x80\x94 "
|
77
|
+
# Make sure HAS_PAGE is only ever false.
|
78
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Unless has_page == true, it is not required.", "has_page: '#{parent_has_page}'") if parent.has_key?(META) && parent[META].has_key?(HAS_PAGE) && !parent_has_page
|
79
|
+
# Make sure we have the correct meta properties for parent (based on invisible property).
|
80
|
+
if parent_invisible
|
81
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Invisible routes shouldn't have: icon") unless parent_icon.nil?
|
82
|
+
else
|
83
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Missing meta property: icon") if parent_icon.nil?
|
84
|
+
end
|
85
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Missing meta property: title") if parent_title.nil?
|
86
|
+
# Make sure properties are in the correct order.
|
87
|
+
expected = {
|
88
|
+
PATH => true,
|
89
|
+
META => false,
|
90
|
+
COMPONENT => true,
|
91
|
+
CHILDREN => false
|
92
|
+
}
|
93
|
+
Blufin::Validate::assert_valid_keys(expected, parent.keys, routes_file)
|
94
|
+
# Make sure meta properties are in the correct order.
|
95
|
+
if parent.has_key?(META)
|
96
|
+
expected = {
|
97
|
+
TITLE => false,
|
98
|
+
ICON => false,
|
99
|
+
HAS_PAGE => false,
|
100
|
+
INVISIBLE => false
|
101
|
+
}
|
102
|
+
Blufin::Validate::assert_valid_keys(expected, parent[META].keys, routes_file)
|
103
|
+
end
|
104
|
+
# Make sure parent path(s) have a preceding slash.
|
105
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Parent path must have preceding slash.") unless parent[PATH] =~ /^\//
|
106
|
+
# Validate children, if they exist.
|
107
|
+
validate_children(parent, Blufin::Strings::remove_surrounding_slashes(parent[PATH]), routes_file, error_prefix) if parent.has_key?(CHILDREN)
|
108
|
+
end
|
109
|
+
|
110
|
+
rescue => e
|
111
|
+
|
112
|
+
Blufin::Terminal::print_exception(e)
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
# Check for rogue files.
|
117
|
+
path_to_pages = "#{@project_path_inner}/#{@path_pages}"
|
118
|
+
Blufin::Files::get_files_in_dir(path_to_pages).each do |file|
|
119
|
+
next if file =~ /#{path_to_pages}\/(#{@path_pages_ignore.join('|')})\/[a-z0-9]/
|
120
|
+
unless @files_expected.include?(file)
|
121
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "Rogue file: #{file}")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
return @files_to_write, @errors
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# Recursive function to validate children.
|
132
|
+
# @return void
|
133
|
+
def self.validate_children(parent, parent_path, routes_file, error_prefix, validate_nested = true)
|
134
|
+
raise RuntimeError, "Expected key: #{CHILDREN}" unless parent.has_key?(CHILDREN)
|
135
|
+
children = parent[CHILDREN]
|
136
|
+
parent_has_page = parent.has_key?(META) ? (parent[META][HAS_PAGE] ? true : false) : false
|
137
|
+
# Make sure we have an array with items.
|
138
|
+
unless children.is_a?(Array) || children.length == 0
|
139
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Children must be an Array and cannot be empty.")
|
140
|
+
return
|
141
|
+
end
|
142
|
+
children.each_with_index do |child, idx|
|
143
|
+
# Make a more direct error prefix.
|
144
|
+
error_prefix = "Route: #{child[NAME]} \xe2\x80\x94 " if child.has_key?(NAME)
|
145
|
+
# Make sure properties are in the correct order.
|
146
|
+
expected = {
|
147
|
+
PATH => true,
|
148
|
+
NAME => true,
|
149
|
+
META => false,
|
150
|
+
COMPONENT => true,
|
151
|
+
CHILDREN => false
|
152
|
+
}
|
153
|
+
Blufin::Validate::assert_valid_keys(expected, child.keys, routes_file)
|
154
|
+
# Make sure meta properties are in the correct order.
|
155
|
+
if child.has_key?(META)
|
156
|
+
expected = {
|
157
|
+
FULLPATH => false,
|
158
|
+
CODE => false,
|
159
|
+
TITLE => false,
|
160
|
+
ICON => false,
|
161
|
+
TAB_PARENT => false,
|
162
|
+
DISABLED => false,
|
163
|
+
}
|
164
|
+
Blufin::Validate::assert_valid_keys(expected, child[META].keys, routes_file)
|
165
|
+
end
|
166
|
+
|
167
|
+
# TODO - If non-tabs, must have FULLPATH, CODE, TITLE
|
168
|
+
# TODO - If tabs, must have ICON, TAB_PARENT
|
169
|
+
|
170
|
+
expected_name = Blufin::Strings::remove_surrounding_slashes("#{parent_path}/#{child[PATH]}").gsub('/', '-')
|
171
|
+
# Handle special case for dashboard.
|
172
|
+
expected_name = 'dashboard' if child[NAME] == 'dashboard' && expected_name.strip == ''
|
173
|
+
expected_file = Blufin::Strings::remove_surrounding_slashes("#{parent_path}/#{child[PATH]}").split('/')
|
174
|
+
raise RuntimeError, "Expected file count should never be greater than 3: #{expected_file.inspect}" if expected_file.length > 3
|
175
|
+
fullpath = '' if expected_file.length == 0
|
176
|
+
fullpath = expected_file[0] if expected_file.length == 1
|
177
|
+
fullpath = "#{expected_file[0]}/#{expected_file[1]}" if expected_file.length == 2
|
178
|
+
fullpath = "#{expected_file[0]}/#{expected_file[1]}/#{expected_file[2]}" if expected_file.length == 3
|
179
|
+
expected_file = '' if expected_file.length == 0
|
180
|
+
expected_file = expected_file[0] if expected_file.length == 1
|
181
|
+
expected_file = "#{expected_file[0]}/#{expected_file[1]}" if expected_file.length == 2
|
182
|
+
expected_file = "#{expected_file[0]}/#{expected_file[1]}-#{expected_file[2]}" if expected_file.length == 3
|
183
|
+
# Check full path is correct.
|
184
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "Expected meta.fullpath: #{fullpath}", "Got meta.fullpath: '#{child[META][FULLPATH]}'") if child[META].has_key?(FULLPATH) && child[META][FULLPATH].strip != fullpath
|
185
|
+
# Check the parent path.
|
186
|
+
if idx == 0
|
187
|
+
if validate_nested
|
188
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}If #{HAS_PAGE} flag is set, 1st child must have empty path.", "path: '#{child[PATH]}'") if parent_has_page && child[PATH] != ''
|
189
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}If #{HAS_PAGE} flag is NOT set, 1st child cannot have empty path.", "path: '#{child[PATH]}'") if !parent_has_page && child[PATH].strip == ''
|
190
|
+
# This handles the root paths, IE: 'dashboard/dashboard.vue'
|
191
|
+
expected_file = "#{expected_name}/#{expected_name}" if parent_has_page
|
192
|
+
else
|
193
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Cannot have empty path.", "path: '#{child[PATH]}'") if child[PATH].strip == ''
|
194
|
+
end
|
195
|
+
else
|
196
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Cannot have empty path.", "path: '#{child[PATH]}'") if child[PATH].strip == ''
|
197
|
+
end
|
198
|
+
expected_file = "/#{@path_pages}/#{Blufin::Strings::remove_surrounding_slashes(expected_file)}.vue"
|
199
|
+
actual_file = "#{@project_path_inner}/#{Blufin::Strings::remove_surrounding_slashes(expected_file)}"
|
200
|
+
# Make sure we don't have any duplicate files.
|
201
|
+
if @files.include?(expected_file)
|
202
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "Duplicate file: #{expected_file}")
|
203
|
+
else
|
204
|
+
@files << expected_file
|
205
|
+
@files_expected << actual_file
|
206
|
+
end
|
207
|
+
|
208
|
+
@files_to_write << actual_file unless Blufin::Files::file_exists(actual_file)
|
209
|
+
|
210
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "Expected name: #{expected_name}", "Got name: '#{child[NAME]}'") if child[NAME].strip != expected_name
|
211
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "Expected component: #{expected_file}", "Got component: '#{child[COMPONENT]}'") if child[COMPONENT].strip != expected_file
|
212
|
+
|
213
|
+
# Make sure there are no duplicate codes.
|
214
|
+
if child[META].has_key?(CODE)
|
215
|
+
code = child[META][CODE]
|
216
|
+
if @codes.include?(code)
|
217
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "Duplicate code: #{code}")
|
218
|
+
else
|
219
|
+
@codes << code
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# Validate nested children (if any).
|
224
|
+
if child.has_key?(CHILDREN)
|
225
|
+
unless validate_nested
|
226
|
+
# This will probably never get hit, but just in case.
|
227
|
+
@errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Cannot go more than 3 levels deep.") unless validate_nested
|
228
|
+
return
|
229
|
+
end
|
230
|
+
validate_children(child, "#{parent_path}/#{child[PATH]}", routes_file, error_prefix, false)
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
data/lib/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
EWORLD_VERSION = '
|
1
|
+
EWORLD_VERSION = '2.0.0'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class ApiDocsWriter < EWorld::BaseWriter
|
4
|
+
|
5
|
+
# Responsible for writing all the spring boot @RestController classes.
|
6
|
+
# @return void
|
7
|
+
def self.write(api_project, ui_project, controllers)
|
8
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_API_SIMPLE}, instead got: #{api_project[Blufin::Projects::TYPE]}" unless api_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_API_SIMPLE
|
9
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{ui_project[Blufin::Projects::TYPE]}" unless ui_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
|
10
|
+
@generated = []
|
11
|
+
@overwritten = []
|
12
|
+
@project_path = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID])
|
13
|
+
@project_path_api = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID], true)
|
14
|
+
@project_path_ui = Blufin::Projects::get_project_path(ui_project[Blufin::Projects::PROJECT_ID], true)
|
15
|
+
@transient_data_api = api_project[Blufin::Projects::TRANSIENT_DATA]
|
16
|
+
@transient_data_ui = ui_project[Blufin::Projects::TRANSIENT_DATA]
|
17
|
+
|
18
|
+
# TODO - This needs better data...
|
19
|
+
@data = controllers
|
20
|
+
|
21
|
+
target_file = "#{@project_path}/#{Blufin::Strings::remove_surrounding_slashes(@transient_data_ui[Blufin::Projects::CG_QUASAR_ROOT])}/#{Blufin::Strings::remove_surrounding_slashes(@transient_data_ui[Blufin::Projects::CG_QUASAR_API_DOCS_FILE])}"
|
22
|
+
|
23
|
+
# Write the file.
|
24
|
+
@overwritten << target_file if Blufin::Files::write_file_if_changed(target_file, Blufin::Arrays::convert_string_to_line_array(JSON.pretty_generate(@data, { indent: ' ' })), write_empty_trailing_line: true)
|
25
|
+
|
26
|
+
return @generated, @overwritten
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class BaseWriter
|
4
|
+
|
5
|
+
PACKAGE = '{{--PACKAGE--}}'
|
6
|
+
CLASS = '{{--CLASS--}}'
|
7
|
+
CLASS_LOWER = '{{--CLASS-LOWER--}}'
|
8
|
+
IMPORTS = '{{--IMPORTS--}}'
|
9
|
+
|
10
|
+
# Generic method to get root path for Controllers/Services in Java.
|
11
|
+
# @return string.
|
12
|
+
def self.get_java_path_for(project_path, path)
|
13
|
+
controller_path = "#{project_path}/#{Blufin::Strings::remove_surrounding_slashes(path)}"
|
14
|
+
controller_path_parent = controller_path.split('/')
|
15
|
+
controller_path_parent.pop
|
16
|
+
"/#{Blufin::Strings::remove_surrounding_slashes(controller_path_parent.join('/'))}"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class ControllerWriter < EWorld::BaseWriter
|
4
|
+
|
5
|
+
PACKAGE_NAME = 'controllers'
|
6
|
+
ROOT_PATH = '{{--ROOT-PATH--}}'
|
7
|
+
METHODS = '{{--METHODS--}}'
|
8
|
+
|
9
|
+
|
10
|
+
# Responsible for writing all the spring boot @RestController classes.
|
11
|
+
# @return void
|
12
|
+
def self.write(api_project, ui_project, controllers)
|
13
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_API_SIMPLE}, instead got: #{api_project[Blufin::Projects::TYPE]}" unless api_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_API_SIMPLE
|
14
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{ui_project[Blufin::Projects::TYPE]}" unless ui_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
|
15
|
+
@generated = []
|
16
|
+
@overwritten = []
|
17
|
+
@project_path = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID])
|
18
|
+
@project_path_api = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID], true)
|
19
|
+
@project_path_ui = Blufin::Projects::get_project_path(ui_project[Blufin::Projects::PROJECT_ID], true)
|
20
|
+
@transient_data_api = api_project[Blufin::Projects::TRANSIENT_DATA]
|
21
|
+
@transient_data_ui = ui_project[Blufin::Projects::TRANSIENT_DATA]
|
22
|
+
@controller_path = "#{EWorld::BaseWriter::get_java_path_for(@project_path, @transient_data_api['ControllerPath'])}/#{PACKAGE_NAME}"
|
23
|
+
|
24
|
+
# Loop controllers.
|
25
|
+
controllers.each { |clazz, data| write_controller(clazz, data) }
|
26
|
+
|
27
|
+
# TODO - REMOVE
|
28
|
+
# puts @transient_data_api.to_yaml
|
29
|
+
# puts @transient_data_ui.to_yaml
|
30
|
+
# puts
|
31
|
+
# puts "\x1B[38;5;154m#{controllers.to_yaml}\x1B[0m"
|
32
|
+
|
33
|
+
return @generated, @overwritten
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Write controllers.
|
40
|
+
# @return void
|
41
|
+
def self.write_controller(clazz, data)
|
42
|
+
|
43
|
+
content = <<TEMPLATE
|
44
|
+
package #{PACKAGE}.api.#{PACKAGE_NAME};
|
45
|
+
|
46
|
+
import #{PACKAGE}.api.system.auth.annotations.Secured;
|
47
|
+
import #{PACKAGE}.api.system.auth.data.Permission;
|
48
|
+
import #{PACKAGE}.api.system.rest.base.AbstractController;
|
49
|
+
import #{PACKAGE}.lib.constants.Constants;
|
50
|
+
import #{PACKAGE}.lib.exceptions.ClientErrorException;
|
51
|
+
import #{PACKAGE}.lib.exceptions.NotImplementedException;
|
52
|
+
import #{PACKAGE}.lib.exceptions.ServerErrorException;
|
53
|
+
import #{PACKAGE}.lib.rest.data.ClientData;
|
54
|
+
import #{PACKAGE}.lib.rest.response.ApiResponseBuilder;
|
55
|
+
import #{PACKAGE}.core.#{EWorld::ServiceWriter::PACKAGE_NAME}.#{CLASS}Service;
|
56
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
57
|
+
import org.springframework.web.bind.annotation.RequestMapping;
|
58
|
+
import org.springframework.web.bind.annotation.RequestParam;
|
59
|
+
import org.springframework.web.bind.annotation.RestController;
|
60
|
+
import org.springframework.http.ResponseEntity;
|
61
|
+
import org.springframework.web.bind.annotation.GetMapping;
|
62
|
+
import org.springframework.web.bind.annotation.PostMapping;
|
63
|
+
import org.springframework.web.bind.annotation.PutMapping;
|
64
|
+
import org.springframework.web.bind.annotation.DeleteMapping;
|
65
|
+
|
66
|
+
import java.io.IOException;
|
67
|
+
import java.util.Arrays;
|
68
|
+
import java.util.List;
|
69
|
+
|
70
|
+
@RestController
|
71
|
+
@RequestMapping("#{ROOT_PATH}")
|
72
|
+
public class #{CLASS}Controller extends AbstractController {
|
73
|
+
|
74
|
+
@Autowired
|
75
|
+
#{CLASS}Service #{CLASS_LOWER}Service;#{METHODS}}
|
76
|
+
TEMPLATE
|
77
|
+
|
78
|
+
methods_output = ''
|
79
|
+
|
80
|
+
# Add all the end-points.
|
81
|
+
if data.has_key?('EndPoints') && data['EndPoints'].is_a?(Array)
|
82
|
+
methods_output = "\n"
|
83
|
+
data['EndPoints'].each do |end_point|
|
84
|
+
method = end_point['Method'].downcase
|
85
|
+
method = method[0].upcase + method[1..-1]
|
86
|
+
path = end_point['Path'].downcase
|
87
|
+
camel_case = Blufin::Strings::snake_case_to_camel_case(path.gsub('-', '_'))
|
88
|
+
method_title = "#{method.downcase}#{camel_case}"
|
89
|
+
methods_output += <<TEMPLATE
|
90
|
+
|
91
|
+
@Secured
|
92
|
+
@#{method}Mapping("#{Blufin::Strings::remove_surrounding_slashes(path)}")
|
93
|
+
public ResponseEntity #{method_title}() {
|
94
|
+
|
95
|
+
return ApiResponseBuilder.ok(#{CLASS_LOWER}Service.#{method_title}());
|
96
|
+
}
|
97
|
+
TEMPLATE
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
content = content.gsub(METHODS, methods_output)
|
102
|
+
content = content.gsub(PACKAGE, @transient_data_api['Package'])
|
103
|
+
content = content.gsub(CLASS, clazz)
|
104
|
+
content = content.gsub(CLASS_LOWER, clazz[0].downcase + clazz[1..-1])
|
105
|
+
content = content.gsub(ROOT_PATH, data['RootPath'])
|
106
|
+
|
107
|
+
file = "#{@controller_path}/#{clazz}Controller.java"
|
108
|
+
|
109
|
+
Blufin::Files::write_file_java(file, Blufin::Arrays::convert_string_to_line_array(content), nil, false)
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class JsDocsWriter < EWorld::BaseWriter
|
4
|
+
|
5
|
+
# Responsible for writing all the spring boot @RestController classes.
|
6
|
+
# @return void
|
7
|
+
def self.write(api_project, ui_project, js_data)
|
8
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_API_SIMPLE}, instead got: #{api_project[Blufin::Projects::TYPE]}" unless api_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_API_SIMPLE
|
9
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{ui_project[Blufin::Projects::TYPE]}" unless ui_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
|
10
|
+
@generated = []
|
11
|
+
@overwritten = []
|
12
|
+
@project_path = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID])
|
13
|
+
@project_path_api = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID], true)
|
14
|
+
@project_path_ui = Blufin::Projects::get_project_path(ui_project[Blufin::Projects::PROJECT_ID], true)
|
15
|
+
@transient_data_api = api_project[Blufin::Projects::TRANSIENT_DATA]
|
16
|
+
@transient_data_ui = ui_project[Blufin::Projects::TRANSIENT_DATA]
|
17
|
+
|
18
|
+
# TODO - This needs better data...
|
19
|
+
@data = js_data
|
20
|
+
|
21
|
+
target_file = "#{@project_path}/#{Blufin::Strings::remove_surrounding_slashes(@transient_data_ui[Blufin::Projects::CG_QUASAR_ROOT])}/#{Blufin::Strings::remove_surrounding_slashes(@transient_data_ui['JsDocsFile'])}"
|
22
|
+
|
23
|
+
# Write the file.
|
24
|
+
@overwritten << target_file if Blufin::Files::write_file_if_changed(target_file, Blufin::Arrays::convert_string_to_line_array(JSON.pretty_generate(@data, { indent: ' ' })), write_empty_trailing_line: true)
|
25
|
+
|
26
|
+
return @generated, @overwritten
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class RouteWriter < EWorld::BaseWriter
|
4
|
+
|
5
|
+
# Responsible for writing the routes.js file.
|
6
|
+
# @return void
|
7
|
+
def self.write(project, files_to_write)
|
8
|
+
|
9
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{project[Blufin::Projects::TYPE]}" unless project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
|
10
|
+
@generated = []
|
11
|
+
@overwritten = []
|
12
|
+
|
13
|
+
begin
|
14
|
+
|
15
|
+
files_to_write.each do |file|
|
16
|
+
Blufin::Files::write_file(file, Blufin::Arrays::convert_string_to_line_array(get_blank_file_content))
|
17
|
+
@generated << file
|
18
|
+
end
|
19
|
+
|
20
|
+
rescue => e
|
21
|
+
|
22
|
+
Blufin::Terminal::print_exception(e)
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
return @generated, @overwritten
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Returns the contents of a blank file.
|
33
|
+
# @return string
|
34
|
+
def self.get_blank_file_content
|
35
|
+
<<TEMPLATE
|
36
|
+
<template>
|
37
|
+
<div>
|
38
|
+
<base-title h="5">{{ $route.meta.title }}</base-title>
|
39
|
+
</div>
|
40
|
+
</template>
|
41
|
+
|
42
|
+
<script>
|
43
|
+
export default {
|
44
|
+
data() {
|
45
|
+
return {};
|
46
|
+
}
|
47
|
+
};
|
48
|
+
</script>
|
49
|
+
|
50
|
+
<style scoped type="text/scss" lang="scss"></style>
|
51
|
+
TEMPLATE
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module EWorld
|
2
|
+
|
3
|
+
class ServiceWriter < EWorld::BaseWriter
|
4
|
+
|
5
|
+
PACKAGE_NAME = 'services'
|
6
|
+
AUTOWIRED = '{{--AUTOWIRED--}}'
|
7
|
+
METHODS = '{{--METHODS--}}'
|
8
|
+
|
9
|
+
# Responsible for writing all the spring boot @RestController classes.
|
10
|
+
# @return void
|
11
|
+
def self.write(api_project, ui_project, controllers)
|
12
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_API_SIMPLE}, instead got: #{api_project[Blufin::Projects::TYPE]}" unless api_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_API_SIMPLE
|
13
|
+
raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{ui_project[Blufin::Projects::TYPE]}" unless ui_project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
|
14
|
+
@generated = []
|
15
|
+
@overwritten = []
|
16
|
+
@project_path = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID])
|
17
|
+
@project_path_api = Blufin::Projects::get_project_path(api_project[Blufin::Projects::PROJECT_ID], true)
|
18
|
+
@project_path_ui = Blufin::Projects::get_project_path(ui_project[Blufin::Projects::PROJECT_ID], true)
|
19
|
+
@transient_data_api = api_project[Blufin::Projects::TRANSIENT_DATA]
|
20
|
+
@transient_data_ui = ui_project[Blufin::Projects::TRANSIENT_DATA]
|
21
|
+
@service_path = "#{EWorld::BaseWriter::get_java_path_for(@project_path, @transient_data_api['ServicePath'])}/#{PACKAGE_NAME}"
|
22
|
+
|
23
|
+
# Loop controllers.
|
24
|
+
controllers.each do |clazz, data|
|
25
|
+
write_java_service(clazz, data)
|
26
|
+
write_axios_service(clazz, data)
|
27
|
+
end
|
28
|
+
|
29
|
+
return @generated, @overwritten
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Write Java services.
|
36
|
+
# @return void
|
37
|
+
def self.write_java_service(clazz, data)
|
38
|
+
|
39
|
+
file = "#{@service_path}/#{clazz}Service.java"
|
40
|
+
|
41
|
+
methods = {}
|
42
|
+
|
43
|
+
# TODO NOW - Here we need to parse in the stuff from the java file scanner.
|
44
|
+
|
45
|
+
autowired_output = ''
|
46
|
+
methods_output = ''
|
47
|
+
|
48
|
+
if data.has_key?('EndPoints') && data['EndPoints'].is_a?(Array)
|
49
|
+
methods_output = "\n"
|
50
|
+
data['EndPoints'].each do |end_point|
|
51
|
+
method = end_point['Method'].downcase
|
52
|
+
method = method[0].upcase + method[1..-1]
|
53
|
+
path = end_point['Path'].downcase
|
54
|
+
camel_case = Blufin::Strings::snake_case_to_camel_case(path.gsub('-', '_'))
|
55
|
+
method_title = "#{method.downcase}#{camel_case}"
|
56
|
+
if methods.has_key?(method_title)
|
57
|
+
|
58
|
+
# TODO - Must scan file here ...
|
59
|
+
|
60
|
+
else
|
61
|
+
|
62
|
+
methods_output += <<TEMPLATE
|
63
|
+
|
64
|
+
public Object #{method_title}() {
|
65
|
+
|
66
|
+
return null;
|
67
|
+
}
|
68
|
+
TEMPLATE
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
methods.each do |method|
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
content = <<TEMPLATE
|
78
|
+
package #{PACKAGE}.core.#{PACKAGE_NAME};
|
79
|
+
|
80
|
+
import gov.hi.dhs.fmm.lib.rest.request.AbstractService;
|
81
|
+
import org.springframework.stereotype.Service;
|
82
|
+
|
83
|
+
@Service
|
84
|
+
public class #{CLASS}Service extends AbstractService {#{AUTOWIRED}#{METHODS}}
|
85
|
+
TEMPLATE
|
86
|
+
|
87
|
+
content = content.gsub(AUTOWIRED, autowired_output)
|
88
|
+
content = content.gsub(METHODS, methods_output)
|
89
|
+
content = content.gsub(PACKAGE, @transient_data_api['Package'])
|
90
|
+
content = content.gsub(CLASS, clazz)
|
91
|
+
|
92
|
+
Blufin::Files::write_file_java(file, Blufin::Arrays::convert_string_to_line_array(content), nil, false)
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
# Write Axios services.
|
97
|
+
# @return void
|
98
|
+
def self.write_axios_service(clazz, data)
|
99
|
+
|
100
|
+
# TODO - Overwrite Axios Service.
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|