corebasic 1.0.220 → 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/dip/suffix/date.js +7 -7
- package/dist/libs/elabase.js +4 -4
- package/dist/libs/features.js +15 -15
- package/dist/libs/messaging.js +1 -1
- package/dist/libs/utils.js +24 -24
- package/libs/features.ts +38 -19
- package/package.json +1 -1
|
@@ -36,13 +36,13 @@ export function formatDate(value, format) {
|
|
|
36
36
|
// years and months and dates are already deduplicated
|
|
37
37
|
const separator = '|';
|
|
38
38
|
const replacements = {
|
|
39
|
-
YYYY:
|
|
40
|
-
YY:
|
|
41
|
-
MMMM:
|
|
42
|
-
MMM:
|
|
43
|
-
MM:
|
|
44
|
-
DD:
|
|
45
|
-
D:
|
|
39
|
+
YYYY: () => years.join(separator),
|
|
40
|
+
YY: () => years.map(y => String(y).slice(-2)).join(separator),
|
|
41
|
+
MMMM: () => months.map(m => MONTH_LONG[m]).join(separator),
|
|
42
|
+
MMM: () => months.map(m => MONTH_SHORT[m]).join(separator),
|
|
43
|
+
MM: () => months.map(m => String(m + 1).padStart(2, "0")).join(separator),
|
|
44
|
+
DD: () => dates.map(d => String(d).padStart(2, "0")).join(separator),
|
|
45
|
+
D: () => dates.join(separator),
|
|
46
46
|
};
|
|
47
47
|
return format.replace(/YYYY|MMMM|MMM|YY|MM|DD|D/g, token => replacements[token]());
|
|
48
48
|
}
|
package/dist/libs/elabase.js
CHANGED
|
@@ -466,7 +466,7 @@ let Essentials = {
|
|
|
466
466
|
};
|
|
467
467
|
function prepareResult(result) {
|
|
468
468
|
let res = result.content?.length === 1 ? result.content[0].items : result.content; // For raw, this resolves to result.content which is ArrayBuffer
|
|
469
|
-
res.metadata =
|
|
469
|
+
res.metadata = () => result.metadata;
|
|
470
470
|
if (result.metadata.executor === "raw")
|
|
471
471
|
setRawBatchIterator(res);
|
|
472
472
|
return res;
|
|
@@ -507,7 +507,7 @@ function parseBinaryResponse(result) {
|
|
|
507
507
|
}
|
|
508
508
|
function setRawBatchIterator(arrayBuffer) {
|
|
509
509
|
arrayBuffer.metadata().items.forEach(batch => {
|
|
510
|
-
batch.kv =
|
|
510
|
+
batch.kv = () => {
|
|
511
511
|
const batchItem = {
|
|
512
512
|
count: batch.count,
|
|
513
513
|
slice: Essentials.sliceArrayBuffer(arrayBuffer, batch.offset, batch.size),
|
|
@@ -636,7 +636,7 @@ function getRawKeyValue(arrayBuffer, offset) {
|
|
|
636
636
|
// Zero-copy view window bounded strictly to the key bytes
|
|
637
637
|
let _id = masterView.subarray(offset, offset + keySize);
|
|
638
638
|
let _id_string;
|
|
639
|
-
_id.toText =
|
|
639
|
+
_id.toText = () => {
|
|
640
640
|
// Fix: Pass the typed array view itself, NOT the underlying root buffer
|
|
641
641
|
_id_string = _id_string === undefined ? _id.buffer.slice(_id.byteOffset, _id.byteOffset + _id.byteLength) : _id_string;
|
|
642
642
|
return bufferToString(_id_string);
|
|
@@ -651,7 +651,7 @@ function getRawKeyValue(arrayBuffer, offset) {
|
|
|
651
651
|
offset += dataSize;
|
|
652
652
|
_val = Essentials.sliceArrayBuffer(arrayBuffer, _val.byteOffset, _val.byteLength);
|
|
653
653
|
// _val = _val.buffer.slice(_val.byteOffset, _val.byteOffset + _val.byteLength);
|
|
654
|
-
_val.toText =
|
|
654
|
+
_val.toText = () => bufferToString(_val);
|
|
655
655
|
return { _id, _val, next: offset };
|
|
656
656
|
}
|
|
657
657
|
// Axios usage
|
package/dist/libs/features.js
CHANGED
|
@@ -22,7 +22,7 @@ const getFeatureUrl = api => api.split(' ')[1];
|
|
|
22
22
|
const getFeature = name => features[name];
|
|
23
23
|
const DEPLOY_TOKEN_SECRET = process.env.DEPLOY_TOKEN_SECRET || "MY_SECRET_DEPLOY_TOKEN";
|
|
24
24
|
const SERVICE_ACCESS_TOKEN = jwt.sign({ app: process.env.APP_DEPLOYMENT_NAME }, DEPLOY_TOKEN_SECRET, { expiresIn: '365d' });
|
|
25
|
-
const NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN = await (async (
|
|
25
|
+
const NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN = await (async () => { if (process.env.NDCURVE_DEVELOPER_SERVICE)
|
|
26
26
|
try {
|
|
27
27
|
return (await Utils.fileToJson('file://', '/.ndcurve/developer.license.json')).accessToken?.trim();
|
|
28
28
|
}
|
|
@@ -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(':')) {
|
|
@@ -75,7 +77,7 @@ export const send = async (meta, feature, data, params) => {
|
|
|
75
77
|
let response;
|
|
76
78
|
let req = { meta, body: payload, params, method };
|
|
77
79
|
req = JSON.parse(JSON.stringify(req));
|
|
78
|
-
let res = { json: payload => response = payload, end:
|
|
80
|
+
let res = { json: payload => response = payload, end: () => true };
|
|
79
81
|
await apiHandler(req, res);
|
|
80
82
|
return response;
|
|
81
83
|
}
|
|
@@ -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/dist/libs/messaging.js
CHANGED
|
@@ -125,7 +125,7 @@ export async function hdel(key, subkey) {
|
|
|
125
125
|
}
|
|
126
126
|
// Hydrate
|
|
127
127
|
export async function hydrate(callback) {
|
|
128
|
-
setTimeout(async (
|
|
128
|
+
setTimeout(async () => {
|
|
129
129
|
let { user, company, items } = await callback();
|
|
130
130
|
await publish(user, { event: "RPC_hydrate", data: { company, items }, txn: Utils.uid() });
|
|
131
131
|
}, 100);
|
package/dist/libs/utils.js
CHANGED
|
@@ -184,18 +184,18 @@ export function validityToMillisecs(start, validity) {
|
|
|
184
184
|
count = parseIntValue(count);
|
|
185
185
|
period = period.toLowerCase();
|
|
186
186
|
const timeline = {
|
|
187
|
-
year:
|
|
188
|
-
years:
|
|
189
|
-
month:
|
|
190
|
-
months:
|
|
191
|
-
day:
|
|
192
|
-
days:
|
|
193
|
-
week:
|
|
194
|
-
weeks:
|
|
195
|
-
hour:
|
|
196
|
-
hours:
|
|
197
|
-
minute:
|
|
198
|
-
minutes:
|
|
187
|
+
year: () => addYears(now, count),
|
|
188
|
+
years: () => addYears(now, count),
|
|
189
|
+
month: () => addMonths(now, count),
|
|
190
|
+
months: () => addMonths(now, count),
|
|
191
|
+
day: () => now.setDate(now.getDate() + count),
|
|
192
|
+
days: () => now.setDate(now.getDate() + count),
|
|
193
|
+
week: () => now.setDate(now.getDate() + (count * 7)),
|
|
194
|
+
weeks: () => now.setDate(now.getDate() + (count * 7)),
|
|
195
|
+
hour: () => now.setHours(now.getHours() + count),
|
|
196
|
+
hours: () => now.setHours(now.getHours() + count),
|
|
197
|
+
minute: () => now.setMinutes(now.getMinutes() + count),
|
|
198
|
+
minutes: () => now.setMinutes(now.getMinutes() + count),
|
|
199
199
|
};
|
|
200
200
|
timeline[period]();
|
|
201
201
|
return now.getTime();
|
|
@@ -206,18 +206,18 @@ export function validityToUTCMillisecs(start, validity) {
|
|
|
206
206
|
count = parseIntValue(count);
|
|
207
207
|
period = period.toLowerCase();
|
|
208
208
|
const timeline = {
|
|
209
|
-
year:
|
|
210
|
-
years:
|
|
211
|
-
month:
|
|
212
|
-
months:
|
|
213
|
-
day:
|
|
214
|
-
days:
|
|
215
|
-
week:
|
|
216
|
-
weeks:
|
|
217
|
-
hour:
|
|
218
|
-
hours:
|
|
219
|
-
minute:
|
|
220
|
-
minutes:
|
|
209
|
+
year: () => addUTCYears(now, count),
|
|
210
|
+
years: () => addUTCYears(now, count),
|
|
211
|
+
month: () => addUTCMonths(now, count),
|
|
212
|
+
months: () => addUTCMonths(now, count),
|
|
213
|
+
day: () => now.setUTCDate(now.getUTCDate() + count),
|
|
214
|
+
days: () => now.setUTCDate(now.getUTCDate() + count),
|
|
215
|
+
week: () => now.setUTCDate(now.getUTCDate() + (count * 7)),
|
|
216
|
+
weeks: () => now.setUTCDate(now.getUTCDate() + (count * 7)),
|
|
217
|
+
hour: () => now.setUTCHours(now.getUTCHours() + count),
|
|
218
|
+
hours: () => now.setUTCHours(now.getUTCHours() + count),
|
|
219
|
+
minute: () => now.setUTCMinutes(now.getUTCMinutes() + count),
|
|
220
|
+
minutes: () => now.setUTCMinutes(now.getUTCMinutes() + count),
|
|
221
221
|
};
|
|
222
222
|
timeline[period]();
|
|
223
223
|
return now.getTime();
|
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
|