@agung_dhewe/webapps 1.1.2 → 1.2.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.
Files changed (93) hide show
  1. package/lib/fgta5js-dist/fgta5js-v1.8.5.min.js +11 -0
  2. package/lib/fgta5js-dist/fgta5js-v1.8.5.min.js.map +1 -0
  3. package/{libs → lib}/webmodule/module-edit.css +73 -18
  4. package/{libs → lib}/webmodule/module-list.css +13 -0
  5. package/lib/webmodule/module-print.css +28 -0
  6. package/{libs → lib}/webmodule/module.css +13 -6
  7. package/{libs → lib}/webmodule/module.js +14 -4
  8. package/lib/webmodule/pagehelper.mjs +129 -0
  9. package/modules/generator/appgen-io.mjs +153 -76
  10. package/modules/generator/appgen-ui.mjs +234 -167
  11. package/modules/generator/generator-designtemplate-def.html +38 -0
  12. package/modules/generator/generator-designtemplate.html +11 -1492
  13. package/modules/generator/generator.css +103 -65
  14. package/modules/generator/generator.mjs +1 -1
  15. package/modules/generator/generator.svg +98 -0
  16. package/modules/generator/generatorEdit.mjs +43 -35
  17. package/modules/generator/generatorList.mjs +27 -0
  18. package/modules/generator/tpl-designerinfo.html +100 -0
  19. package/modules/generator/tpl-field-checkbox.html +200 -0
  20. package/modules/generator/tpl-field-combobox.html +228 -0
  21. package/modules/generator/tpl-field-datepicker.html +192 -0
  22. package/modules/generator/tpl-field-filebox.html +189 -0
  23. package/modules/generator/tpl-field-numberbox.html +218 -0
  24. package/modules/generator/tpl-field-textbox.html +255 -0
  25. package/modules/generator/tpl-field-timepicker.html +192 -0
  26. package/modules/generator/tpl-searchdesign.html +32 -0
  27. package/modules/generator/tpl-uniquedesign.html +25 -0
  28. package/modules/login/login.css +10 -2
  29. package/package.json +5 -3
  30. package/percobaan/coba-sequencer.js +16 -0
  31. package/src/api.js +12 -9
  32. package/src/apis/generator.api.js +35 -23
  33. package/src/apis/login.api.js +1 -0
  34. package/src/context.js +12 -2
  35. package/src/db.js +58 -32
  36. package/src/generator/createApiModule.js +4 -1
  37. package/src/generator/createIcon.js +24 -2
  38. package/src/generator/createLayoutCss.js +107 -0
  39. package/src/generator/createModuleDetilEditHtml.js +12 -1
  40. package/src/generator/createModuleDetilEditMjs.js +32 -28
  41. package/src/generator/createModuleDetilListHtml.js +14 -7
  42. package/src/generator/createModuleDetilListMjs.js +13 -1
  43. package/src/generator/createModuleHeaderEditHtml.js +13 -1
  44. package/src/generator/createModuleHeaderEditMjs.js +23 -2
  45. package/src/generator/createProgramData.js +3 -2
  46. package/src/generator/createTable.js +45 -38
  47. package/src/generator/helper.js +45 -27
  48. package/src/generator/templates/__rollup-module.ejs +1 -1
  49. package/src/generator/templates/api-module.js.ejs +171 -32
  50. package/src/generator/templates/layout.css.ejs +24 -0
  51. package/src/generator/templates/module-ext.html.ejs +1 -1
  52. package/src/generator/templates/module-ext.mjs.ejs +19 -1
  53. package/src/generator/templates/module.ejs.ejs +8 -0
  54. package/src/generator/templates/module.mjs.ejs +42 -5
  55. package/src/generator/templates/moduleDetilEdit.html.ejs +11 -0
  56. package/src/generator/templates/moduleDetilEdit.mjs.ejs +135 -30
  57. package/src/generator/templates/moduleDetilList.html.ejs +2 -1
  58. package/src/generator/templates/moduleDetilList.mjs.ejs +86 -11
  59. package/src/generator/templates/moduleHeaderEdit.html.ejs +8 -1
  60. package/src/generator/templates/moduleHeaderEdit.mjs.ejs +123 -36
  61. package/src/generator/templates/moduleHeaderList.html.ejs +5 -1
  62. package/src/generator/templates/moduleHeaderList.mjs.ejs +47 -15
  63. package/src/generator/trygenerate.js +18 -2
  64. package/src/generator/worker.js +83 -72
  65. package/src/helper.js +12 -13
  66. package/src/logger.js +12 -12
  67. package/src/notifier.js +29 -0
  68. package/src/routers/generatorApi.js +9 -3
  69. package/src/routers/generatorPage.js +3 -1
  70. package/src/routers/moduleApi.js +1 -1
  71. package/src/routers/modulePage.js +32 -7
  72. package/src/sequencerdoc.js +22 -46
  73. package/src/sequencerline.js +16 -4
  74. package/src/session.js +69 -33
  75. package/src/startup.js +47 -10
  76. package/src/webapps.js +62 -18
  77. package/templates/_lib_debug.ejs +8 -8
  78. package/templates/_lib_production.ejs +2 -2
  79. package/templates/application.page.ejs +39 -6
  80. package/templates/generator.page.ejs +4 -3
  81. package/templates/index.page.ejs +2 -2
  82. package/templates/login.page.ejs +3 -3
  83. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js +0 -11
  84. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js.map +0 -1
  85. package/libs/webmodule/pagehelper.mjs +0 -45
  86. package/modules/generator/generator.png +0 -0
  87. /package/{libs/fgta5js-dist/fgta5js-v1.8.3.min.css → lib/fgta5js-dist/fgta5js-v1.8.5.min.css} +0 -0
  88. /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin-ext.woff2 +0 -0
  89. /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin.woff2 +0 -0
  90. /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin-ext.woff2 +0 -0
  91. /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin.woff2 +0 -0
  92. /package/{libs → lib}/fgta5js-dist/fonts/karla.css +0 -0
  93. /package/{libs → lib}/webmodule/module-footer.css +0 -0
