samanbayaka 0.0.26 → 0.0.27

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.
package/README.md CHANGED
@@ -436,6 +436,8 @@ SBK_CONFIG_CRED='<your_etcs_user> <your_etcd_pass> <your_etcd_port>' node index.
436
436
  ```
437
437
  or
438
438
  ```bash
439
+ rm -rf node_modules/samanbayaka/ &&cp -r ../../samanbayaka/. node_modules/samanbayaka/ && SBK_CONFIG_CRED='sbk sbk@123 12379' node index.mjs
440
+
439
441
  pm2 stop "$(basename "$PWD")" && rm -rf node_modules/samanbayaka/ &&cp -r ../../samanbayaka/. node_modules/samanbayaka/ && SBK_CONFIG_CRED='sbk sbk@123 12379' pm2 start index.mjs --name "$(basename "$PWD")" --stop-exit-codes 1 --output /var/log/samanbayaka/sbk-out-${HOSTNAME}-$$.log --error /var/log/samanbayaka/sbk-err-${HOSTNAME}-$$.log
440
442
  ```
441
443
  * production
@@ -618,6 +620,8 @@ services:
618
620
  etcdctl --endpoints=http://etcd:2379 --user=root:${ETCD_ROOT_PW} user grant-role msg msg
619
621
 
620
622
  # ---------------------------------------------------------
623
+ etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/sys/yaml/SYS_CONFIGS "$(cat /etcd-data/sysconfig.yml)" || true
624
+
621
625
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/global/envs/REVISION "" || true
622
626
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/global/envs/APP_ENV development || true
623
627
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/global/envs/LOG_LEVEL warn || true
@@ -652,14 +656,12 @@ services:
652
656
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/demo true || true
653
657
 
654
658
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/system true || true
655
- etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/system/envs/PORT 8765 || true
656
- etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/system/envs/BROADCAST_INTERVAL 600000 || true
657
659
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/system/envs/LOG_LEVEL error || true
658
660
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/system/envs/MAX_L1_TTL 0 || true
659
661
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/system/envs/MAX_L2_TTL 0 || true
660
662
 
661
663
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/gateway true || true
662
- etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/gateway/envs/PORT 9876 || true
664
+ etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/gateway/envs/PORT 8765 || true
663
665
 
664
666
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/test true || true
665
667
  etcdctl --endpoints=http://etcd:2379 --user=configadmin:${ETCD_CONFIG_ADMIN_PW} put /config/sbk/members/sms add || true
package/commit-hash.mjs CHANGED
@@ -1 +1 @@
1
- export const COMMIT_HASH = '2a7a879';
1
+ export const COMMIT_HASH = '64e1dcc';
package/config/nats.yml CHANGED
@@ -10,7 +10,6 @@ retryPolicy:
10
10
  delay: 200
11
11
  maxDelay: 3000
12
12
  factor: 2
13
- check: null # err => err && !!err.retryable
14
13
 
15
14
  contextParamsCloning: false
16
15
 
@@ -0,0 +1,24 @@
1
+ # Expose the system API on the specified port
2
+ port: <your_sys_port>
3
+
4
+ # Project description
5
+ projDescription: "{#var#} is a microservices-based project built with moleculer and moleculer-web, designed for scalable, high-performance service communication and API management."
6
+
7
+ # Configuration brodcast interval in miliseconds
8
+ broadcastInterval: 600000 # 10 minitues
9
+
10
+ # The broadcast interval increases by the specified factor after each broadcast,
11
+ # i.e., interval = factor × interval.
12
+ factor: 1.1
13
+
14
+ # Configuration broadcast maximum duration in miliseconds
15
+ maxBroadcastDuration: 86400000 # 24 hours
16
+
17
+ # Expose the API to the domain
18
+ domain: sbk.wbsedcl.in
19
+
20
+ # Directory Path for API Assets
21
+ assetPath: public
22
+
23
+ # URL of Redpanda web client
24
+ redpandaWebUiPath: http://redpanda.web.ui:9080
@@ -7,24 +7,11 @@ import os from "os"
7
7
  import { createRequire } from 'module'
8
8
 
9
9
  import chokidar from "chokidar"
10
- import * as configHld from '#hUti/config-handler.mjs'
11
10
 
12
11
  const __filename = fileURLToPath(import.meta.url)
13
12
  const __dirname = path.dirname(__filename)
14
13
  const require = createRequire(import.meta.url)
15
14
 
16
- /**
17
- * Edge configs
18
- */
19
- const EC_ASSET_PATH = (await configHld.getConfigs(`/config/sbk/edge/asset/path`)) || "public"
20
-
21
-
22
- /**
23
- * Configuration path
24
- * @type {string}
25
- */
26
- const CONFIG_PATH = process.env.SBK_CONFIG_PATH // Environment variable of configuration path
27
-
28
15
 
29
16
  /**
30
17
  * Project absolute path
@@ -50,12 +37,12 @@ const SERVICES_DIR = /node_modules/.test(__dirname)
50
37
  /**
51
38
  * Assets path
52
39
  */
53
- export const assetPath = {
54
- rootFolder: path
40
+ export const absoluteAssetPath = (dirName) => {
41
+ return path
55
42
  .join(
56
43
  ABSOLUTE_PATH,
57
- EC_ASSET_PATH,
58
- ),
44
+ dirName,
45
+ )
59
46
  }
60
47
 
61
48
 
@@ -103,7 +90,7 @@ const pkgMain = readPkg(ABSOLUTE_PATH)
103
90
  * Create and object of name and version
104
91
  * @type {Object}
105
92
  */
106
- export const pkgDtls = {
93
+ export const pkgInfo = {
107
94
  name: pkgMain.name.split('-')[0]
108
95
  .split(" ")
109
96
  .map(word => word.charAt(0).toUpperCase() + word.slice(1))
@@ -113,139 +100,22 @@ export const pkgDtls = {
113
100
  }
114
101
 
115
102
 
116
- // /**
117
- // * OpenAPI configuration
118
- // */
119
- // export const openApiConfig = {
120
- // info: {
121
- // title: pkgDtls.name,
122
- // version: pkgDtls.version,
123
- // summary: CONFIG.openApiInfo[0].summary,
124
- // description: CONFIG.openApiInfo[0].description,
125
- // },
126
- // servers: CONFIG.openApiInfo[0].url,
127
- // }
128
-
129
- // /**
130
- // * Load modules from path as moleculer-repl is only supports cjs files
131
- // * @param {string} directory path
132
- // * @param {RegExp} regx to filter only *.mjs files from service path
133
- // * @return {void}
134
- // */
135
- // export const loadServices = async (broker) => {
136
- // /**
137
- // * Derive the service directory from the server configuration.
138
- // * @type {string}
139
- // */
140
- // const SERVICES_DIR = path
141
- // .join(
142
- // ABSOLUTE_PATH,
143
- // CONFIG.servicesDir,
144
- // serviceName
145
- // )
146
-
147
- // const filePath = path.join(SERVICES_DIR, CONFIG.serviceMain)
148
-
149
- // /**
150
- // * Dynamic import with cache busting
151
- // * @type {object}
152
- // */
153
- // const module = await import(`${pathToFileURL(filePath)}?t=${Date.now()}`)
154
- // const schema = module.default || module
155
-
156
- // if (!schema || typeof schema !== "object" || !schema.name || schema.name != serviceName) {
157
- // const regex = new RegExp(`(\\/${CONFIG.servicesDir}\\/.*)$`)
158
- // const rfPath = pathToFileURL(filePath).href.match(regex)[1]
159
- // await broker.stop()
160
- // broker.logger.fatal('SBKERR ❖', `Service start failed: invalid service name or schema in ${rfPath}`)
161
- // process.exit(0)
162
- // }
163
-
164
- // broker.createService(schema)
165
- // broker.logger.info('SBKMSG ❖', `Hot-realod: ${isHotReloadEnabled ? "ON" : "OFF"}`)
166
-
167
- // const watcher = chokidar.watch(SERVICES_DIR, {
168
- // ignoreInitial: true,
169
- // awaitWriteFinish: {
170
- // stabilityThreshold: 200, // wait 200ms after last change
171
- // pollInterval: 50
172
- // },
173
- // ignored: [
174
- // /(^|[\/\\])\../,
175
- // /~$/,
176
- // /\.swp$/,
177
- // /\.tmp$/
178
- // ]
179
- // })
180
-
181
- // const handleWatchFile = async(wfPath, isUnlink) => {
182
- // const regex = new RegExp(`(\\/${CONFIG.servicesDir}\\/.*)$`)
183
- // const rfPath = pathToFileURL(wfPath).href.match(regex)[1]
184
- // /**
185
- // * Hot Reloading of moleculer services from service path
186
- // */
187
- // if(isHotReloadEnabled){
188
- // if(path.basename(filePath) === path.basename(wfPath)){
189
- // const oldServiceFullName = (broker.services.find(s => s.name === serviceName))?.fullName
190
- // const oldService = broker.getLocalService(oldServiceFullName)
191
-
192
- // if (!isUnlink) {
193
- // try {
194
- // /**
195
- // * Dynamic import with cache busting
196
- // */
197
- // const serviceModule = await import(`${pathToFileURL(filePath)}?t=${Date.now()}`)
198
- // const schema = serviceModule.default || serviceModule
199
-
200
- // if (!schema || typeof schema !== "object" || !schema.name || schema.name != serviceName) {
201
- // broker.logger.error('SBKERR ❖', `Hot-reloading terminated due to an invalid service name or schema for ${filePath}`)
202
- // return
203
- // }
204
-
205
- // /**
206
- // * Remove the already loaded service if it exists.
207
- // */
208
- // if (oldService) {
209
- // await broker.destroyService(oldService)
210
- // }
211
-
212
- // /**
213
- // * Create new service
214
- // */
215
- // broker.createService(schema)
216
- // const newServiceFullName = schema.version === undefined
217
- // ? schema.name
218
- // : `${schema.version}.${schema.name}`
219
- // broker.logger.info('SBKMSG ❖', `Service '${newServiceFullName}' reloaded.`)
220
- // } catch (err) {
221
- // broker.logger.error('SBKERR ❖', `Hot-reloading of service '${newServiceFullName}' failed..`, err)
222
- // }
223
- // } else if (event === "unlink") {
224
- // /**
225
- // * Remove the already loaded service if it exists.
226
- // */
227
- // if (oldService) {
228
- // await broker.destroyService(oldService)
229
- // broker.logger.info('SBKMSG ❖', `Service '${newServiceFullName}' removed.`)
230
- // }
231
- // }
232
- // }
233
- // else {
234
- // broker.logger.warn('SBKWRN ❖',`Changes detected in the file "${rfPath}". Restart required to apply updates.`)
235
- // }
236
-
237
- // }
238
- // else {
239
- // broker.logger.warn('SBKWRN ❖',`Changes detected in the file "${rfPath}". Restart required to apply updates.`)
240
- // }
241
- // }
242
-
243
- // watcher.on("add", (fp) => handleWatchFile(fp, false))
244
- // watcher.on("change", (fp) => handleWatchFile(fp, false))
245
- // watcher.on("unlink", (fp) => handleWatchFile(fp, true))
246
- // }
247
-
248
-
103
+ /**
104
+ * File chage watcher in the service directory
105
+ */
106
+ export const dirWatcher = chokidar.watch(SERVICES_DIR, {
107
+ ignoreInitial: true,
108
+ awaitWriteFinish: {
109
+ stabilityThreshold: 2000, // wait 2000ms after last change
110
+ pollInterval: 50
111
+ },
112
+ ignored: [
113
+ /(^|[\/\\])\../,
114
+ /~$/,
115
+ /\.swp$/,
116
+ /\.tmp$/
117
+ ]
118
+ })
249
119
 
250
120
 
251
121
 
@@ -68,19 +68,6 @@ const formatAjvErrors = (errors, params) => {
68
68
  path,
69
69
  message: `The value '${val}' ${err.message}`
70
70
  }
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
71
  })
72
+
86
73
  }
@@ -24,19 +24,18 @@ export const client = new Etcd3({
24
24
  })
25
25
 
26
26
  /**
27
- * Getting configurations through dynamic loading of ESM modules
28
- * ftom the path defined in environment variable
27
+ * Getting configurations against a Etcd key
29
28
  * @param {string}
30
- * @return {object}
29
+ * @return {object | string}
31
30
  */
32
- export const getConfigs = async (path) => {
31
+ export const getConfigs = async (path, isYaml = false) => {
33
32
  try {
34
- const yamlText = await client.get(path)
33
+ const yamlText = (await client.get(path))?.toString()
35
34
  if ( path.split('/').includes('yaml') ) {
36
- return Object.freeze( YAML.parse(yamlText?.toString()) )
35
+ return isYaml ? yamlText : Object.freeze( YAML.parse( yamlText ) )
37
36
  }
38
37
  else {
39
- return yamlText?.toString()
38
+ return yamlText
40
39
  }
41
40
 
42
41
  } catch (err) {
@@ -44,7 +43,12 @@ export const getConfigs = async (path) => {
44
43
  }
45
44
  }
46
45
 
47
-
46
+ /**
47
+ * Getting all keys having prefix path
48
+ * @param {string} path
49
+ * @param {Boolean} fullPath
50
+ * @return {array}
51
+ */
48
52
  export const getConfigKeys = async (path, fullPath = false) => {
49
53
  try {
50
54
  const entries = await client.getAll()
@@ -60,6 +64,35 @@ export const getConfigKeys = async (path, fullPath = false) => {
60
64
  }
61
65
  }
62
66
 
67
+ /**
68
+ * Create Etcd key with value
69
+ * @param {string} path
70
+ * @param {string} data
71
+ */
72
+ export const putConfig = async(path, data) => {
73
+ await client.put(path)
74
+ .value(data)
75
+ }
76
+
77
+ /**
78
+ * Delete Etcd key
79
+ * @param {string} path
80
+ * @return {string}
81
+ */
82
+ export const delConfig = async(path) => {
83
+ const deletedData = await client
84
+ .delete()
85
+ .key(path)
86
+ .getPrevious()
87
+
88
+ return deletedData.map(item => ({
89
+ ...item,
90
+ key: Buffer.from(item.key).toString("utf8"),
91
+ value: Buffer.from(item.value).toString("utf8"),
92
+ }))
93
+
94
+ }
95
+
63
96
 
64
97
  export const getConfigAll = async (path, fullPath = false) => {
65
98
  try {
@@ -115,8 +148,5 @@ export const watchConfigs = async (path, callback) => {
115
148
 
116
149
  }
117
150
 
118
- export const putConfig = async(path, data) => {
119
- await client.put(path)
120
- .value(data)
121
- }
151
+
122
152
 
@@ -250,7 +250,7 @@ export const ErrorFormatterMW = {
250
250
  return await next(ctx)
251
251
  }
252
252
  catch (err) {
253
- if(!err?.data?.traceId){
253
+ if(!err?.data?.traceId) {
254
254
  const requestID = ctx?.requestID
255
255
  const status = err?.code || 500
256
256
  const type = err?.type || 'INTERNAL_ERROR'
@@ -301,7 +301,7 @@ export const ErrorFormatterMW = {
301
301
  * Ensures all errors include a standard set of fields such as status code,
302
302
  * message, and optional metadata for client consumption.
303
303
  */
304
- export const httpErrorFormatter = (req, res, err)=>{
304
+ export const httpErrorFormatter = (req, res, err)=> {
305
305
  const code = err.code || 500
306
306
  const errorBody = {
307
307
  ...(err?.data || { message: err.message }),
@@ -4,13 +4,13 @@ export const validateGlobalConfigs = async(prefix) => {
4
4
  try{
5
5
  const nodeVer = errHdl.checkMinNoveVer()
6
6
  const configHdl = await import("./config-handler.mjs")
7
- const { serviceDtls } = await import("#hFil/esm-loading.mjs")
7
+ const { serviceDtls, dirWatcher } = await import("#hFil/esm-loading.mjs")
8
8
  const globalConfigs = await configHdl.getConfigAll(prefix)
9
9
 
10
10
 
11
11
  const isServiceRemoved = (((await configHdl.getConfigs( `/config/sbk/members/${serviceDtls.name}` )) || "false") == "false")
12
12
  if ( serviceDtls.name != "samanbayaka" && isServiceRemoved ) {
13
- throw new Error (`The service "${serviceDtls.name}" is not in the trusted list. Please contact your CONFIGADMIN for assistance.`)
13
+ throw new Error (`The service "${serviceDtls.name}" is disallowed by CONFIGADMIN.`)
14
14
  }
15
15
 
16
16
  return Object.freeze({
@@ -22,6 +22,7 @@ export const validateGlobalConfigs = async(prefix) => {
22
22
  telemetry: errHdl.validateTelemetry(globalConfigs?.TELEMETRY),
23
23
  configRevision: errHdl.validateConfRevision(globalConfigs?.REVISION),
24
24
  serviceDtls,
25
+ dirWatcher,
25
26
  hostEntry: {
26
27
  nats: await errHdl.validateHostEntry('nats'),
27
28
  redis: await errHdl.validateHostEntry('redis'),
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Generate Moleculer params definitions from the OpenAPI schema to enable request parameter validation using AJV
3
+ * @param {object} schema
4
+ */
5
+ export const openApiToMoleculerParams = (schema) => {
6
+ if( schema?.openapi?.parameters || schema?.openapi?.requestBody ){
7
+ schema.params = {
8
+ type: "object",
9
+ properties: {
10
+ params: {
11
+ type: "object",
12
+ properties: {
13
+ },
14
+ required: [],
15
+ additionalProperties: false,
16
+ },
17
+ query: {
18
+ type: "object",
19
+ properties: {
20
+
21
+ },
22
+ required: [],
23
+ },
24
+ body: {}
25
+ },
26
+ required:[],
27
+ additionalProperties: false,
28
+ }
29
+
30
+
31
+ if( schema?.openapi?.requestBody?.required ){
32
+ schema.params.required.push("body")
33
+ }
34
+
35
+ if( schema?.openapi?.requestBody && schema?.openapi?.requestBody?.content ){
36
+ schema.params.properties.body.anyOf = Object.entries(schema?.openapi?.requestBody?.content)
37
+ .map(el=>el[1].schema)
38
+
39
+ }
40
+
41
+ if( schema?.openapi?.parameters ) {
42
+ schema.params.properties.params.properties = schema?.openapi?.parameters
43
+ .filter(el=> el.in == "path")
44
+ .reduce((obj, item) => {
45
+ obj[item.name] = item.schema
46
+ return obj
47
+ }, {})
48
+ schema.params.properties.params.required = Object.keys(schema.params.properties.params.properties)
49
+
50
+ if( schema.params.properties.params.required.length > 0 ){
51
+ schema.params.required.push("params")
52
+ }
53
+
54
+ schema.params.properties.query.properties = schema?.openapi?.parameters
55
+ .filter(el=> el.in == "query").reduce((obj, item) => {
56
+ obj[item.name] = item.schema
57
+ return obj
58
+ }, {})
59
+
60
+ if( Object.keys(schema.params.properties.query.properties).length > 0 ){
61
+ schema.params.required.push("query")
62
+ }
63
+
64
+ schema.params.properties.query.required = schema?.openapi?.parameters
65
+ .filter(el=> el.in == "query")
66
+ .filter(el => el.required)
67
+ .map(el => el.name )
68
+ }
69
+ }
70
+
71
+ }
package/index.mjs CHANGED
@@ -10,6 +10,7 @@ import HybridCacher from "#hMol/HybridCacher.mjs"
10
10
 
11
11
  import { gracefulShutdown, validateServiceName, ErrorFormatterMW } from '#hUti/error-handler.mjs'
12
12
  import { createOpenTelemetryExporters, OpenTelemetryMW } from '#hUti/telemetry.mjs'
13
+ import { openApiToMoleculerParams } from '#hUti/openapi-to-mol-params.mjs'
13
14
 
14
15
  /**
15
16
  * Global Configs
@@ -137,6 +138,18 @@ const createSbkServices = async(schemas, isREPL = false) => {
137
138
  ...configRevisionListner
138
139
  }
139
140
 
141
+ /**
142
+ * Override params according to the OpenAPI schema definition
143
+ */
144
+ if( schema?.actions ) {
145
+ Object.keys(schema.actions).map((el) => {
146
+ if( schema.actions[el] ){
147
+ openApiToMoleculerParams(schema.actions[el])
148
+
149
+ }
150
+ })
151
+ }
152
+
140
153
  if( index == 0 ) validateServiceName(schema, SBK_GLOBAL_CONFIGS.serviceDtls.name)
141
154
  broker.createService(schema)
142
155
  }
@@ -156,6 +169,17 @@ const createSbkServices = async(schemas, isREPL = false) => {
156
169
  }
157
170
 
158
171
 
172
+ /**
173
+ * Notify on changes to files in the service directory.
174
+ */
175
+ SBK_GLOBAL_CONFIGS.dirWatcher.on("add", (fp) => {
176
+ broker.logger.warn({message: `The new file "${fp}" has been added to your service folder. Restart your service for the changes to take effect.`})
177
+ })
178
+ SBK_GLOBAL_CONFIGS.dirWatcher.on("change", (fp) => {
179
+ broker.logger.warn({message: `The file "${fp}" in your service folder has been modified. Restart your service for the changes to take effect.`})
180
+ })
181
+
182
+
159
183
  /**
160
184
  * Listen for force stop signals
161
185
  */
@@ -194,7 +218,6 @@ export default {
194
218
  * Loading Demo
195
219
  */
196
220
  createDemo: async() => {
197
- const { default: about } = await import('#sAbt/index.mjs')
198
221
  const { default: apiGateway } = await import('#sApi/index.mjs')
199
222
  const demo = await import('#sDmo/index.mjs')
200
223
 
@@ -207,7 +230,6 @@ export default {
207
230
  })
208
231
  createSbkServices([
209
232
  gtWy,
210
- about,
211
233
  demo.user,
212
234
  demo.role,
213
235
  demo.mail,
@@ -227,9 +249,8 @@ export default {
227
249
  },
228
250
 
229
251
  registerEdgeAPI: async () => {
230
- const { default: about } = await import('#sAbt/index.mjs')
231
252
  const { default: apiGateway } = await import('#sApi/index.mjs')
232
- createSbkServices([apiGateway, about])
253
+ createSbkServices(apiGateway)
233
254
 
234
255
  },
235
256
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samanbayaka",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "description": "Moleculer Gateway service with kafka transporter",
5
5
  "homepage": "https://gitlab.com/dalal.suvendu/samanbayaka#readme",
6
6
  "bugs": {
@@ -40,6 +40,7 @@
40
40
  "@opentelemetry/semantic-conventions": "^1.40.0",
41
41
  "ajv": "^8.18.0",
42
42
  "approve-builds": "^1.0.0",
43
+ "body-parser": "^2.3.0",
43
44
  "chokidar": "^5.0.0",
44
45
  "compression": "^1.8.1",
45
46
  "cookie-parser": "^1.4.7",
@@ -1,4 +1,3 @@
1
- ```html
2
1
  <!DOCTYPE html>
