corebasic 1.0.221 → 1.0.222
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/features.js +13 -13
- package/libs/features.ts +38 -19
- package/package.json +1 -1
package/dist/libs/features.js
CHANGED
|
@@ -52,12 +52,14 @@ let appId = Utils.uid();
|
|
|
52
52
|
let SERVICE_ADDRESS = process.env.APP_ENDPOINT || 'http://127.0.0.1:3000';
|
|
53
53
|
export const get = feature => {
|
|
54
54
|
const throwError = () => { throw new Error(`Feature ${feature} not found in internal or external list during Features.subscribe call`); };
|
|
55
|
-
|
|
55
|
+
const baseFeature = getFeature(feature);
|
|
56
|
+
let { api, service = SERVICE_ADDRESS, topic } = baseFeature ? baseFeature : (SLYP_FEATURES_LIST[feature] ?? throwError());
|
|
56
57
|
return { api, service, topic };
|
|
57
58
|
};
|
|
58
59
|
export const send = async (meta, feature, data, params) => {
|
|
59
60
|
const throwError = () => { throw new Error(`Feature ${feature} not found in internal or external list during inter feature call`); };
|
|
60
|
-
|
|
61
|
+
const baseFeature = getFeature(feature);
|
|
62
|
+
let { api, service = SERVICE_ADDRESS } = baseFeature ? baseFeature : (SLYP_FEATURES_LIST[feature] ?? throwError());
|
|
61
63
|
let method = getFeatureMethod(api);
|
|
62
64
|
let url = getFeatureUrl(api);
|
|
63
65
|
if (params || url.includes(':')) {
|
|
@@ -92,13 +94,12 @@ let appids = {};
|
|
|
92
94
|
async function announce() {
|
|
93
95
|
let exp_features = {};
|
|
94
96
|
for (let [key, { api, subscribe }] of Object.entries(features))
|
|
95
|
-
exp_features[key] = { api, service: SERVICE_ADDRESS, subscribe };
|
|
97
|
+
exp_features[key] = { api, service: SERVICE_ADDRESS, subscribe, topic: "" };
|
|
96
98
|
await Messaging.subscribe(`${process.env.REDIS_CHANNEL_PREFIX}_SLYP_FEATURES_LIST`, async (message, channel) => {
|
|
97
|
-
let msg = JSON.parse(message);
|
|
98
|
-
if (
|
|
99
|
-
appids[
|
|
99
|
+
let { uid, ...msg } = JSON.parse(message);
|
|
100
|
+
if (uid !== appId && !appids[uid]) {
|
|
101
|
+
appids[uid] = true;
|
|
100
102
|
SLYP_FEATURES_LIST = { ...SLYP_FEATURES_LIST, ...msg };
|
|
101
|
-
delete SLYP_FEATURES_LIST.uid;
|
|
102
103
|
await Messaging.produce(`${process.env.REDIS_CHANNEL_PREFIX}_SLYP_FEATURES_LIST`, JSON.stringify({ ...exp_features, uid: appId }));
|
|
103
104
|
await subscribe();
|
|
104
105
|
}
|
|
@@ -187,15 +188,15 @@ async function registerHandler(features) {
|
|
|
187
188
|
apis[feature.api] = apis[feature.api] ?? {};
|
|
188
189
|
apis[feature.api][name] = feature;
|
|
189
190
|
const featureName = name;
|
|
190
|
-
|
|
191
|
-
let handler =
|
|
192
|
-
|
|
193
|
-
if (
|
|
191
|
+
const nameParts = name.split('.');
|
|
192
|
+
let handler = nameParts.pop();
|
|
193
|
+
const featurePath = `src/${nameParts.join('/')}`;
|
|
194
|
+
if (featurePath === 'src/transactions/query')
|
|
194
195
|
continue;
|
|
195
196
|
if (featureName.startsWith("flows.") && !featureName.startsWith("flows.query.") && !featureName.startsWith("flows.command.") && !featureName.startsWith("flows.designs."))
|
|
196
197
|
feature.handler = (await import(__rewriteRelativeImportExtension(`${new URL(`src/flows/query.js`, PROJECT_ROOT_URL).toString().replace('file://', '')}`))).FEATURE_HANDLERS[handler];
|
|
197
198
|
else
|
|
198
|
-
feature.handler = (await import(__rewriteRelativeImportExtension(`${new URL(`${
|
|
199
|
+
feature.handler = (await import(__rewriteRelativeImportExtension(`${new URL(`${featurePath}.js`, PROJECT_ROOT_URL).toString().replace('file://', '')}`)))[handler];
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
202
|
function registerApi() {
|
|
@@ -335,7 +336,6 @@ async function subscribe() {
|
|
|
335
336
|
catch (_) { }
|
|
336
337
|
delete subscribed_consumers[key];
|
|
337
338
|
}
|
|
338
|
-
let exp_features = {};
|
|
339
339
|
for (let key in SLYP_FEATURES_LIST)
|
|
340
340
|
if (!Utils.isEmpty(SLYP_FEATURES_LIST[key].subscribe)) {
|
|
341
341
|
subscriptions[key] = SLYP_FEATURES_LIST[key].subscribe;
|
package/libs/features.ts
CHANGED
|
@@ -8,7 +8,26 @@ import axios from 'axios'
|
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
import jwt from 'jsonwebtoken'
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
export type Message = unknown
|
|
12
|
+
export type Req = unknown
|
|
13
|
+
export type Res = unknown
|
|
14
|
+
export type Query = (req: Req, res: Res) => Promise<void>
|
|
15
|
+
export type Command = (topic: string, message: Message, req?: Req, res?: Res) => Promise<void>
|
|
16
|
+
type Handler = Query | Command
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
type RemoteFeatureEntry = {
|
|
20
|
+
api: string
|
|
21
|
+
service: string
|
|
22
|
+
subscribe: string
|
|
23
|
+
topic: string
|
|
24
|
+
headers?: {JWT?: string, service?: boolean, NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN?: string}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type FeatureEntry = { api: string, topic: string, bypass: boolean, featureless: boolean, subscribe: string, handler: Handler }
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
let features: Record<string, FeatureEntry> = {}
|
|
12
31
|
let apis = {}
|
|
13
32
|
|
|
14
33
|
const getFeatureMethod = api => api.split(' ')[0].toLowerCase()
|
|
@@ -39,20 +58,22 @@ async function loadLocalFeatures() { // For Local Testing
|
|
|
39
58
|
return data
|
|
40
59
|
}
|
|
41
60
|
|
|
42
|
-
let SLYP_FEATURES_LIST = await loadLocalFeatures()
|
|
61
|
+
let SLYP_FEATURES_LIST: Record<string, RemoteFeatureEntry> = await loadLocalFeatures()
|
|
43
62
|
let appId = Utils.uid()
|
|
44
63
|
let SERVICE_ADDRESS = process.env.APP_ENDPOINT || 'http://127.0.0.1:3000'
|
|
45
64
|
|
|
46
65
|
|
|
47
66
|
export const get = feature => {
|
|
48
67
|
const throwError = () => {throw new Error(`Feature ${feature} not found in internal or external list during Features.subscribe call`)}
|
|
49
|
-
|
|
68
|
+
const baseFeature: FeatureEntry = getFeature(feature)
|
|
69
|
+
let {api, service = SERVICE_ADDRESS, topic} = baseFeature ? baseFeature as FeatureEntry & {service: string} : (SLYP_FEATURES_LIST[feature] ?? throwError())
|
|
50
70
|
return {api, service, topic}
|
|
51
71
|
}
|
|
52
72
|
|
|
53
73
|
export const send = async (meta, feature, data, params) => {
|
|
54
74
|
const throwError = () => {throw new Error(`Feature ${feature} not found in internal or external list during inter feature call`)}
|
|
55
|
-
|
|
75
|
+
const baseFeature: FeatureEntry = getFeature(feature)
|
|
76
|
+
let {api, service = SERVICE_ADDRESS} = baseFeature ? baseFeature as FeatureEntry & {service: string} : (SLYP_FEATURES_LIST[feature] ?? throwError())
|
|
56
77
|
let method = getFeatureMethod(api)
|
|
57
78
|
let url = getFeatureUrl(api)
|
|
58
79
|
|
|
@@ -90,16 +111,15 @@ export const send = async (meta, feature, data, params) => {
|
|
|
90
111
|
|
|
91
112
|
let appids = {}
|
|
92
113
|
async function announce() {
|
|
93
|
-
let exp_features = {}
|
|
114
|
+
let exp_features: Record<string, RemoteFeatureEntry> = {}
|
|
94
115
|
for (let [key, {api,subscribe}] of Object.entries(features))
|
|
95
|
-
exp_features[key] = {api, service: SERVICE_ADDRESS, subscribe}
|
|
116
|
+
exp_features[key] = {api, service: SERVICE_ADDRESS, subscribe, topic: ""}
|
|
96
117
|
|
|
97
118
|
await Messaging.subscribe(`${process.env.REDIS_CHANNEL_PREFIX}_SLYP_FEATURES_LIST`, async (message, channel) => {
|
|
98
|
-
let msg = JSON.parse(message)
|
|
99
|
-
if (
|
|
100
|
-
appids[
|
|
119
|
+
let {uid, ...msg} = JSON.parse(message) as Record<string, RemoteFeatureEntry> & {uid: string}
|
|
120
|
+
if (uid !== appId && !appids[uid]) {
|
|
121
|
+
appids[uid] = true
|
|
101
122
|
SLYP_FEATURES_LIST = {...SLYP_FEATURES_LIST, ...msg}
|
|
102
|
-
delete SLYP_FEATURES_LIST.uid
|
|
103
123
|
await Messaging.produce(`${process.env.REDIS_CHANNEL_PREFIX}_SLYP_FEATURES_LIST`, JSON.stringify({...exp_features, uid: appId }))
|
|
104
124
|
await subscribe()
|
|
105
125
|
}
|
|
@@ -151,7 +171,7 @@ const apiHandler = async (req, res) => {
|
|
|
151
171
|
if (method === "get") {
|
|
152
172
|
try {
|
|
153
173
|
req.body = {...req.body, topic}
|
|
154
|
-
await feature.handler(req, res)
|
|
174
|
+
await (feature.handler as Query)(req, res)
|
|
155
175
|
} catch (err) {
|
|
156
176
|
if (process.env.DEBUG_MODE)
|
|
157
177
|
console.log('Error: Feature: ', req.body?.feature ?? (featureless ? `Featureless Api:${featureless.api}` : undefined), err)
|
|
@@ -159,7 +179,7 @@ const apiHandler = async (req, res) => {
|
|
|
159
179
|
}
|
|
160
180
|
} else if (method !== "get" && feature.bypass) {
|
|
161
181
|
try {
|
|
162
|
-
await feature.handler(topic, prepareMessage(req), req, res)
|
|
182
|
+
await (feature.handler as Command)(topic, prepareMessage(req), req, res)
|
|
163
183
|
} catch (err) {
|
|
164
184
|
if (process.env.DEBUG_MODE)
|
|
165
185
|
console.log('Error: Feature: ', req.body?.feature ?? (featureless ? `Featureless Api:${featureless.api}` : undefined), err)
|
|
@@ -194,17 +214,17 @@ async function registerHandler(features) {
|
|
|
194
214
|
apis[feature.api][name] = feature
|
|
195
215
|
const featureName = name
|
|
196
216
|
|
|
197
|
-
|
|
198
|
-
let handler =
|
|
199
|
-
|
|
217
|
+
const nameParts = name.split('.')
|
|
218
|
+
let handler = nameParts.pop()
|
|
219
|
+
const featurePath = `src/${nameParts.join('/')}`
|
|
200
220
|
|
|
201
|
-
if (
|
|
221
|
+
if (featurePath === 'src/transactions/query')
|
|
202
222
|
continue
|
|
203
223
|
|
|
204
224
|
if (featureName.startsWith("flows.") && !featureName.startsWith("flows.query.") && !featureName.startsWith("flows.command.") && !featureName.startsWith("flows.designs."))
|
|
205
225
|
feature.handler = (await import(`${new URL(`src/flows/query.js`, PROJECT_ROOT_URL).toString().replace('file://', '')}`)).FEATURE_HANDLERS[handler]
|
|
206
226
|
else
|
|
207
|
-
feature.handler = (await import(`${new URL(`${
|
|
227
|
+
feature.handler = (await import(`${new URL(`${featurePath}.js`, PROJECT_ROOT_URL).toString().replace('file://', '')}`))[handler]
|
|
208
228
|
}
|
|
209
229
|
}
|
|
210
230
|
function registerApi() {
|
|
@@ -266,7 +286,7 @@ export const start = async (app, url, file) => {
|
|
|
266
286
|
// // TODO: use $useChunks: [] once support is added in dip insert
|
|
267
287
|
// 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
|
|
268
288
|
// TODO: Avoid duplicate processing
|
|
269
|
-
await features[message.feature].handler(topic, message)
|
|
289
|
+
await (features[message.feature].handler as Command)(topic, message)
|
|
270
290
|
await Dip.insert(globalMeta, "Features.txns", {_id: message.txn, status: "Processed"}, {idempotent: true})
|
|
271
291
|
break
|
|
272
292
|
} catch(err) {
|
|
@@ -348,7 +368,6 @@ async function subscribe() {
|
|
|
348
368
|
}
|
|
349
369
|
|
|
350
370
|
|
|
351
|
-
let exp_features = {}
|
|
352
371
|
for (let key in SLYP_FEATURES_LIST)
|
|
353
372
|
if (!Utils.isEmpty(SLYP_FEATURES_LIST[key].subscribe)) {
|
|
354
373
|
subscriptions[key] = SLYP_FEATURES_LIST[key].subscribe
|