corebasic 1.0.231 → 1.0.233
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/dist/libs/auth.js +3 -3
- package/dist/libs/dip/suffix/index.js +1 -1
- package/dist/libs/dip/suffix/suffix.js +2 -3
- package/dist/libs/dip/suffix/tests/policy.applySuffixPolicy.test.js +26 -99
- package/dist/libs/dip/suffix/tests/policy.test.js +1 -1
- package/dist/libs/dip.js +1 -0
- package/dist/libs/dipper.js +13 -12
- package/dist/libs/elabase.js +36 -45
- package/dist/libs/features.js +113 -62
- package/dist/libs/kafka.js +5 -8
- package/dist/libs/messaging.js +1 -1
- package/dist/libs/utils.js +1 -1
- package/libs/auth.ts +3 -3
- package/libs/dip/suffix/index.ts +1 -1
- package/libs/dip/suffix/policy.ts +1 -1
- package/libs/dip/suffix/suffix.ts +3 -4
- package/libs/dip/suffix/tests/policy.applySuffixPolicy.test.ts +26 -180
- package/libs/dip/suffix/tests/policy.test.ts +1 -1
- package/libs/dip.ts +7 -5
- package/libs/dipper.ts +14 -13
- package/libs/elabase.ts +172 -126
- package/libs/features.ts +234 -96
- package/libs/kafka.ts +12 -14
- package/libs/messaging.ts +2 -2
- package/libs/utils.ts +1 -1
- package/package.json +1 -1
- package/tsconfig.json +16 -1
package/dist/libs/features.js
CHANGED
|
@@ -16,10 +16,13 @@ import axios from 'axios';
|
|
|
16
16
|
// @ts-ignore
|
|
17
17
|
import jwt from 'jsonwebtoken';
|
|
18
18
|
let features = {};
|
|
19
|
-
let apis = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
19
|
+
let apis = {
|
|
20
|
+
// <api>: {<feature>: FeatureEntry}
|
|
21
|
+
};
|
|
22
|
+
const getFeatureMethod = (api) => api.split(' ')[0].toLowerCase();
|
|
23
|
+
const getFeatureUrl = (api) => { const url = api.split(' ')[1]; if (!url)
|
|
24
|
+
throw new Error(`Invalid Feature url in api: ${api}`); return url; };
|
|
25
|
+
const getFeature = (name) => features[name];
|
|
23
26
|
const DEPLOY_TOKEN_SECRET = process.env.DEPLOY_TOKEN_SECRET || "MY_SECRET_DEPLOY_TOKEN";
|
|
24
27
|
const SERVICE_ACCESS_TOKEN = jwt.sign({ app: process.env.APP_DEPLOYMENT_NAME }, DEPLOY_TOKEN_SECRET, { expiresIn: '365d' });
|
|
25
28
|
const NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN = await (async () => { if (process.env.NDCURVE_DEVELOPER_SERVICE)
|
|
@@ -50,7 +53,7 @@ async function loadLocalFeatures() {
|
|
|
50
53
|
let SLYP_FEATURES_LIST = await loadLocalFeatures();
|
|
51
54
|
let appId = Utils.uid();
|
|
52
55
|
let SERVICE_ADDRESS = process.env.APP_ENDPOINT || 'http://127.0.0.1:3000';
|
|
53
|
-
export const get = feature => {
|
|
56
|
+
export const get = (feature) => {
|
|
54
57
|
const throwError = () => { throw new Error(`Feature ${feature} not found in internal or external list during Features.subscribe call`); };
|
|
55
58
|
const baseFeature = getFeature(feature);
|
|
56
59
|
let { api, service = SERVICE_ADDRESS, topic } = baseFeature ? baseFeature : (SLYP_FEATURES_LIST[feature] ?? throwError());
|
|
@@ -68,16 +71,27 @@ export const send = async (meta, feature, data, params) => {
|
|
|
68
71
|
if (url.includes(':'))
|
|
69
72
|
throw new Error(`Error: Internal feature call send on feature: ${feature} when api/params/substitution`);
|
|
70
73
|
}
|
|
71
|
-
|
|
74
|
+
const payload = { ...meta, data, feature, txn: Utils.uid() };
|
|
72
75
|
service = service.replace('http://slyp.app', 'https://slyp.app');
|
|
73
76
|
// return (await axios[method](`${service}${url}`, { data: payload, headers: {jwt: headers.jwt}, timeout: 1000 })).data
|
|
74
77
|
// Used to work. But request to 127.0.0.1 fails to send the specified headers along with the request.
|
|
75
78
|
// return (await axios[method](`${service}${url}`, payload, {headers: {jwt: SERVICE_ACCESS_TOKEN, service: true}, timeout: 1000 })).data // Worked Earlier, but issue spotted
|
|
76
|
-
if (
|
|
79
|
+
if (baseFeature) { // Local call
|
|
77
80
|
let response;
|
|
78
|
-
let req = {
|
|
81
|
+
let req = { body: payload, params: params ?? {}, method, path: url, url: '', headers: {}, query: {}, on: (_event, _callback) => { } };
|
|
79
82
|
req = JSON.parse(JSON.stringify(req));
|
|
80
|
-
|
|
83
|
+
const callback = (payload) => { response = payload; };
|
|
84
|
+
const res = {
|
|
85
|
+
json: callback,
|
|
86
|
+
send: callback,
|
|
87
|
+
end: () => { },
|
|
88
|
+
status: (_status) => { return { send: callback, json: callback }; },
|
|
89
|
+
sendStatus: (_status) => { },
|
|
90
|
+
setHeader: (_header, _value) => { },
|
|
91
|
+
flushHeaders: () => { },
|
|
92
|
+
headersSent: false,
|
|
93
|
+
writableEnded: false,
|
|
94
|
+
};
|
|
81
95
|
await apiHandler(req, res);
|
|
82
96
|
return response;
|
|
83
97
|
}
|
|
@@ -95,7 +109,7 @@ async function announce() {
|
|
|
95
109
|
let exp_features = {};
|
|
96
110
|
for (let [key, { api, subscribe }] of Object.entries(features))
|
|
97
111
|
exp_features[key] = { api, service: SERVICE_ADDRESS, subscribe, topic: "" };
|
|
98
|
-
await Messaging.subscribe(`${process.env.REDIS_CHANNEL_PREFIX}_SLYP_FEATURES_LIST`, async (message,
|
|
112
|
+
await Messaging.subscribe(`${process.env.REDIS_CHANNEL_PREFIX}_SLYP_FEATURES_LIST`, async (message, _channel) => {
|
|
99
113
|
let { uid, ...msg } = JSON.parse(message);
|
|
100
114
|
if (uid !== appId && !appids[uid]) {
|
|
101
115
|
appids[uid] = true;
|
|
@@ -109,11 +123,13 @@ async function announce() {
|
|
|
109
123
|
function getFeaturelessFeature(req) {
|
|
110
124
|
if (Session.ALLOWED_URLS.includes(req.path)) {
|
|
111
125
|
for (let key in features) {
|
|
112
|
-
|
|
126
|
+
const feature = features[key];
|
|
127
|
+
if (feature.featureless && feature.api === req.method.toUpperCase() + ' ' + req.path) {
|
|
113
128
|
return getFeature(key);
|
|
114
129
|
}
|
|
115
130
|
}
|
|
116
131
|
}
|
|
132
|
+
return undefined;
|
|
117
133
|
}
|
|
118
134
|
const apiHandler = async (req, res) => {
|
|
119
135
|
let method = req.method.toLowerCase();
|
|
@@ -129,44 +145,77 @@ const apiHandler = async (req, res) => {
|
|
|
129
145
|
console.warn(`Feature: ${req.body.feature} not available`);
|
|
130
146
|
throw { status: 404, message: `Resource not found. Feature ${req.body.feature} not available.` };
|
|
131
147
|
}
|
|
148
|
+
feature = feature; // typescript validation with !
|
|
132
149
|
let topic = feature.topic;
|
|
133
|
-
let params = getFeatureUrl(feature.api).split("/").filter(item => item.startsWith(":")).map(item => item.replace(":", ""));
|
|
150
|
+
let params = getFeatureUrl(feature.api).split("/").filter((item) => item.startsWith(":")).map((item) => item.replace(":", ""));
|
|
134
151
|
for (let param of params)
|
|
135
152
|
if (!req.params[param])
|
|
136
153
|
throw { status: 404, message: "Resource not found. One or more url parameter not specified." };
|
|
137
|
-
let meta = { ...req.body, data: undefined };
|
|
138
|
-
req.meta = meta;
|
|
154
|
+
let meta = { ...req.body, data: undefined }; // TODO: Must also include invoiceTxn
|
|
139
155
|
if (process.env.USE_DEFAULT_COMPANY) {
|
|
140
|
-
|
|
141
|
-
|
|
156
|
+
meta.company = 'DEFAULT_COMPANY';
|
|
157
|
+
meta.outlet = 'DEFAULT_OUTLET';
|
|
142
158
|
}
|
|
159
|
+
meta.txn = meta.txn ?? Utils.uid();
|
|
160
|
+
const message = {
|
|
161
|
+
meta,
|
|
162
|
+
data: req.body.data,
|
|
163
|
+
params: req.params,
|
|
164
|
+
// To be removed 1
|
|
165
|
+
date: new Date().getTime(),
|
|
166
|
+
// To be removed 2
|
|
167
|
+
topic,
|
|
168
|
+
feature: req.body.feature,
|
|
169
|
+
user: req.body.user,
|
|
170
|
+
txn: meta.txn,
|
|
171
|
+
};
|
|
172
|
+
const appReq = {
|
|
173
|
+
meta: message.meta,
|
|
174
|
+
body: message,
|
|
175
|
+
params: message.params,
|
|
176
|
+
method: method,
|
|
177
|
+
path: req.path,
|
|
178
|
+
url: req.url,
|
|
179
|
+
headers: req.headers,
|
|
180
|
+
query: req.query,
|
|
181
|
+
on: req.on,
|
|
182
|
+
};
|
|
183
|
+
const appRes = res;
|
|
143
184
|
if (method === "get") {
|
|
144
185
|
try {
|
|
145
|
-
req.body
|
|
146
|
-
|
|
186
|
+
// await feature.handler({...req, headers: req.headers, body: {...req.body, topic} }, res)
|
|
187
|
+
// req.body = {...req.body, topic}
|
|
188
|
+
await feature.handler(appReq, appRes);
|
|
147
189
|
}
|
|
148
190
|
catch (err) {
|
|
149
191
|
if (process.env.DEBUG_MODE)
|
|
150
|
-
console.
|
|
192
|
+
console.error('Error: Feature: ', req.body?.feature ?? (featureless ? `Featureless Api:${featureless.api}` : undefined), err);
|
|
151
193
|
throw { status: 500, message: "Failed to GET feature", ...err };
|
|
152
194
|
}
|
|
153
195
|
}
|
|
154
196
|
else if (method !== "get" && feature.bypass) {
|
|
155
197
|
try {
|
|
156
|
-
await feature.handler(topic,
|
|
198
|
+
await feature.handler(topic, message, appReq, appRes);
|
|
157
199
|
}
|
|
158
200
|
catch (err) {
|
|
159
201
|
if (process.env.DEBUG_MODE)
|
|
160
|
-
console.
|
|
202
|
+
console.error('Error: Feature: ', req.body?.feature ?? (featureless ? `Featureless Api:${featureless.api}` : undefined), err);
|
|
161
203
|
throw { status: 500, message: "Failed to POST feature", ...err };
|
|
162
204
|
}
|
|
163
205
|
}
|
|
164
|
-
else
|
|
165
|
-
|
|
206
|
+
else {
|
|
207
|
+
try {
|
|
208
|
+
await Kafka.send(`Features.${topic}`, message, message.user, { compression: Kafka.CompressionTypes.GZIP });
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
throw { status: 500, message: "Failed to queue the transaction" };
|
|
212
|
+
}
|
|
213
|
+
appRes.json({ data: { txn: message.txn, success: true, status: "Queued", featureQueued: true } });
|
|
214
|
+
}
|
|
166
215
|
}
|
|
167
216
|
catch (err) {
|
|
168
217
|
if (process.env.DEBUG_MODE)
|
|
169
|
-
console.
|
|
218
|
+
console.error('Error: Feature: ', req.body?.feature ?? (featureless ? `Featureless Api:${featureless.api}` : undefined), err);
|
|
170
219
|
try { // Sometimes error occurs when disconnecting stream from front end
|
|
171
220
|
res.status(err.status ?? 500).json(err);
|
|
172
221
|
}
|
|
@@ -203,6 +252,8 @@ function registerApi() {
|
|
|
203
252
|
for (let api in apis) {
|
|
204
253
|
let method = getFeatureMethod(api);
|
|
205
254
|
let url = api.split(' ')[1];
|
|
255
|
+
if (!url)
|
|
256
|
+
throw new Error(`No url path found in api ${api} during Features.registerApi()`);
|
|
206
257
|
if (api === 'GET /transactions/:id')
|
|
207
258
|
continue;
|
|
208
259
|
ExpressApp[method](url, apiHandler);
|
|
@@ -216,13 +267,13 @@ export const start = async (app, url, file) => {
|
|
|
216
267
|
PROJECT_ROOT_URL = url;
|
|
217
268
|
features = await Utils.fileToJson(url, file);
|
|
218
269
|
await announce();
|
|
219
|
-
app.get('/features', async (
|
|
270
|
+
app.get('/features', async (_req, res) => {
|
|
220
271
|
let exp_features = {};
|
|
221
272
|
for (let [key, { api }] of Object.entries(features))
|
|
222
|
-
exp_features[key] = { api, service: `${SERVICE_ADDRESS}
|
|
273
|
+
exp_features[key] = { api, service: `${SERVICE_ADDRESS}`, subscribe: '', topic: '' };
|
|
223
274
|
if (process.env.LOAD_LOCAL_FEATURES) {
|
|
224
275
|
for (let key in SLYP_FEATURES_LIST)
|
|
225
|
-
SLYP_FEATURES_LIST[key].headers = { JWT: SERVICE_ACCESS_TOKEN, service: true, NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN };
|
|
276
|
+
SLYP_FEATURES_LIST[key].headers = { JWT: SERVICE_ACCESS_TOKEN, service: true, NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN }; // TODO: CRITICAL: Security issue
|
|
226
277
|
}
|
|
227
278
|
res.json({ data: { ...SLYP_FEATURES_LIST, ...exp_features } });
|
|
228
279
|
});
|
|
@@ -230,20 +281,21 @@ export const start = async (app, url, file) => {
|
|
|
230
281
|
await registerFeatures(features);
|
|
231
282
|
// Get unique kafka topics list from features
|
|
232
283
|
let kafkaTopics = [];
|
|
233
|
-
for (
|
|
284
|
+
for (const name in features) {
|
|
234
285
|
let feature = features[name];
|
|
235
|
-
if (feature.api.split(' ')[0]
|
|
286
|
+
if (feature.api.split(' ')[0]?.toLowerCase() === "get")
|
|
236
287
|
continue;
|
|
237
288
|
kafkaTopics = [...new Set(kafkaTopics.concat([feature.topic]))];
|
|
238
289
|
}
|
|
239
290
|
// Subscribe to each topic
|
|
240
291
|
for (let topic of kafkaTopics) {
|
|
241
|
-
|
|
292
|
+
const groupId = '';
|
|
293
|
+
Kafka.receive(`Features.${topic}`, groupId, async (topic, message) => {
|
|
242
294
|
if (Utils.isEmpty(message.meta?.company))
|
|
243
295
|
message.meta = { ...message.meta, company: "GLOBAL", outlet: "GLOBAL" };
|
|
244
296
|
if (!message?.feature)
|
|
245
297
|
return;
|
|
246
|
-
const timer = ms => new Promise(res => setTimeout(res, ms)); // A promise that resolves after "ms" Milliseconds
|
|
298
|
+
const timer = (ms) => new Promise(res => setTimeout(res, ms)); // A promise that resolves after "ms" Milliseconds
|
|
247
299
|
topic = topic.replace(/^.*Features./, '');
|
|
248
300
|
while (true) {
|
|
249
301
|
try {
|
|
@@ -251,7 +303,12 @@ export const start = async (app, url, file) => {
|
|
|
251
303
|
// // TODO: use $useChunks: [] once support is added in dip insert
|
|
252
304
|
// await Dip.insert(globalMeta, `users.txns`, { _id: `${message.user}_${iso_date}_${message.txn}`, user: message.user, feature: message.feature, date: message.date, created: message.date, updated: message.date, status: "Queued" }, {idempotent: true}) // Can always update the status later
|
|
253
305
|
// TODO: Avoid duplicate processing
|
|
254
|
-
|
|
306
|
+
const feature = features[message.feature];
|
|
307
|
+
if (!feature) {
|
|
308
|
+
console.warn(`Feature ${message.feature} missing, in executing handler during Kafka.receive(topic: ${topic})`);
|
|
309
|
+
throw new Error(`Feature ${message.feature} missing, in executing handler during Kafka.receive(topic: ${topic})`);
|
|
310
|
+
}
|
|
311
|
+
await feature.handler(topic, message);
|
|
255
312
|
await Dip.insert(globalMeta, "Features.txns", { _id: message.txn, status: "Processed" }, { idempotent: true });
|
|
256
313
|
break;
|
|
257
314
|
}
|
|
@@ -296,31 +353,13 @@ export const start = async (app, url, file) => {
|
|
|
296
353
|
console.log('Messaging failed to start. Maybe missing redis');
|
|
297
354
|
}
|
|
298
355
|
};
|
|
299
|
-
function prepareMessage(req) {
|
|
300
|
-
let txn = req.body.txn ?? Utils.uid();
|
|
301
|
-
let _id = req.body.data?._id ?? txn;
|
|
302
|
-
let { data, feature, app, user, outlet, company, client, version } = req.body;
|
|
303
|
-
let meta = req.meta;
|
|
304
|
-
let params = req.params;
|
|
305
|
-
return { data, params, meta, feature, app, user, outlet, company, client, version, txn, id: _id, date: new Date().getTime() };
|
|
306
|
-
}
|
|
307
|
-
const commandAction = async (req, res, topic) => {
|
|
308
|
-
let message = prepareMessage(req);
|
|
309
|
-
try {
|
|
310
|
-
await Kafka.send(`Features.${topic}`, message, message.user, { compression: Kafka.CompressionTypes.GZIP });
|
|
311
|
-
}
|
|
312
|
-
catch {
|
|
313
|
-
throw { status: 500, message: "Failed to queue the transaction" };
|
|
314
|
-
}
|
|
315
|
-
res.json({ data: { txn: message.txn, success: true, status: "Queued", featureQueued: true } });
|
|
316
|
-
};
|
|
317
356
|
let subscriptions = {
|
|
318
357
|
// "coins.query.hello": "invoices.command.add", // Consumer : Feature of Topic
|
|
319
358
|
};
|
|
320
359
|
let subscribed_consumers = {};
|
|
321
360
|
async function subscribe() {
|
|
322
361
|
let Features = { get, send };
|
|
323
|
-
for (let [key, { subscribe }] of Object.entries(features))
|
|
362
|
+
for (let [key, { subscribe }] of Object.entries(features)) {
|
|
324
363
|
if (!Utils.isEmpty(subscribe) && subscriptions[key] !== subscribe && subscribed_consumers[key]) {
|
|
325
364
|
try {
|
|
326
365
|
await subscribed_consumers[key].disconnect();
|
|
@@ -328,30 +367,37 @@ async function subscribe() {
|
|
|
328
367
|
catch (_) { }
|
|
329
368
|
delete subscribed_consumers[key];
|
|
330
369
|
}
|
|
331
|
-
|
|
332
|
-
|
|
370
|
+
}
|
|
371
|
+
for (let key in SLYP_FEATURES_LIST) {
|
|
372
|
+
const feature = SLYP_FEATURES_LIST[key];
|
|
373
|
+
if (!Utils.isEmpty(feature?.subscribe) && subscriptions[key] !== feature?.subscribe && subscribed_consumers[key]) {
|
|
333
374
|
try {
|
|
334
375
|
await subscribed_consumers[key].disconnect();
|
|
335
376
|
}
|
|
336
377
|
catch (_) { }
|
|
337
378
|
delete subscribed_consumers[key];
|
|
338
379
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
380
|
+
}
|
|
381
|
+
for (let key in SLYP_FEATURES_LIST) {
|
|
382
|
+
const feature = SLYP_FEATURES_LIST[key];
|
|
383
|
+
if (!Utils.isEmpty(feature?.subscribe)) {
|
|
384
|
+
subscriptions[key] = feature.subscribe;
|
|
342
385
|
}
|
|
343
|
-
|
|
386
|
+
}
|
|
387
|
+
for (let [key, { subscribe }] of Object.entries(features)) {
|
|
344
388
|
if (!Utils.isEmpty(subscribe)) {
|
|
345
389
|
subscriptions[key] = subscribe;
|
|
346
390
|
}
|
|
391
|
+
}
|
|
347
392
|
for (let consumer in subscriptions) {
|
|
348
393
|
let publisher = subscriptions[consumer];
|
|
349
|
-
|
|
350
|
-
if (subscribed_consumers[consumer] || !
|
|
394
|
+
const publisherFeature = getFeature(publisher);
|
|
395
|
+
if (subscribed_consumers[consumer] || !publisherFeature)
|
|
351
396
|
continue;
|
|
352
|
-
let
|
|
397
|
+
let { topic } = publisherFeature;
|
|
398
|
+
let kafka_consumer_promise = Kafka.receive(`Features.${topic}`, consumer, async (topic, message) => {
|
|
353
399
|
topic = topic.replace(/^.*Features./, '');
|
|
354
|
-
const timer = ms => new Promise(res => setTimeout(res, ms)); // A promise that resolves after "ms" Milliseconds
|
|
400
|
+
const timer = (ms) => new Promise(res => setTimeout(res, ms)); // A promise that resolves after "ms" Milliseconds
|
|
355
401
|
while (true) {
|
|
356
402
|
try {
|
|
357
403
|
await Features.send(message.meta, consumer, message.data, message.params);
|
|
@@ -363,6 +409,11 @@ async function subscribe() {
|
|
|
363
409
|
await timer(10000);
|
|
364
410
|
}
|
|
365
411
|
});
|
|
366
|
-
|
|
412
|
+
kafka_consumer_promise
|
|
413
|
+
.then(kafka_consumer => {
|
|
414
|
+
subscribed_consumers[consumer] = kafka_consumer;
|
|
415
|
+
}).catch(() => {
|
|
416
|
+
throw new Error("Error: Remote service to service kafka Feature subscription.");
|
|
417
|
+
});
|
|
367
418
|
}
|
|
368
419
|
}
|
package/dist/libs/kafka.js
CHANGED
|
@@ -33,23 +33,20 @@ export const createTopic = async (topic, partition, replicas) => {
|
|
|
33
33
|
// ===========
|
|
34
34
|
let consumers = [];
|
|
35
35
|
const start_consumer = async function (topic, groupId, callback) {
|
|
36
|
-
|
|
37
|
-
groupId = typeof groupId === "string" ? `${appName}.${groupId}` : `${appName}.${topic}`;
|
|
36
|
+
groupId = groupId ? `${appName}.${groupId}` : `${appName}.${topic}`;
|
|
38
37
|
const consumer = kafka.consumer({ groupId: groupId });
|
|
39
38
|
consumers.push(consumer);
|
|
40
39
|
await consumer.connect();
|
|
41
40
|
await consumer.subscribe({ topic: topic, fromBeginning: true });
|
|
42
|
-
const fn = callback;
|
|
43
41
|
await consumer.run({
|
|
44
42
|
autoCommit: false,
|
|
45
43
|
eachMessage: async ({ topic, partition, message }) => {
|
|
46
|
-
//
|
|
47
|
-
let success;
|
|
44
|
+
// callback(topic, message.value.toString(), partition) // toString() returns array so won't parse if json.
|
|
48
45
|
try {
|
|
49
|
-
|
|
46
|
+
await callback(topic, JSON.parse(message.value), partition);
|
|
50
47
|
}
|
|
51
48
|
catch (ex) {
|
|
52
|
-
|
|
49
|
+
await callback(topic, message.value, partition); // NOTE: Beware: Ensure Kafka.receive<T> can handle raw message type that is not json parseable
|
|
53
50
|
}
|
|
54
51
|
await consumer.commitOffsets([{ topic, partition, offset: (Number(message.offset) + 1).toString() }]);
|
|
55
52
|
},
|
|
@@ -82,7 +79,7 @@ const start_producer = async function (topic, message, key, options) {
|
|
|
82
79
|
// start_producer('quickstart-events', 'Hello KafkaJS user! Little')
|
|
83
80
|
export const receive = async function (topic, groupId, callback) {
|
|
84
81
|
topic = topicPrefix + topic;
|
|
85
|
-
return
|
|
82
|
+
return await start_consumer(topic, groupId, callback);
|
|
86
83
|
};
|
|
87
84
|
export const send = async function (topic, message, key, options) {
|
|
88
85
|
topic = topicPrefix + topic;
|
package/dist/libs/messaging.js
CHANGED
|
@@ -34,7 +34,7 @@ async function connect({ user, req, res, uid }) {
|
|
|
34
34
|
message = JSON.parse(message);
|
|
35
35
|
}
|
|
36
36
|
catch { }
|
|
37
|
-
for (let {
|
|
37
|
+
for (let { res } of users_pool[user].reqres) {
|
|
38
38
|
res.write(JSON.stringify({ message, channel }) + "\n");
|
|
39
39
|
if (res.flush) // If compression enabled
|
|
40
40
|
res.flush();
|
package/dist/libs/utils.js
CHANGED
package/libs/auth.ts
CHANGED
|
@@ -47,7 +47,7 @@ type SuccessCallback = (
|
|
|
47
47
|
let validateFn: ValidateFunction | undefined
|
|
48
48
|
let validateErrMessage: string | undefined
|
|
49
49
|
|
|
50
|
-
export const validate = (callback: ValidateFunction,
|
|
50
|
+
export const validate = (callback: ValidateFunction, _errMessage?: string) => {
|
|
51
51
|
validateFn = callback
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -58,7 +58,7 @@ export const start = (app: AuthApp, successCallback?: SuccessCallback) => {
|
|
|
58
58
|
return
|
|
59
59
|
}
|
|
60
60
|
try {
|
|
61
|
-
let login = await attemptLogin(req
|
|
61
|
+
let login = await attemptLogin(req)
|
|
62
62
|
if (login.mode === 'verify' && login.success) {
|
|
63
63
|
let tokens = Session.generateAccessToken(login.userId, req.body.clientId ?? '')
|
|
64
64
|
let response = {...login, tokens}
|
|
@@ -74,7 +74,7 @@ export const start = (app: AuthApp, successCallback?: SuccessCallback) => {
|
|
|
74
74
|
})
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
async function attemptLogin(req: AuthRequest
|
|
77
|
+
async function attemptLogin(req: AuthRequest) {
|
|
78
78
|
let meta = {company: "GLOBAL", outlet: "GLOBAL"}
|
|
79
79
|
|
|
80
80
|
let expiry = 300000
|
package/libs/dip/suffix/index.ts
CHANGED
|
@@ -89,7 +89,7 @@ function flatten_value(target_key: string, value: unknown, flattened: unknown[],
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
export function entries(target_key: string, query: unknown,
|
|
92
|
+
export function entries(target_key: string, query: unknown, _binary_slice?: Buffer): unknown[] {
|
|
93
93
|
let result = flatten_id_values(target_key, query); // extract all valid _id
|
|
94
94
|
|
|
95
95
|
// let cows = result.map(v => extract_direct_id(v, binary_slice))
|
|
@@ -140,7 +140,7 @@ type SuffixItem = { key?: string; value?: string; type: string; ls_threshold?: n
|
|
|
140
140
|
type CollectionsJsonType = Record<string, {policy?: {when: object, suffix: SuffixItem[]}[]}>
|
|
141
141
|
type Arg = { db: string; collection: string[]; }
|
|
142
142
|
|
|
143
|
-
export async function applySuffixPolicy(COLLECTIONS_JSON: CollectionsJsonType, cols: string | string[], query: Record<string, any>, insertMode
|
|
143
|
+
export async function applySuffixPolicy(COLLECTIONS_JSON: CollectionsJsonType, cols: string | string[], query: Record<string, any>, insertMode: boolean, arg: Arg) {
|
|
144
144
|
const collections = Array.isArray(cols) ? cols : [cols]
|
|
145
145
|
let suffixes: string[] = []
|
|
146
146
|
|
|
@@ -6,7 +6,7 @@ type SuffixItem = { key?: string; value?: string; type: string; ls_threshold?: n
|
|
|
6
6
|
type Arg = { db: string; collection: string[]; }
|
|
7
7
|
|
|
8
8
|
const EXPLICIT_SUFFIX_POLICY_TYPES = new Set([ "string", "date", "number" ]);
|
|
9
|
-
export async function suffix(doc: Record<string, any>, policies: SuffixItem[], insertMode
|
|
9
|
+
export async function suffix(doc: Record<string, any>, policies: SuffixItem[], insertMode: boolean, arg: Arg) {
|
|
10
10
|
let suffixes = [""]
|
|
11
11
|
for (const policy of policies) {
|
|
12
12
|
|
|
@@ -92,9 +92,8 @@ export async function suffix(doc: Record<string, any>, policies: SuffixItem[], i
|
|
|
92
92
|
if (!keys.length && !insertMode) {
|
|
93
93
|
ls = true
|
|
94
94
|
for (const suffix of suffixes) {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const dirs = (await Dip.operation("ls", { db: arg?.db, collection: collection, suffix })).filter((dir: string) => !dir.startsWith('chunk-'))
|
|
95
|
+
for (const collection of arg.collection) {
|
|
96
|
+
const dirs = (await Dip.operation("ls", { db: arg.db, collection: collection, suffix })).filter((dir: string) => !dir.startsWith('chunk-'))
|
|
98
97
|
suffixAssociatedKeys[suffix] = suffixAssociatedKeys[suffix] ?? []
|
|
99
98
|
suffixAssociatedKeys[suffix].push(...dirs)
|
|
100
99
|
}
|