3
2
  <html lang="en">
4
3
  <head>
@@ -624,4 +623,3 @@ Promise.all([
624
623
 
625
624
  </body>
626
625
  </html>
627
- ```
@@ -0,0 +1,27 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Scalar API Reference</title>
5
+ <meta charset="utf-8" />
6
+ <meta
7
+ name="viewport"
8
+ content="width=device-width, initial-scale=1" />
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app"></div>
13
+
14
+ <!-- Load the Script -->
15
+ <script src="./js/standalone.js"></script>
16
+
17
+ <!-- Initialize the Scalar API Reference -->
18
+ <script>
19
+ Scalar.createApiReference('#app', {
20
+ // The URL of the OpenAPI/Swagger document
21
+ url: '../sbk/system/docs/openapi/json',
22
+ // Avoid CORS issues
23
+ // proxyUrl: 'https://proxy.scalar.com',
24
+ })
25
+ </script>
26
+ </body>
27
+ </html>
@@ -21,7 +21,8 @@ export default {
21
21
  },
22
22
 
23
23
  handler: async(ctx) => {
24
- return `Welcome to ${pkgDtls.name} is a microservices-based project built with moleculer and moleculer-web, designed for scalable, high-performance service communication and API management.`
24
+ return ctx.call("system.projDesc")
25
+ // return `${pkgDtls.name} is a microservices-based project built with moleculer and moleculer-web, designed for scalable, high-performance service communication and API management.`
25
26
  },
26
27
  },
27
28
  version: {