corebasic 1.0.229 → 1.0.231

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/libs/kafka.ts CHANGED
@@ -4,12 +4,73 @@ import { Kafka, logLevel as KafkaLogLevel, CompressionTypes as KafkaCompressionT
4
4
  export const logLevel = KafkaLogLevel
5
5
  export const CompressionTypes = KafkaCompressionTypes
6
6
 
7
- let kafka, producer, admin
8
7
 
9
- let appName
8
+ type KafkaCallback = (topic: string, message: unknown, partition: number) => unknown | Promise<unknown>
9
+
10
+ type KafkaConsumer = {
11
+ connect: () => Promise<void>
12
+ subscribe: (arg: {topic: string; fromBeginning: boolean}) => Promise<void>
13
+ run: (arg: {
14
+ autoCommit: boolean
15
+ eachMessage: (arg: {
16
+ topic: string
17
+ partition: number
18
+ message: {
19
+ value: string | Buffer | null
20
+ offset: string
21
+ }
22
+ }) => Promise<void>
23
+ }) => Promise<void>
24
+ commitOffsets: (offsets: {topic: string; partition: number; offset: string}[]) => Promise<void>
25
+ }
26
+
27
+ type KafkaProducer = {
28
+ connect: () => Promise<void>
29
+ send: (arg: unknown) => Promise<unknown>
30
+ }
31
+
32
+ type KafkaAdmin = {
33
+ createTopics: (arg: {
34
+ topics: {
35
+ topic: string
36
+ numPartitions: number
37
+ replicationFactor: number
38
+ }[]
39
+ }) => Promise<unknown>
40
+ }
41
+
42
+ type KafkaClient = {
43
+ consumer: (arg: {groupId: string}) => KafkaConsumer
44
+ producer: (arg: {allowAutoTopicCreation: boolean}) => KafkaProducer
45
+ admin: () => KafkaAdmin
46
+ }
47
+
48
+ type KafkaStartArg = {
49
+ clientId?: string
50
+ brokers?: string[]
51
+ sasl?: false | {
52
+ mechanism: string
53
+ username?: string
54
+ password?: string
55
+ }
56
+ logLevel?: unknown
57
+ }
58
+
59
+
60
+ let kafka: KafkaClient
61
+ let producer: KafkaProducer
62
+ let admin: KafkaAdmin
63
+
64
+ let appName: string
10
65
  let topicPrefix = ''
11
66
 
12
- export const start = (arg) => {
67
+ declare global {
68
+ var app: {
69
+ name?: string
70
+ } | undefined
71
+ }
72
+
73
+ export const start = (arg?: KafkaStartArg) => {
13
74
  arg = !arg && !process.env.APP_DEPLOYMENT_NAME ? { clientId: (global.app?.name ?? 'app') + '-dev', brokers: ['127.0.0.1:9092'], sasl: false, logLevel: logLevel.ERROR } : arg
14
75
  appName = arg?.clientId ?? (process.env.APP_DEPLOYMENT_NAME ?? (global.app?.name ?? 'app'))
15
76
  topicPrefix = `${appName}.`
@@ -28,7 +89,7 @@ export const start = (arg) => {
28
89
  }
29
90
 
30
91
 
31
- export const createTopic = async (topic, partition, replicas) => {
92
+ export const createTopic = async (topic: string, partition?: number, replicas?: number) => {
32
93
  topic = topicPrefix + topic
33
94
  return await admin.createTopics({ topics: [{topic, numPartitions: partition ?? 1, replicationFactor: replicas ?? 1}] })
34
95
  }
@@ -39,7 +100,7 @@ export const createTopic = async (topic, partition, replicas) => {
39
100
 
40
101
  let consumers = []
41
102
 
42
- const start_consumer = async function (topic, groupId, callback?: Function) {
103
+ const start_consumer = async function (topic: string, groupId: string | KafkaCallback, callback?: KafkaCallback) {
43
104
  callback = typeof groupId === "string" ? callback : groupId
44
105
  groupId = typeof groupId === "string" ? `${appName}.${groupId}` : `${appName}.${topic}`
45
106
 
@@ -49,15 +110,17 @@ const start_consumer = async function (topic, groupId, callback?: Function) {
49
110
  await consumer.connect()
50
111
  await consumer.subscribe({ topic: topic, fromBeginning: true })
51
112
 
113
+ const fn = callback!
114
+
52
115
  await consumer.run({
53
116
  autoCommit: false,
54
117
  eachMessage: async ({ topic, partition, message }) => {
55
- // callback(topic, message.value.toString(), partition) // toString() returns array so won't parse if json.
118
+ // fn(topic, message.value.toString(), partition) // toString() returns array so won't parse if json.
56
119
  let success
57
120
  try {
58
- success = await callback(topic, JSON.parse(message.value), partition)
121
+ success = await fn(topic, JSON.parse(message.value as string), partition)
59
122
  } catch (ex) {
60
- success = await callback(topic, message.value, partition)
123
+ success = await fn(topic, message.value, partition)
61
124
  }
62
125
 
63
126
  await consumer.commitOffsets([{ topic, partition, offset: (Number(message.offset) + 1).toString() }]);
@@ -71,7 +134,7 @@ const start_consumer = async function (topic, groupId, callback?: Function) {
71
134
  // Producer
72
135
  // ===========
73
136
  let producerInvoked = false
74
- const start_producer = async function (topic, message, key, options) {
137
+ const start_producer = async function (topic: string, message: object, key: string, options?: object) {
75
138
 
76
139
  let isJson = Object.prototype.toString.call(message) === '[object Object]' || Object.prototype.toString.call(message) === '[object Array]'
77
140
 
@@ -97,13 +160,13 @@ const start_producer = async function (topic, message, key, options) {
97
160
  // start_consumer('quickstart-events')
98
161
  // start_producer('quickstart-events', 'Hello KafkaJS user! Little')
99
162
 
100
- export const receive = async function(topic, groupId, callback?: Function) {
163
+ export const receive = async function(topic: string, groupId: string, callback?: KafkaCallback) {
101
164
  topic = topicPrefix + topic
102
165
  return (await start_consumer(topic, groupId, callback))
103
166
  }
104
167
 
105
168
 
106
- export const send = async function(topic, message, key, options) {
169
+ export const send = async function(topic: string, message: object, key: string, options?: object) {
107
170
  topic = topicPrefix + topic
108
171
  await start_producer(topic, message, key, options)
109
172
  }
package/libs/messaging.ts CHANGED
@@ -9,24 +9,85 @@ import { createClient } from 'redis';
9
9
  const url = process.env.REDIS_URL || "redis://localhost:6380"
10
10
 
11
11
  // url: 'redis://alice:foobared@localhost:6380'
12
- let consumer, publisher
13
12
 
14
13
 
14
+ type RedisListener = (message: string, channel: string) => void
15
15
 
16
- let users_pool = {
16
+ type RedisConsumer = {
17
+ connect: () => Promise<void>
18
+ subscribe: (channel: string, listener: RedisListener) => Promise<void>
19
+ unsubscribe: (channel: string, listener: RedisListener) => Promise<void>
20
+ on: (event: string, listener: (err: unknown) => void) => void
21
+ }
22
+
23
+ type RedisPublisher = {
24
+ connect: () => Promise<void>
25
+ publish: (channel: string, message: string) => Promise<unknown>
26
+ }
27
+
28
+ type Request = {
29
+ body: {
30
+ client: string
31
+ }
32
+ params: {
33
+ user: string
34
+ }
35
+ on: (event: string, listener: () => void | Promise<void>) => void
36
+ }
37
+
38
+ type Response = {
39
+ writeHead: (status: number, headers: Record<string, string>) => void
40
+ write: (data: string) => void
41
+ flush?: () => void
42
+ end: () => void
43
+ json: (body: unknown) => void
44
+ }
45
+
46
+ type UserRequest = {
47
+ req: Request
48
+ res: Response
49
+ uid: string
50
+ }
17
51
 
52
+ type UserListeners = {
53
+ count: number
54
+ [uid: string]: number | RedisListener
18
55
  }
19
56
 
20
- async function disconnect(user, uid) {
57
+ type UserPool = {
58
+ reqres: UserRequest[]
59
+ listeners: UserListeners
60
+ }
61
+
62
+ type ExpressApp = {
63
+ get: (
64
+ path: string,
65
+ handler: (req: Request, res: Response) => Promise<void>
66
+ ) => unknown
67
+ }
68
+
69
+
70
+ let consumer: RedisConsumer
71
+ let publisher: RedisPublisher
72
+
73
+
74
+ let users_pool: Record<string, UserPool> = {}
75
+
76
+
77
+ async function disconnect(user: string, uid: string) {
21
78
  if (!users_pool[user])
22
79
  return
23
80
 
24
- let [{res}] = users_pool[user].reqres.filter(item => item.uid === uid).concat([{}])
25
- res.end()
81
+
82
+ let res_items = users_pool[user].reqres.filter(item => item.uid === uid)
83
+ if (res_items) {
84
+ const res = res_items[0]!.res
85
+ res.end()
86
+ }
26
87
 
27
88
  if (users_pool[user].listeners[uid]) {
28
89
  if (users_pool[user].listeners.count == 1)
29
- await consumer.unsubscribe(user, users_pool[user].listeners[uid]);
90
+ await consumer.unsubscribe(user, users_pool[user].listeners[uid] as RedisListener);
30
91
  users_pool[user].listeners.count --
31
92
  }
32
93
  users_pool[user].reqres = users_pool[user].reqres.filter(item => item.uid !== uid)
@@ -36,9 +97,9 @@ async function disconnect(user, uid) {
36
97
 
37
98
  // await consumer.unsubscribe(user);
38
99
  }
39
- async function connect({user,req,res, uid}) {
100
+ async function connect({user, req, res, uid}: {user: string, req: Request, res: Response, uid: string}) {
40
101
  res.writeHead(200, {'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive'})
41
- const listener = (message, channel) => {
102
+ const listener = (message: string, channel: string) => {
42
103
  if (users_pool[user]) {
43
104
  try {message = JSON.parse(message)} catch {}
44
105
  for (let {req, res} of users_pool[user].reqres) {
@@ -56,7 +117,7 @@ async function connect({user,req,res, uid}) {
56
117
  users_pool[user].listeners.count ++
57
118
  }
58
119
 
59
- export async function start(app) {
120
+ export async function start(app: ExpressApp) {
60
121
  consumer = createClient({ url });
61
122
  await consumer.connect();
62
123
  publisher = createClient({ url });
@@ -79,7 +140,7 @@ export async function start(app) {
79
140
  }
80
141
 
81
142
 
82
- export async function publish(channel, message) {
143
+ export async function publish(channel: string, message: object | string) {
83
144
  if (publisher && !Utils.isEmpty(channel)) {
84
145
  try {
85
146
  await publisher.publish(channel, typeof message === "object" ? JSON.stringify(message) : message)
@@ -108,44 +169,44 @@ export async function newProducer() {
108
169
  let defaultConsumer = await newConsumer()
109
170
  let defaultProducer = await newProducer()
110
171
 
111
- export async function subscribe(channel, listener) {
172
+ export async function subscribe(channel: string, listener: RedisListener) {
112
173
  await defaultConsumer.subscribe(channel, listener)
113
174
  }
114
175
 
115
- export async function produce(channel, message) {
176
+ export async function produce(channel: string, message: string) {
116
177
  await defaultProducer.publish(channel, message)
117
178
  }
118
179
 
119
180
 
120
181
  let defaultSetGetConsumer = await newConsumer()
121
182
 
122
- export async function set(key, value) {
183
+ export async function set(key: string, value: object | string | number) {
123
184
  await defaultSetGetConsumer.set(`${process.env.REDIS_CHANNEL_PREFIX}_${key}`, typeof value === 'object' ? JSON.stringify(value) : value)
124
185
  }
125
- export async function get(key) {
186
+ export async function get(key: string) {
126
187
  let value = await defaultSetGetConsumer.get(`${process.env.REDIS_CHANNEL_PREFIX}_${key}`)
127
188
  try { value = JSON.parse(value) } catch(err) { }
128
189
  return value
129
190
  }
130
- export async function del(key) {
191
+ export async function del(key: string) {
131
192
  await defaultSetGetConsumer.del(`${process.env.REDIS_CHANNEL_PREFIX}_${key}`)
132
193
  }
133
194
 
134
- export async function hset(key, subkey, value) {
195
+ export async function hset(key: string, subkey: string, value: object | string | number) {
135
196
  await defaultSetGetConsumer.HSET(`${process.env.REDIS_CHANNEL_PREFIX}_${key}`, subkey, typeof value === 'object' ? JSON.stringify(value) : value)
136
197
  }
137
- export async function hget(key, subkey) {
198
+ export async function hget(key: string, subkey: string) {
138
199
  let value = await defaultSetGetConsumer.HGET(`${process.env.REDIS_CHANNEL_PREFIX}_${key}`, subkey)
139
200
  try { value = JSON.parse(value) } catch(err) { }
140
201
  return value
141
202
  }
142
- export async function hdel(key, subkey) {
203
+ export async function hdel(key: string, subkey: string) {
143
204
  await defaultSetGetConsumer.HDEL(`${process.env.REDIS_CHANNEL_PREFIX}_${key}`, subkey)
144
205
  }
145
206
 
146
207
  // Hydrate
147
208
 
148
- export async function hydrate(callback) {
209
+ export async function hydrate(callback: () => Promise<{user: string, company: string, items: any[]}>) {
149
210
  setTimeout(async () => {
150
211
  let {user,company,items} = await callback()
151
212
  await publish(user, {event: "RPC_hydrate", data: { company, items }, txn: Utils.uid() })
package/libs/session.ts CHANGED
@@ -3,7 +3,17 @@ import * as Features from './features.ts'
3
3
  // @ts-ignore
4
4
  import jwt from 'jsonwebtoken'
5
5
 
6
- let app
6
+ type Req = { header: (h: string) => string; path: string; url: string; body: { staff: string; company: string; outlet: string; app: string; feature: string; } }
7
+ type Res = { json: (body: unknown) => unknown; status: (code: number) => { json: (body: unknown) => unknown };}
8
+ type Next = () => void;
9
+ type Use = (req: Req, res: Res, next: Next) => Promise<void>
10
+
11
+ type ReqRefreshToken = { body: { userId: string; clientId: string; refreshToken: string } }
12
+ type ResRefreshToken = { json: (body: unknown) => unknown; status: (code: number) => { json: (body: unknown) => unknown };}
13
+
14
+ type ExpressApp = {use: (fn: Use) => void, post: (route: string, callback: (req: ReqRefreshToken, res: ResRefreshToken) => void) => void}
15
+
16
+ let app: ExpressApp
7
17
 
8
18
 
9
19
 
@@ -15,16 +25,15 @@ const DEPLOY_TOKEN_SECRET = process.env.DEPLOY_TOKEN_SECRET || "MY_SECRET_DEPLOY
15
25
 
16
26
  const NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN_SECRET = process.env.NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN_PUBLIC_KEY
17
27
 
18
- let urlsAllowed = []
19
- export var ALLOWED_URLS = []
28
+ let urlsAllowed: string[] = []
29
+ export let ALLOWED_URLS: string[] = []
20
30
 
21
- export const start = (expressApp, allowedUrls) => {
31
+ export const start = (expressApp: ExpressApp, allowedUrls: string[]) => {
22
32
  urlsAllowed = ["/refreshToken", "/login"].concat(allowedUrls ?? [])
23
33
  ALLOWED_URLS = urlsAllowed
24
34
  app = expressApp
25
35
 
26
-
27
- app.use(async (req, res, next) => {
36
+ app.use(async (req: Req, res: Res, next: Next) => {
28
37
 
29
38
  // return next() // Disable session
30
39
 
@@ -33,7 +42,7 @@ export const start = (expressApp, allowedUrls) => {
33
42
  if (urlsAllowed.includes(req.path))
34
43
  return next()
35
44
 
36
- const checkPrivilege = async req => {
45
+ const checkPrivilege = async (req: Req) => {
37
46
  const staff = Utils.isEmpty(req.body.staff) ? 'BLANK_STAFF' : req.body.staff
38
47
  const granted = (await Features.send({company: req.body.company, outlet: req.body.outlet, app: req.body.app}, "privileges.query.check", {feature: req.body.feature }, {id: staff})).data.granted
39
48
  if (!granted)
@@ -71,11 +80,13 @@ export const start = (expressApp, allowedUrls) => {
71
80
  return next()
72
81
  throw null;
73
82
  } catch (error) {
74
- return res.status(401).json({ message: error?.message === "Access Denied" ? error.message : 'Unauthorized' })
83
+ type ErrorType = { message?: string }
84
+ res.status(401).json({ message: (error as ErrorType)?.message === "Access Denied" ? "Access Denied" : 'Unauthorized' })
75
85
  }
76
86
  })
77
87
 
78
- app.post("/refreshToken", (req, res) => {
88
+
89
+ app.post("/refreshToken", (req: ReqRefreshToken, res: ResRefreshToken) => {
79
90
  try {
80
91
  let { userId, clientId, refreshToken } = req.body
81
92
  type Decoded = {userId: string, clientId: string}
@@ -101,7 +112,7 @@ export const start = (expressApp, allowedUrls) => {
101
112
  }
102
113
 
103
114
 
104
- export const generateAccessToken = (userId, clientId) => {
115
+ export const generateAccessToken = (userId: string, clientId: string) => {
105
116
  let data = { userId, clientId }
106
117
 
107
118
  let now = Utils.now()
package/libs/utils.ts CHANGED
@@ -124,7 +124,7 @@ export function toDate(arg: string, currentTime?: boolean): Date | undefined { /
124
124
 
125
125
 
126
126
  export function getDatesBetweenTwoDates(start: number | Date, end: number | Date) {
127
- let arr = [];
127
+ let arr: Date[] = [];
128
128
  let dt = new Date(start);
129
129
 
130
130
  dt.setHours(0)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "corebasic",
3
3
  "type": "module",
4
- "version": "1.0.229",
4
+ "version": "1.0.231",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "./index.ts",