@@ -29,19 +29,22 @@ import { createInfoLogs } from './createInfoLogs.js';
29
29
  import { createInfoRecordExtender } from './createInfoRecordExtender.js';
30
30
  import { createIcon } from './createIcon.js'
31
31
  import { createProgramData } from './createProgramData.js'
32
+ import { createLayoutCss } from './createLayoutCss.js';
32
33
 
33
34
 
34
35
 
35
- const { generator_id, user_id, user_name, ipaddress, jeda } = workerData;
36
+ const { generator_id, user_id, user_name, ipaddress, ModuleDbContract, jeda } = workerData;
36
37
 
37
38
 
38
39
  main(generator_id)
39
40
 
40
41
 
41
42
  async function main(id) {
43
+ const tablename = ModuleDbContract.generator.table
44
+
42
45
  try {
43
- const queryParams = {generator_id: id}
44
- const sql = 'select generator_data from core."generator" where generator_id = \${generator_id}'
46
+ const queryParams = { generator_id: id }
47
+ const sql = `select generator_data from ${tablename} where generator_id = \${generator_id}`
45
48
  const data = await db.one(sql, queryParams);
46
49
 
47
50
 
@@ -50,8 +53,8 @@ async function main(id) {
50
53
 
51
54
 
52
55
  await generate(id, data.generator_data)
53
-
54
-
56
+
57
+
55
58
  } catch (err) {
56
59
  err.message = `Generator Worker: ${err.message}`
57
60
  throw err
@@ -59,14 +62,14 @@ async function main(id) {
59
62
  }
60
63
 
61
64
  async function sleep(s) {
62
- if (s==0) {
65
+ if (s == 0) {
63
66
  return
64
67
  }
65
68
 
66
- return new Promise(lanjut=>{
67
- setTimeout(()=>{
69
+ return new Promise(lanjut => {
70
+ setTimeout(() => {
68
71
  lanjut()
69
- }, s*1000)
72
+ }, s * 1000)
70
73
  })
71
74
  }
72
75
 
@@ -87,9 +90,9 @@ async function generate(id, data) {
87
90
 
88
91
 
89
92
  const context = {
90
- id:id,
93
+ id: id,
91
94
  user_id: user_id,
92
- user_name: user_name,
95
+ user_name: user_name,
93
96
  ipaddress: ipaddress,
94
97
  title: data.title,
95
98
  descr: data.description,
@@ -97,6 +100,7 @@ async function generate(id, data) {
97
100
  appname: data.appname,
98
101
  moduleName: data.name,
99
102
  entities: data.entities,
103
+ actions: data.actions,
100
104
  icon: data.icon,
101
105
  timeGenerated: formattedTime,
102
106
  postMessage: (info) => {
@@ -115,7 +119,7 @@ async function generate(id, data) {
115
119
  const headerItems = entityHeader.Items
116
120
  for (var entityName in context.entities) {
117
121
  // tambahkan jika bukan header
118
- if (entityName!='header') {
122
+ if (entityName != 'header') {
119
123
  const headerPK = structuredClone(headerItems[headerPkFieldName])
120
124
  headerPK.Reference.pk = entityHeader.pk
121
125
  headerPK.Reference.table = entityHeader.table
@@ -132,98 +136,103 @@ async function generate(id, data) {
132
136
  // process.exit(0)
133
137
 
134
138
 
135
- await prepareDirectory(context, {overwrite:true})
139
+ await prepareDirectory(context, { overwrite: true })
136
140
  await sleep(jedaWaktu)
137
141
 
138
142
 
139
-
140
- const iconFileName = await createIcon(context, {overwrite:true})
141
143
 
142
- await createProgramData(context, {iconFileName})
143
-
144
- await createTable(context, {overwrite:true})
145
- await sleep(jedaWaktu)
146
-
147
- await createApiModule(context, {overwrite:true})
144
+ const iconFileName = await createIcon(context, { overwrite: true })
145
+
146
+ await createProgramData(context, { iconFileName })
147
+
148
+ await createTable(context, { overwrite: true })
148
149
  await sleep(jedaWaktu)
149
150
 
150
151
 
151
-
152
- await createModuleRollup(context, {overwrite:true})
152
+
153
+ await createModuleRollup(context, { overwrite: true })
153
154
  await sleep(jedaWaktu)
154
155
 
155
- await createModuleContext(context, {overwrite:true})
156
+ await createModuleContext(context, { overwrite: true })
156
157
  await sleep(jedaWaktu)
157
158
 
158
-
159
159
 
160
- await createModuleEjs(context, {overwrite:true})
160
+
161
+ await createModuleEjs(context, { overwrite: true })
161
162
  await sleep(jedaWaktu)
162
163
 
163
-
164
- await createModuleMjs(context, {overwrite:true, iconFileName})
164
+
165
+ await createModuleMjs(context, { overwrite: true, iconFileName })
165
166
  await sleep(jedaWaktu)
166
167
 
167
168
 
168
169
 
169
170
  // Header
170
- await createModuleHeaderListHtml(context, {overwrite:true})
171
+ await createModuleHeaderListHtml(context, { overwrite: true })
171
172
  await sleep(jedaWaktu)
172
-
173
173
 
174
- await createModuleHeaderListMjs(context, {overwrite:true})
174
+
175
+ await createModuleHeaderListMjs(context, { overwrite: true })
175
176
  await sleep(jedaWaktu)
176
177
 
177
-
178
- await createModuleHeaderEditHtml(context, {overwrite:true})
178
+
179
+ await createModuleHeaderEditHtml(context, { overwrite: true })
179
180
  await sleep(jedaWaktu)
180
181
 
181
-
182
- await createModuleHeaderEditMjs(context, {overwrite:true})
182
+
183
+ await createModuleHeaderEditMjs(context, { overwrite: true })
183
184
  await sleep(jedaWaktu)
184
-
185
185
 
186
-
186
+
187
+
187
188
  // Detils
188
- await createModuleDetilListHtml(context, {overwrite:true})
189
+ await createModuleDetilListHtml(context, { overwrite: true })
189
190
  await sleep(jedaWaktu)
190
191
 
191
- await createModuleDetilListMjs(context, {overwrite:true})
192
+ await createModuleDetilListMjs(context, { overwrite: true })
192
193
  await sleep(jedaWaktu)
193
194
 
194
195
 
195
- await createModuleDetilEditHtml(context, {overwrite:true})
196
+ await createModuleDetilEditHtml(context, { overwrite: true })
196
197
  await sleep(jedaWaktu)
197
-
198
- await createModuleDetilEditMjs(context, {overwrite:true})
198
+
199
+ await createModuleDetilEditMjs(context, { overwrite: true })
199
200
  await sleep(jedaWaktu)
200
-
201
201
 
202
- await createInfoLogs(context, {overwrite:true})
202
+
203
+ await createInfoLogs(context, { overwrite: true })
203
204
  await sleep(jedaWaktu)
204
205
 
205
206
 
206
207
  // Extender
207
- await createApiExtenderModule(context, {overwrite:false})
208
+ await createModuleExtenderHtml(context, { overwrite: false })
208
209
  await sleep(jedaWaktu)
209
210
 
210
- await createModuleExtenderHtml(context, {overwrite:false})
211
+ await createModuleExtenderMjs(context, { overwrite: false })
211
212
  await sleep(jedaWaktu)
212
213
 
213
- await createModuleExtenderMjs(context, {overwrite:false})
214
+ await createInfoAboutExtender(context, { overwrite: false })
214
215
  await sleep(jedaWaktu)
215
216
 
216
- await createInfoAboutExtender(context, {overwrite:false})
217
+ await createInfoRecordExtender(context, { overwrite: false })
217
218
  await sleep(jedaWaktu)
218
219
 
219
- await createInfoRecordExtender(context, {overwrite:false})
220
+
221
+ // Layout CSS
222
+ await createLayoutCss(context, { overwrite: true })
220
223
  await sleep(jedaWaktu)
221
-
222
-
223
224
 
224
225
 
226
+ // Api
227
+
228
+ await createApiExtenderModule(context, { overwrite: false })
229
+ await createApiModule(context, { overwrite: true })
230
+
231
+ context.postMessage({ message: `restarting service` })
232
+ await sleep(1)
233
+
225
234
  // Selesai
226
- context.postMessage({message: `finish`, done:true})
235
+ context.postMessage({ message: `finish`, done: true })
227
236
  } catch (err) {
228
237
  throw err
229
238
  }
@@ -237,7 +246,7 @@ async function prepareDirectory(context) {
237
246
 
238
247
  try {
239
248
 
240
- context.postMessage({message: `preparing directory`})
249
+ context.postMessage({ message: `preparing directory` })
241
250
  // await sleep(1)
242
251
 
243
252
  // cek jika directory project exists
@@ -250,20 +259,20 @@ async function prepareDirectory(context) {
250
259
  const apiDir = path.join(directory, 'src', 'apis')
251
260
  const apiExtenderDir = path.join(apiDir, 'extenders')
252
261
 
253
- const moduleDirExists = await directoryExists(moduleDir)
262
+ const moduleDirExists = await directoryExists(moduleDir)
254
263
  if (!moduleDirExists) {
255
264
  // direktori modul tidak ditemukan, buat dulu
256
- context.postMessage({message: `creating new directory: '${moduleDir}`})
265
+ context.postMessage({ message: `creating new directory: '${moduleDir}` })
257
266
  await mkdir(moduleDir, {});
258
267
  // await sleep(1)
259
268
  }
260
269
 
261
- const apiDirExists = await directoryExists(apiDir)
270
+ const apiDirExists = await directoryExists(apiDir)
262
271
  if (!apiDirExists) {
263
272
  throw new Error(`directory tujuan '${apiDir}' tidak ditemukan`)
264
273
  }
265
274
 
266
- const apiExtenderDirExists = await directoryExists(apiExtenderDir)
275
+ const apiExtenderDirExists = await directoryExists(apiExtenderDir)
267
276
  if (!apiExtenderDirExists) {
268
277
  throw new Error(`directory tujuan '${apiExtenderDir}' tidak ditemukan`)
269
278
  }
@@ -276,7 +285,7 @@ async function prepareDirectory(context) {
276
285
  console.log("\n\n\x1b[1m\x1b[31mERROR\x1b[0m")
277
286
  console.log('Module sudah di lock, tidak bisa digenerate ulang')
278
287
  process.exit(1)
279
- }
288
+ }
280
289
 
281
290
 
282
291
  context.moduleDir = moduleDir
@@ -312,7 +321,7 @@ async function checkEntitiy(context) {
312
321
 
313
322
 
314
323
  // cek appname
315
- if (apps[context.appname]==null) {
324
+ if (apps[context.appname] == null) {
316
325
  throw new Error(`App Name: '${context.appname}' tidak valid. Cek di data apps`)
317
326
  }
318
327
 
@@ -324,15 +333,15 @@ async function checkEntitiy(context) {
324
333
  const entity_table = entity.table
325
334
  const entity_pk = entity.pk
326
335
  const Items = entity.Items
327
-
328
- let pkExists = false
336
+
337
+ let pkExists = false
329
338
 
330
339
  for (let fieldName in Items) {
331
340
  const item = Items[fieldName]
332
341
  const component = item.component
333
342
 
334
343
  // Cek Primary Key
335
- if (fieldName==entity_pk) {
344
+ if (fieldName == entity_pk) {
336
345
  pkExists = true
337
346
  if (!item.showInForm) {
338
347
  throw new Error(`Primary key '${fieldName}' pada entity '${entityName}' harus di embed di form. Apabila ingin menyembunyakannya, gunakan 'hidden' di Container CSS `)
@@ -340,7 +349,7 @@ async function checkEntitiy(context) {
340
349
  }
341
350
 
342
351
  // Cek combobox
343
- if (component=='Combobox') {
352
+ if (component == 'Combobox') {
344
353
  // cek apakah konfig udah bener
345
354
  const reference = item.Reference
346
355
  const table = reference.table.trim()
@@ -350,31 +359,33 @@ async function checkEntitiy(context) {
350
359
  const loaderApiModule = reference.loaderApiModule.trim()
351
360
  const loaderApiPath = reference.loaderApiPath.trim()
352
361
 
353
- if(table=='') {
362
+ if (table == '') {
354
363
  throw new Error(`table reference Combobox '${fieldName}' di entity '${entityName}' tidak boleh kosong`)
355
364
  }
356
365
 
357
- if(pk=='') {
366
+ if (pk == '') {
358
367
  throw new Error(`PK untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak boleh kosong`)
359
368
  }
360
-
361
- if(bindingValue=='') {
369
+
370
+ if (bindingValue == '') {
362
371
  throw new Error(`binding value untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak boleh kosong`)
363
372
  }
364
373
 
365
- if(bindingText=='') {
374
+ if (bindingText == '') {
366
375
  throw new Error(`binding value untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak boleh kosong`)
367
376
  }
368
377
 
369
- if(loaderApiModule=='') {
378
+ if (loaderApiModule == '') {
370
379
  throw new Error(`loader API Name untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak boleh kosong`)
371
380
  }
372
381
 
373
- if (apps[loaderApiModule]==null) {
374
- throw new Error(`loader API Name: '${loaderApiModule}' untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak valid. Cek di data apps`)
382
+ if (apps[loaderApiModule] == null) {
383
+ if (loaderApiModule != '/') {
384
+ throw new Error(`loader API Name: '${loaderApiModule}' untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak valid. Cek di data apps`)
385
+ }
375
386
  }
376
387
 
377
- if(loaderApiPath=='') {
388
+ if (loaderApiPath == '') {
378
389
  throw new Error(`loader API path untuk table reference Combobox '${fieldName}' di entity '${entityName}' tidak boleh kosong`)
379
390
  }
380
391
  }
package/src/helper.js CHANGED
@@ -6,21 +6,20 @@ import context from './context.js'
6
6
 
7
7
 
8
8
  export function kebabToCamel(str) {
9
- return str
10
- .split('-')
11
- .map((part, index) =>
12
- index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
13
- )
14
- .join('');
9
+ return str
10
+ .split('-')
11
+ .map((part, index) =>
12
+ index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
13
+ )
14
+ .join('');
15
15
  }
16
16
 
17
17
 
18
- export async function importApiModule(modulename, options={}) {
18
+ export async function importApiModule(modulename, options = {}) {
19
19
  // jika mode debug,
20
20
  // load api akan selalu dilakukan saat request (tanpa caching)
21
21
 
22
-
23
- const cached = options.cached===true ? true : false
22
+ const cached = context.isApiCached()
24
23
  const apiDir = options.apiDir || path.join('.', 'apis')
25
24
  const apiPath = path.join(apiDir, `${modulename}.api.js`)
26
25
 
@@ -32,11 +31,11 @@ export async function importApiModule(modulename, options={}) {
32
31
  const freshUrl = `${fullPath}?v=${mtime}`;
33
32
  const module = await import(freshUrl);
34
33
 
35
- if (module.default===undefined) {
34
+ if (module.default === undefined) {
36
35
  throw new Error(`modul api '${modulename}' tidak mempunyai default class untuk import`)
37
36
  }
38
37
 
39
- return module.default;
38
+ return module.default;
40
39
  }
41
40
  }
42
41
 
@@ -52,8 +51,8 @@ export async function isFileExists(filepath) {
52
51
  }
53
52
  }
54
53
 
55
- export async function parseTemplate(tplFilePath, variables={}) {
56
- const template = await fs.readFile(tplFilePath, 'utf-8');
54
+ export async function parseTemplate(tplFilePath, variables = {}) {
55
+ const template = await fs.readFile(tplFilePath, 'utf-8');
57
56
  const content = ejs.render(template, variables)
58
57
  return content
59
58
  }
package/src/logger.js CHANGED
@@ -6,25 +6,25 @@ export default new (class {
6
6
  console.log('logger access', modulename, url, errormessage)
7
7
  }
8
8
 
9
-
9
+
10
10
  async log(logdata) {
11
- const { id, user_id, user_name, moduleName, action, tablename, executionTimeMs, remark, metadata, ipaddress=''} = logdata
12
- const sql = `insert into datalog
11
+ const { id, user_id, user_name, moduleName, action, tablename, executionTimeMs, remark, metadata, ipaddress = '' } = logdata
12
+ const sql = `insert into log."datalog"
13
13
  (log_time, log_user_id, log_user_name, log_action, log_ipaddress, log_module, log_table, log_doc_id, log_remark, log_executiontime, log_metadata)
14
14
  values
15
15
  (now(), \${log_user_id}, \${log_user_name}, \${log_action}, \${log_ipaddress}, \${log_module}, \${log_table}, \${log_doc_id}, \${log_remark}, \${log_executiontime}, \${log_metadata})
16
16
  RETURNING log_time
17
17
  `
18
18
  const variable = {
19
- log_user_id: user_id,
20
- log_user_name: user_name,
21
- log_action: action,
22
- log_ipaddress: ipaddress,
23
- log_module: moduleName,
24
- log_table: tablename,
25
- log_doc_id: id,
26
- log_remark: remark,
27
- log_executiontime: executionTimeMs,
19
+ log_user_id: user_id,
20
+ log_user_name: user_name,
21
+ log_action: action,
22
+ log_ipaddress: ipaddress,
23
+ log_module: moduleName,
24
+ log_table: tablename,
25
+ log_doc_id: id,
26
+ log_remark: remark,
27
+ log_executiontime: executionTimeMs,
28
28
  log_metadata: metadata
29
29
  }
30
30
 
@@ -0,0 +1,29 @@
1
+
2
+
3
+ export default async function notifyClient(notifierServer, clientId, status, info) {
4
+ try {
5
+
6
+ const method = 'POST'
7
+ const data = { clientId, status, info }
8
+ const url = `${notifierServer}/notify`
9
+ const response = await fetch(url, {
10
+ method: method,
11
+ headers: {
12
+ 'Content-Type': 'application/json',
13
+ },
14
+ body: JSON.stringify(data)
15
+ });
16
+
17
+ if (!response.ok) {
18
+ const httpErrorStatus = response.status
19
+ const httpErrorStatustext = response.statusText
20
+ const err = new Error(`${httpErrorStatus} ${httpErrorStatustext}: ${method} ${url}`)
21
+ err.code = httpErrorStatus
22
+ throw err
23
+ }
24
+
25
+ return response
26
+ } catch (err) {
27
+ throw err
28
+ }
29
+ }
@@ -1,16 +1,22 @@
1
+ import context from './../context.js'
1
2
  import * as helper from './../helper.js'
2
3
  import { handleError } from './handleError.js'
4
+ import * as path from 'path'
5
+
3
6
 
4
7
  export async function generatorApi(req, res, next) {
5
8
  // res.status(200).send(`{"code":"1", "message":"api not implemented"}`)
6
9
  const moduleName = 'generator'
7
10
  const methodName = req.params.method
8
-
11
+ const options = {
12
+ apiDir: path.join(context.getWebappsDirectory(), 'src', 'apis')
13
+ }
14
+
9
15
  try {
10
16
 
11
- const ModuleClass = await helper.importApiModule(moduleName)
17
+ const ModuleClass = await helper.importApiModule(moduleName, options)
12
18
  const method = helper.kebabToCamel(methodName);
13
- if (ModuleClass===undefined) {
19
+ if (ModuleClass === undefined) {
14
20
  throw new Error(`invalid module: '${moduleName}'`)
15
21
  }
16
22
 
@@ -13,6 +13,7 @@ export async function generatorPage(req, res, next) {
13
13
  const generatorListPath = path.join(__dirname, 'modules', 'generator', 'generatorList.html')
14
14
  const generatorEditPath = path.join(__dirname, 'modules', 'generator', 'generatorEdit.html')
15
15
  const generatorDesignPath = path.join(__dirname, 'modules', 'generator', 'generator-designtemplate.html')
16
+ const generatorModulePath = path.join(__dirname, 'modules', 'generator')
16
17
 
17
18
  // load halaman html-nya
18
19
  const variables = {
@@ -20,7 +21,8 @@ export async function generatorPage(req, res, next) {
20
21
  ...{
21
22
  generatorListPath,
22
23
  generatorEditPath,
23
- generatorDesignPath
24
+ generatorDesignPath,
25
+ generatorModulePath
24
26
  }
25
27
  }
26
28
 
@@ -15,7 +15,7 @@ export async function moduleApi(req, res, next) {
15
15
 
16
16
  const ModuleClass = await helper.importApiModule(moduleName, options)
17
17
  const method = helper.kebabToCamel(methodName);
18
- if (ModuleClass===undefined) {
18
+ if (ModuleClass === undefined) {
19
19
  throw new Error(`invalid module: '${moduleName}'`)
20
20
  }
21
21
 
@@ -24,13 +24,19 @@ export async function modulePage(req, res) {
24
24
  const moduleDir = path.join(__rootDir, 'public', 'modules', moduleName)
25
25
  const ejsPath = path.join(__rootDir, 'public', 'modules', moduleName, `${moduleName}.ejs`)
26
26
  const cssPath = path.join(__rootDir, 'public', 'modules', moduleName, `${moduleName}.css`);
27
+ const cssLayoutPath = path.join(__rootDir, 'public', 'modules', moduleName, `${moduleName}.layout.css`);
28
+ const cssApplicationPath = path.join(__rootDir, 'public', 'local', 'application.css');
29
+
30
+
31
+ const variance = req.query.variance;
32
+ const id = req.query.id;
27
33
 
28
34
 
29
35
  // const mjsFileName = appDebugMode ? `${moduleName}.mjs` : `${moduleName}.min.mjs`
30
36
  let mjsFileName
31
37
  if (appDebugMode) {
32
38
  // Default Debug
33
- if (req.query.mode=='release') {
39
+ if (req.query.mode == 'release') {
34
40
  const version = await getCurrentVersion(path.join(__rootDir, 'public', 'modules', moduleName, 'version.txt'))
35
41
  mjsFileName = `${moduleName}-${version}.min.mjs`
36
42
  } else {
@@ -38,7 +44,7 @@ export async function modulePage(req, res) {
38
44
  }
39
45
  } else {
40
46
  // Default Production
41
- if (req.query.mode=='debug') {
47
+ if (req.query.mode == 'debug') {
42
48
  mjsFileName = `${moduleName}.mjs`
43
49
  } else {
44
50
  const version = await getCurrentVersion(path.join(__rootDir, 'public', 'modules', moduleName, 'version.txt'))
@@ -51,24 +57,33 @@ export async function modulePage(req, res) {
51
57
  const htmlExtenderFile = `${moduleName}-ext.html`
52
58
  const htmlExtenderPath = path.join(__rootDir, 'public', 'modules', moduleName, htmlExtenderFile)
53
59
 
60
+ const iconFileName = `${moduleName}.svg`
61
+ const iconFilePath = path.join(__rootDir, 'public', 'modules', moduleName, iconFileName)
54
62
 
63
+ const cssLayoutExists = await helper.isFileExists(cssLayoutPath)
55
64
  const cssExists = await helper.isFileExists(cssPath)
56
65
  const mjsExists = await helper.isFileExists(mjsPath);
57
66
  const htmlExtenderExists = await helper.isFileExists(htmlExtenderPath);
67
+ const iconFileExists = await helper.isFileExists(iconFilePath);
68
+
69
+ const cssApplicationExists = await helper.isFileExists(cssApplicationPath);
58
70
 
59
71
  const mjsPrerenderPath = path.join(__rootDir, 'public', 'modules', moduleName, `${moduleName}-prerender.mjs`);
60
72
  const mjsPrerenderExists = await helper.isFileExists(mjsPrerenderPath)
61
73
 
62
74
 
63
- const ejsModuleExist = await helper.isFileExists(ejsPath)
75
+ const ejsModuleExist = await helper.isFileExists(ejsPath)
76
+
77
+ const additionalHeaderPath = path.join(__rootDir, 'public', 'modules', moduleName, `_htmlheader.ejs`);
78
+ const additionalHeaderExists = await helper.isFileExists(additionalHeaderPath)
64
79
 
65
80
  try {
66
81
 
67
82
  // coba cek request halaman
68
83
  const fnParseModuleRequest = context.getFnParseModuleRequest()
69
- if (typeof fnParseModuleRequest==='function') {
84
+ if (typeof fnParseModuleRequest === 'function') {
70
85
  await fnParseModuleRequest(req, res)
71
- }
86
+ }
72
87
 
73
88
 
74
89
  // load halaman html-nya
@@ -77,18 +92,28 @@ export async function modulePage(req, res) {
77
92
  err.status = 404
78
93
  throw err
79
94
  }
80
-
81
- const variables = {
95
+
96
+ const variables = {
82
97
  ...helper.createDefaultEjsVariable(req),
83
98
  ...{
99
+ id,
100
+ variance,
84
101
  moduleDir,
85
102
  ejsPath,
86
103
  mjsPrerenderExists,
104
+ cssLayoutExists,
87
105
  cssExists,
88
106
  mjsExists,
89
107
  mjsFileName,
90
108
  htmlExtenderExists,
91
109
  htmlExtenderPath,
110
+ iconFileName,
111
+ iconFileExists,
112
+ additionalHeaderPath,
113
+ additionalHeaderExists,
114
+ cssApplicationPath,
115
+ cssApplicationExists,
116
+ setting: req.app.locals.appConfig
92
117
  }
93
118
  }
94
119