@yuneta/gobj-js 7.25.8 → 7.26.0
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 +102 -24
- package/dist/gobj-js.cjs.js +608 -132
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +1300 -1027
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +605 -133
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +1344 -1071
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +608 -132
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +1351 -1078
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +608 -132
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +1340 -1067
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +2 -2
package/dist/gobj-js.cjs.js
CHANGED
|
@@ -24,8 +24,8 @@ function vsprintf(fmt, argv) {
|
|
|
24
24
|
return sprintf.apply(null, [fmt].concat(argv || []));
|
|
25
25
|
}
|
|
26
26
|
function sprintf_format(parse_tree, argv) {
|
|
27
|
-
var cursor = 1, tree_length = parse_tree.length, arg, output = "", i, k, ph, pad, pad_character, pad_length, is_positive, sign;
|
|
28
|
-
for (
|
|
27
|
+
var cursor = 1, tree_length = parse_tree.length, arg, output = "", i = 0, k, ph, pad, pad_character, pad_length, is_positive, sign;
|
|
28
|
+
for (; i < tree_length; i++) if (typeof parse_tree[i] === "string") output += parse_tree[i];
|
|
29
29
|
else if (typeof parse_tree[i] === "object") {
|
|
30
30
|
ph = parse_tree[i];
|
|
31
31
|
if (ph.keys) {
|
|
@@ -158,7 +158,7 @@ function command_parser(gobj, command, kw, src) {}
|
|
|
158
158
|
function build_command_response(gobj, result, comment, schema, data) {
|
|
159
159
|
return {
|
|
160
160
|
result,
|
|
161
|
-
comment: comment ||
|
|
161
|
+
comment: comment || "",
|
|
162
162
|
schema: schema || {},
|
|
163
163
|
data: data || []
|
|
164
164
|
};
|
|
@@ -212,7 +212,7 @@ var __global_command_parser_fn__ = null;
|
|
|
212
212
|
var __global_stats_parser_fn__ = null;
|
|
213
213
|
var dl_global_event_types = [];
|
|
214
214
|
var _gclass_register = Object.create(null);
|
|
215
|
-
var __jn_services__ =
|
|
215
|
+
var __jn_services__ = Object.create(null);
|
|
216
216
|
var __yuno__ = null;
|
|
217
217
|
var __default_service__ = null;
|
|
218
218
|
var __inside__ = 0;
|
|
@@ -821,7 +821,8 @@ function set_default(gobj, sdata, it) {
|
|
|
821
821
|
if (!is_object(jn_value)) jn_value = {};
|
|
822
822
|
break;
|
|
823
823
|
case data_type_t.DTP_JSON:
|
|
824
|
-
if (
|
|
824
|
+
if (svalue === "" || svalue === void 0) jn_value = null;
|
|
825
|
+
else if (is_string(svalue)) try {
|
|
825
826
|
jn_value = JSON.parse(svalue);
|
|
826
827
|
} catch (error) {
|
|
827
828
|
log_error(`JSON parse error: ${error.message}`);
|
|
@@ -856,11 +857,17 @@ function json2item(gobj, sdata, it, jn_value_) {
|
|
|
856
857
|
break;
|
|
857
858
|
case data_type_t.DTP_INTEGER:
|
|
858
859
|
jn_value2 = parseInt(jn_value_);
|
|
859
|
-
if (isNaN(jn_value2))
|
|
860
|
+
if (isNaN(jn_value2)) {
|
|
861
|
+
log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
|
|
862
|
+
return -1;
|
|
863
|
+
}
|
|
860
864
|
break;
|
|
861
865
|
case data_type_t.DTP_REAL:
|
|
862
866
|
jn_value2 = Number(jn_value_);
|
|
863
|
-
if (isNaN(jn_value2))
|
|
867
|
+
if (isNaN(jn_value2)) {
|
|
868
|
+
log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
|
|
869
|
+
return -1;
|
|
870
|
+
}
|
|
864
871
|
break;
|
|
865
872
|
case data_type_t.DTP_LIST:
|
|
866
873
|
if (is_string(jn_value_)) try {
|
|
@@ -887,15 +894,11 @@ function json2item(gobj, sdata, it, jn_value_) {
|
|
|
887
894
|
}
|
|
888
895
|
break;
|
|
889
896
|
case data_type_t.DTP_JSON:
|
|
897
|
+
jn_value2 = jn_value_;
|
|
890
898
|
if (is_string(jn_value_)) try {
|
|
891
899
|
jn_value2 = JSON.parse(jn_value_);
|
|
892
900
|
} catch (error) {
|
|
893
|
-
|
|
894
|
-
}
|
|
895
|
-
else jn_value2 = jn_value_;
|
|
896
|
-
if (!is_array(jn_value2) && !is_object(jn_value2)) {
|
|
897
|
-
log_error(`attr must be a json dict/list: ${it.name}`);
|
|
898
|
-
return -1;
|
|
901
|
+
jn_value2 = jn_value_;
|
|
899
902
|
}
|
|
900
903
|
break;
|
|
901
904
|
case data_type_t.DTP_POINTER: jn_value2 = jn_value_;
|
|
@@ -1200,6 +1203,10 @@ function gobj_default_service() {
|
|
|
1200
1203
|
* find a service
|
|
1201
1204
|
************************************************************/
|
|
1202
1205
|
function gobj_find_service(service_name, verbose) {
|
|
1206
|
+
if (!is_string(service_name)) {
|
|
1207
|
+
log_error(`gobj_find_service(): service name must be a string: ${service_name}`);
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1203
1210
|
service_name = service_name.toLowerCase();
|
|
1204
1211
|
let service_gobj = __jn_services__[service_name];
|
|
1205
1212
|
if (!service_gobj) {
|
|
@@ -1334,7 +1341,7 @@ function write_json_parameters(gobj, kw, jn_global) {
|
|
|
1334
1341
|
let new_kw = kw;
|
|
1335
1342
|
if (json2sdata(hs, new_kw, -1, gobj.gclass.gclass_flag & gclass_flag_t.gcflag_ignore_unknown_attrs ? 0 : print_attr_not_found, gobj) < 0) {
|
|
1336
1343
|
log_error(`${gobj_short_name(gobj)} json2data() FAILED`);
|
|
1337
|
-
|
|
1344
|
+
trace_json_masked(new_kw);
|
|
1338
1345
|
}
|
|
1339
1346
|
}
|
|
1340
1347
|
/************************************************************
|
|
@@ -1357,9 +1364,10 @@ function gobj_create2(gobj_name, gclass_name, kw, parent, gobj_flag) {
|
|
|
1357
1364
|
return null;
|
|
1358
1365
|
}
|
|
1359
1366
|
if (is_string(parent)) {
|
|
1360
|
-
|
|
1367
|
+
const parent_name = parent;
|
|
1368
|
+
parent = gobj_find_service(parent_name);
|
|
1361
1369
|
if (!parent) {
|
|
1362
|
-
log_warning(`parent service not found: ${
|
|
1370
|
+
log_warning(`parent service not found: ${parent_name}`);
|
|
1363
1371
|
return null;
|
|
1364
1372
|
}
|
|
1365
1373
|
}
|
|
@@ -1472,6 +1480,7 @@ function gobj_destroy(gobj) {
|
|
|
1472
1480
|
parent.gclass.gmt.mt_child_removed(parent, gobj);
|
|
1473
1481
|
}
|
|
1474
1482
|
if (gobj.gobj_flag & gobj_flag_t.gobj_flag_service) _deregister_service(gobj);
|
|
1483
|
+
if (gobj === __default_service__) __default_service__ = null;
|
|
1475
1484
|
gobj_unsubscribe_list(gobj, gobj.dl_subscriptions, true);
|
|
1476
1485
|
gobj_unsubscribe_list(gobj, gobj.dl_subscribings, true);
|
|
1477
1486
|
if (parent) {
|
|
@@ -1817,7 +1826,7 @@ function gobj_set_bottom_gobj(gobj, bottom_gobj) {
|
|
|
1817
1826
|
log_error(`gobj NULL of bad type`);
|
|
1818
1827
|
return null;
|
|
1819
1828
|
}
|
|
1820
|
-
if (gobj.bottom_gobj) log_warning(`${gobj_short_name(gobj)}: bottom_gobj already set`);
|
|
1829
|
+
if (gobj.bottom_gobj && bottom_gobj) log_warning(`${gobj_short_name(gobj)}: bottom_gobj already set`);
|
|
1821
1830
|
gobj.bottom_gobj = bottom_gobj;
|
|
1822
1831
|
}
|
|
1823
1832
|
/***************************************************************************
|
|
@@ -2232,7 +2241,7 @@ function gobj_write_attr(gobj, path, value, src) {
|
|
|
2232
2241
|
jn_attrs[key] = value;
|
|
2233
2242
|
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(key)) gobj.priv[key] = value;
|
|
2234
2243
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2235
|
-
if (gobj.mt_writing) gobj.mt_writing(gobj, key);
|
|
2244
|
+
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
|
|
2236
2245
|
}
|
|
2237
2246
|
return 0;
|
|
2238
2247
|
}
|
|
@@ -2256,8 +2265,8 @@ function sdata_write_default_values(gobj, include_flag, exclude_flag) {
|
|
|
2256
2265
|
if (!it.name) continue;
|
|
2257
2266
|
if (exclude_flag && it.flag & exclude_flag) continue;
|
|
2258
2267
|
if (include_flag === -1 || it.flag & include_flag) {
|
|
2259
|
-
|
|
2260
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] =
|
|
2268
|
+
set_default(gobj, gobj.jn_attrs, it);
|
|
2269
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] = gobj.jn_attrs[it.name];
|
|
2261
2270
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, it.name);
|
|
2262
2271
|
}
|
|
2263
2272
|
}
|
|
@@ -2291,7 +2300,7 @@ function gobj_write_bool_attr(gobj, name, value) {
|
|
|
2291
2300
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2292
2301
|
if (hs) {
|
|
2293
2302
|
hs[name] = parseBoolean(value);
|
|
2294
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] =
|
|
2303
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
|
|
2295
2304
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2296
2305
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
2297
2306
|
}
|
|
@@ -2307,7 +2316,7 @@ function gobj_write_integer_attr(gobj, name, value) {
|
|
|
2307
2316
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2308
2317
|
if (hs) {
|
|
2309
2318
|
hs[name] = parseInt(value);
|
|
2310
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] =
|
|
2319
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
|
|
2311
2320
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2312
2321
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
2313
2322
|
}
|
|
@@ -2323,7 +2332,7 @@ function gobj_write_str_attr(gobj, name, value) {
|
|
|
2323
2332
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2324
2333
|
if (hs) {
|
|
2325
2334
|
hs[name] = String(value);
|
|
2326
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] =
|
|
2335
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
|
|
2327
2336
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2328
2337
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
2329
2338
|
}
|
|
@@ -2377,15 +2386,15 @@ function gobj_change_parent(gobj, parent) {
|
|
|
2377
2386
|
log_error(`${gobj_short_name(gobj)}: gobj_change_parent() BAD TYPE of parent`);
|
|
2378
2387
|
return -1;
|
|
2379
2388
|
}
|
|
2380
|
-
if (gobj.parent && gobj.parent.mt_child_removed) gobj.parent.mt_child_removed(gobj.parent, gobj);
|
|
2389
|
+
if (gobj.parent && gobj.parent.gclass.gmt.mt_child_removed) gobj.parent.gclass.gmt.mt_child_removed(gobj.parent, gobj);
|
|
2381
2390
|
if (gobj.parent) {
|
|
2382
2391
|
_remove_child(gobj.parent, gobj);
|
|
2383
2392
|
gobj.parent = null;
|
|
2384
2393
|
}
|
|
2385
2394
|
_add_child(parent, gobj);
|
|
2386
|
-
if (parent.mt_child_added) {
|
|
2395
|
+
if (parent.gclass.gmt.mt_child_added) {
|
|
2387
2396
|
if (__trace_gobj_create_delete__(gobj)) log_debug(sprintf("👦👦🔵 child_added(%s): %s", gobj_full_name(parent), gobj_short_name(gobj)));
|
|
2388
|
-
parent.mt_child_added(parent, gobj);
|
|
2397
|
+
parent.gclass.gmt.mt_child_added(parent, gobj);
|
|
2389
2398
|
}
|
|
2390
2399
|
return 0;
|
|
2391
2400
|
}
|
|
@@ -2497,9 +2506,19 @@ function gobj_deliver_posted_events() {
|
|
|
2497
2506
|
let snapshot = __dl_posted_events__;
|
|
2498
2507
|
__dl_posted_events__ = [];
|
|
2499
2508
|
let delivered = 0;
|
|
2500
|
-
for (let
|
|
2509
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2510
|
+
const msg = snapshot[i];
|
|
2501
2511
|
if (msg.dst.obflag & (obflag_t.obflag_destroyed | obflag_t.obflag_destroying)) continue;
|
|
2502
|
-
|
|
2512
|
+
try {
|
|
2513
|
+
gobj_send_event(msg.dst, msg.event, msg.kw, msg.src);
|
|
2514
|
+
} catch (e) {
|
|
2515
|
+
__dl_posted_events__ = snapshot.slice(i + 1).concat(__dl_posted_events__);
|
|
2516
|
+
if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
|
|
2517
|
+
__posted_events_scheduled__ = true;
|
|
2518
|
+
setTimeout(gobj_deliver_posted_events, 0);
|
|
2519
|
+
}
|
|
2520
|
+
throw e;
|
|
2521
|
+
}
|
|
2503
2522
|
delivered++;
|
|
2504
2523
|
}
|
|
2505
2524
|
if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
|
|
@@ -2549,7 +2568,7 @@ function gobj_send_event(dst, event, kw, src) {
|
|
|
2549
2568
|
else trace_machine(sprintf("🔃 mach(%s%s), st: %s, ev: %s, from(%s%s)", !dst.running ? "!!" : "", gobj_short_name(dst), state.state_name, event ? event : "", src && !src.running ? "!!" : "", gobj_short_name(src)));
|
|
2550
2569
|
if (kw) {
|
|
2551
2570
|
if (__trace_gobj_ev_kw__(dst)) {
|
|
2552
|
-
if (json_object_size(kw))
|
|
2571
|
+
if (json_object_size(kw)) trace_json_masked(kw);
|
|
2553
2572
|
}
|
|
2554
2573
|
}
|
|
2555
2574
|
}
|
|
@@ -2569,7 +2588,7 @@ function gobj_send_event(dst, event, kw, src) {
|
|
|
2569
2588
|
}
|
|
2570
2589
|
if (kw) {
|
|
2571
2590
|
if (__trace_gobj_ev_kw__(dst)) {
|
|
2572
|
-
if (json_object_size(kw))
|
|
2591
|
+
if (json_object_size(kw)) trace_json_masked(kw);
|
|
2573
2592
|
}
|
|
2574
2593
|
}
|
|
2575
2594
|
}
|
|
@@ -2577,15 +2596,40 @@ function gobj_send_event(dst, event, kw, src) {
|
|
|
2577
2596
|
let ret = -1;
|
|
2578
2597
|
try {
|
|
2579
2598
|
if (event_action.action) ret = event_action.action(dst, event, kw, src);
|
|
2580
|
-
}
|
|
2599
|
+
} catch (e) {
|
|
2600
|
+
__inside__--;
|
|
2601
|
+
if (!(e && e.__gobj_logged__)) {
|
|
2602
|
+
log_error(`${gobj_short_name(dst)}: action of ${event} in ${dst.current_state.state_name} THREW: ${e && e.stack ? e.stack : e}`);
|
|
2603
|
+
try {
|
|
2604
|
+
e.__gobj_logged__ = true;
|
|
2605
|
+
} catch (e2) {}
|
|
2606
|
+
}
|
|
2607
|
+
throw e;
|
|
2608
|
+
}
|
|
2581
2609
|
if (tracea && __trace_machine_format__ !== 1 && !(dst.obflag & obflag_t.obflag_destroyed)) trace_machine(sprintf("<- mach(%s%s^%s), st: %s, ev: %s, ret: %d", !dst.running ? "!!" : "", gobj_gclass_name(dst), gobj_name(dst), dst.current_state.state_name, event ? event : "", is_number(ret) ? ret : 0));
|
|
2582
2610
|
__inside__--;
|
|
2583
2611
|
return ret;
|
|
2584
2612
|
}
|
|
2585
2613
|
var subs_flag_t = Object.freeze({
|
|
2586
|
-
|
|
2587
|
-
|
|
2614
|
+
__rename_event_name__: 1,
|
|
2615
|
+
__hard_subscription__: 2,
|
|
2616
|
+
__own_event__: 4
|
|
2588
2617
|
});
|
|
2618
|
+
/***************************************************************************
|
|
2619
|
+
* The event type of `event_name` in any registered gclass, null if none.
|
|
2620
|
+
* The C kernel's gobj_find_event_type(): any case, gclasses only.
|
|
2621
|
+
***************************************************************************/
|
|
2622
|
+
function _find_event_type_in_gclasses(event_name) {
|
|
2623
|
+
let lower = String(event_name).toLowerCase();
|
|
2624
|
+
for (let gclass_name in _gclass_register) {
|
|
2625
|
+
let dl = _gclass_register[gclass_name].dl_events;
|
|
2626
|
+
for (let i = 0; i < dl.length; i++) {
|
|
2627
|
+
let event_type = dl[i];
|
|
2628
|
+
if (event_type.event_name && event_type.event_name.toLowerCase() === lower) return event_type;
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
return null;
|
|
2632
|
+
}
|
|
2589
2633
|
var subscription_desc = [
|
|
2590
2634
|
SDATA(data_type_t.DTP_POINTER, "publisher", 0, null, "publisher gobj"),
|
|
2591
2635
|
SDATA(data_type_t.DTP_POINTER, "subscriber", 0, null, "subscriber gobj"),
|
|
@@ -2618,6 +2662,21 @@ function _create_subscription(publisher, event, kw, subscriber) {
|
|
|
2618
2662
|
if (json_size(__config__) > 0) {
|
|
2619
2663
|
let kw_clone = json_deep_copy(__config__);
|
|
2620
2664
|
json_object_set_new(subs, "__config__", kw_clone);
|
|
2665
|
+
let renamed_event = kw_get_str(publisher, kw_clone, "__rename_event_name__", "");
|
|
2666
|
+
if (!empty_string(renamed_event)) {
|
|
2667
|
+
let event_type = _find_event_type_in_gclasses(renamed_event);
|
|
2668
|
+
if (event_type) {
|
|
2669
|
+
json_object_set_new(subs, "renamed_event", event_type.event_name);
|
|
2670
|
+
delete kw_clone.__rename_event_name__;
|
|
2671
|
+
subs_flag |= subs_flag_t.__rename_event_name__;
|
|
2672
|
+
let kw_global = kw_get_dict(publisher, subs, "__global__", null);
|
|
2673
|
+
if (!is_object(kw_global)) {
|
|
2674
|
+
kw_global = {};
|
|
2675
|
+
json_object_set_new(subs, "__global__", kw_global);
|
|
2676
|
+
}
|
|
2677
|
+
kw_global.__original_event_name__ = event;
|
|
2678
|
+
} else log_error(`${gobj_short_name(publisher)}: EVENT NOT FOUND (__rename_event_name__: ${renamed_event})`);
|
|
2679
|
+
}
|
|
2621
2680
|
if (kw_has_key(kw_clone, "__hard_subscription__")) {
|
|
2622
2681
|
let hard_subscription = kw_get_bool(publisher, kw_clone, "__hard_subscription__", false);
|
|
2623
2682
|
json_object_del(kw_clone, "__hard_subscription__");
|
|
@@ -2637,9 +2696,52 @@ function _create_subscription(publisher, event, kw, subscriber) {
|
|
|
2637
2696
|
return subs;
|
|
2638
2697
|
}
|
|
2639
2698
|
/***************************************************************************
|
|
2699
|
+
* The kw to find the subscriptions a (un)subscription `kw` names: `kw` as
|
|
2700
|
+
* _create_subscription() stores it, as the C kernel's
|
|
2701
|
+
* _subscription_match_kw(). The three `__config__` keys the framework
|
|
2702
|
+
* reads (__hard_subscription__, __own_event__, __rename_event_name__)
|
|
2703
|
+
* become the subs_flag and are taken out of the stored `__config__`, and
|
|
2704
|
+
* a renamed event adds `__original_event_name__` to the stored
|
|
2705
|
+
* `__global__`: with `kw` as it came, the same kw matched no subscription,
|
|
2706
|
+
* a repeat of it was made twice (the subscriber got each event twice) and
|
|
2707
|
+
* its withdrawal found nothing. A known renamed event is returned in
|
|
2708
|
+
* `renamed_event`, which _match_subscription() compares: a plain and a
|
|
2709
|
+
* renamed subscription, or two renames of one event, are two. A rename
|
|
2710
|
+
* that no gclass declares stays in the stored `__config__`, and in this
|
|
2711
|
+
* one. Up to gobj-js 7.25.8 the kw was compared as it came, and
|
|
2712
|
+
* `__rename_event_name__` always stayed in the stored `__config__`: a
|
|
2713
|
+
* plain kw with the rest of that __config__ found no repeat (two
|
|
2714
|
+
* subscriptions where C has one).
|
|
2715
|
+
* Return {kw, renamed_event}; renamed_event is "" when kw does not rename.
|
|
2716
|
+
***************************************************************************/
|
|
2717
|
+
function _subscription_match_kw(kw, event) {
|
|
2718
|
+
let __config__ = kw ? kw.__config__ : null;
|
|
2719
|
+
if (!is_object(__config__) || !kw_has_key(__config__, "__hard_subscription__") && !kw_has_key(__config__, "__own_event__") && !kw_has_key(__config__, "__rename_event_name__")) return {
|
|
2720
|
+
kw,
|
|
2721
|
+
renamed_event: ""
|
|
2722
|
+
};
|
|
2723
|
+
let kw_match = Object.assign({}, kw);
|
|
2724
|
+
let config_match = Object.assign({}, __config__);
|
|
2725
|
+
kw_match.__config__ = config_match;
|
|
2726
|
+
let renamed_event = "";
|
|
2727
|
+
let rename = config_match.__rename_event_name__;
|
|
2728
|
+
let event_type = typeof rename === "string" && !empty_string(rename) ? _find_event_type_in_gclasses(rename) : null;
|
|
2729
|
+
if (event_type) {
|
|
2730
|
+
renamed_event = event_type.event_name;
|
|
2731
|
+
delete config_match.__rename_event_name__;
|
|
2732
|
+
if (event && json_size(kw_match.__global__) > 0) kw_match.__global__ = Object.assign({}, kw_match.__global__, { __original_event_name__: event });
|
|
2733
|
+
}
|
|
2734
|
+
delete config_match.__hard_subscription__;
|
|
2735
|
+
delete config_match.__own_event__;
|
|
2736
|
+
return {
|
|
2737
|
+
kw: kw_match,
|
|
2738
|
+
renamed_event
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
/***************************************************************************
|
|
2640
2742
|
* Match subscription
|
|
2641
2743
|
***************************************************************************/
|
|
2642
|
-
function _match_subscription(subs, publisher, event, kw, subscriber) {
|
|
2744
|
+
function _match_subscription(subs, publisher, event, renamed_event, kw, subscriber) {
|
|
2643
2745
|
let __config__ = kw_get_dict(publisher, kw, "__config__", null);
|
|
2644
2746
|
let __global__ = kw_get_dict(publisher, kw, "__global__", null);
|
|
2645
2747
|
let __local__ = kw_get_dict(publisher, kw, "__local__", null);
|
|
@@ -2654,6 +2756,9 @@ function _match_subscription(subs, publisher, event, kw, subscriber) {
|
|
|
2654
2756
|
if (event) {
|
|
2655
2757
|
if (event !== kw_get_str(null, subs, "event", "")) match = false;
|
|
2656
2758
|
}
|
|
2759
|
+
if (renamed_event) {
|
|
2760
|
+
if (renamed_event !== kw_get_str(null, subs, "renamed_event", "")) match = false;
|
|
2761
|
+
}
|
|
2657
2762
|
if (json_size(__config__) > 0) {
|
|
2658
2763
|
let kw_config = kw_get_dict(null, subs, "__config__", null);
|
|
2659
2764
|
if (json_size(kw_config) > 0) {
|
|
@@ -2688,26 +2793,29 @@ function _match_subscription(subs, publisher, event, kw, subscriber) {
|
|
|
2688
2793
|
* kw (__config__, __global__, __local__, __filter__),
|
|
2689
2794
|
* subscriber
|
|
2690
2795
|
***************************************************************************/
|
|
2691
|
-
function _find_subscriptions(dl_subs, publisher, event, kw, subscriber) {
|
|
2796
|
+
function _find_subscriptions(dl_subs, publisher, event, renamed_event, kw, subscriber) {
|
|
2692
2797
|
let iter = [];
|
|
2693
2798
|
for (let i = 0; i < dl_subs.length; i++) {
|
|
2694
2799
|
let subs = dl_subs[i];
|
|
2695
|
-
if (_match_subscription(subs, publisher, event, kw, subscriber)) json_array_append(iter, subs);
|
|
2800
|
+
if (_match_subscription(subs, publisher, event, renamed_event, kw, subscriber)) json_array_append(iter, subs);
|
|
2696
2801
|
}
|
|
2697
2802
|
return iter;
|
|
2698
2803
|
}
|
|
2699
2804
|
/***************************************************************************
|
|
2700
|
-
* Find idx of subscription in dl_subs, -1 not found
|
|
2805
|
+
* Find idx of the subscription `subs` itself in dl_subs, -1 not found.
|
|
2806
|
+
* Up to gobj-js 7.25.8 it was the first entry whose fields matched `subs`:
|
|
2807
|
+
* a subscription already removed took a live one that matched it (a plain
|
|
2808
|
+
* one matches every other of its event and subscriber).
|
|
2701
2809
|
***************************************************************************/
|
|
2702
|
-
function _get_subs_idx(dl_subs,
|
|
2703
|
-
|
|
2704
|
-
let subs = dl_subs[i];
|
|
2705
|
-
if (_match_subscription(subs, publisher, event, kw, subscriber)) return i;
|
|
2706
|
-
}
|
|
2707
|
-
return -1;
|
|
2810
|
+
function _get_subs_idx(dl_subs, subs) {
|
|
2811
|
+
return dl_subs.indexOf(subs);
|
|
2708
2812
|
}
|
|
2709
2813
|
/***************************************************************************
|
|
2710
|
-
* Delete subscription in publisher and subscriber
|
|
2814
|
+
* Delete subscription in publisher and subscriber.
|
|
2815
|
+
* Return 0 removed, -1 a hard one kept (only `force` removes it), 1 it
|
|
2816
|
+
* was not there any more: already removed, as a stale reference is, or by
|
|
2817
|
+
* the mt_subscription_deleted() of an earlier entry of the same list. The
|
|
2818
|
+
* caller says which is an error. As in C.
|
|
2711
2819
|
***************************************************************************/
|
|
2712
2820
|
function _delete_subscription(gobj, subs, force, not_inform) {
|
|
2713
2821
|
let publisher = kw_get_pointer(gobj, subs, "publisher", null, kw_flag_t.KW_REQUIRED);
|
|
@@ -2716,7 +2824,12 @@ function _delete_subscription(gobj, subs, force, not_inform) {
|
|
|
2716
2824
|
if (kw_get_int(gobj, subs, "subs_flag", null, kw_flag_t.KW_REQUIRED) & subs_flag_t.__hard_subscription__ ? 1 : 0) {
|
|
2717
2825
|
if (!force) return -1;
|
|
2718
2826
|
}
|
|
2719
|
-
|
|
2827
|
+
let tracea = __trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher);
|
|
2828
|
+
if (_get_subs_idx(publisher.dl_subscriptions, subs) < 0) {
|
|
2829
|
+
if (tracea) trace_machine(sprintf("💜💜👎 unsubscribing event '%s': publisher %s, subscriber'%s', ALREADY REMOVED", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
|
|
2830
|
+
return 1;
|
|
2831
|
+
}
|
|
2832
|
+
if (tracea) {
|
|
2720
2833
|
trace_machine(sprintf("💜💜👎 unsubscribing event '%s': publisher %s, subscriber'%s'", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
|
|
2721
2834
|
trace_json(subs);
|
|
2722
2835
|
}
|
|
@@ -2725,13 +2838,13 @@ function _delete_subscription(gobj, subs, force, not_inform) {
|
|
|
2725
2838
|
if (publisher.gclass.gmt.mt_subscription_deleted) publisher.gclass.gmt.mt_subscription_deleted(publisher, subs);
|
|
2726
2839
|
}
|
|
2727
2840
|
}
|
|
2728
|
-
let idx = _get_subs_idx(publisher.dl_subscriptions,
|
|
2841
|
+
let idx = _get_subs_idx(publisher.dl_subscriptions, subs);
|
|
2729
2842
|
if (idx >= 0) json_array_remove(publisher.dl_subscriptions, idx);
|
|
2730
2843
|
else {
|
|
2731
2844
|
log_error(`${gobj_short_name(gobj)}: subscription in publisher not found`);
|
|
2732
2845
|
trace_json(subs);
|
|
2733
2846
|
}
|
|
2734
|
-
idx = _get_subs_idx(subscriber.dl_subscribings,
|
|
2847
|
+
idx = _get_subs_idx(subscriber.dl_subscribings, subs);
|
|
2735
2848
|
if (idx >= 0) json_array_remove(subscriber.dl_subscribings, idx);
|
|
2736
2849
|
else {
|
|
2737
2850
|
log_error(`${gobj_short_name(gobj)}: subscription in subscriber not found`);
|
|
@@ -2774,7 +2887,17 @@ function gobj_subscribe_event(publisher, event, kw, subscriber) {
|
|
|
2774
2887
|
}
|
|
2775
2888
|
}
|
|
2776
2889
|
} else event = "";
|
|
2777
|
-
let
|
|
2890
|
+
let match = _subscription_match_kw(kw, event);
|
|
2891
|
+
let dl_subs = _find_subscriptions(publisher.dl_subscriptions, publisher, event, match.renamed_event, match.kw, subscriber);
|
|
2892
|
+
let subs_hard = null;
|
|
2893
|
+
for (let i = 0; i < dl_subs.length; i++) if (kw_get_int(publisher, dl_subs[i], "subs_flag", 0, kw_flag_t.KW_REQUIRED) & subs_flag_t.__hard_subscription__) {
|
|
2894
|
+
subs_hard = dl_subs[i];
|
|
2895
|
+
break;
|
|
2896
|
+
}
|
|
2897
|
+
if (subs_hard) {
|
|
2898
|
+
log_warning(`${gobj_short_name(publisher)}: Hard subscription REPEATED, the one there is kept and returned (event: ${event}, subscriber: ${gobj_short_name(subscriber)})`);
|
|
2899
|
+
return subs_hard;
|
|
2900
|
+
}
|
|
2778
2901
|
if (json_array_size(dl_subs) > 0) {
|
|
2779
2902
|
log_error(`${gobj_short_name(publisher)}: ${json_array_size(dl_subs)} subscription(s) REPEATED, will be deleted and override`);
|
|
2780
2903
|
trace_json(dl_subs, "subscription REPEATED");
|
|
@@ -2789,7 +2912,7 @@ function gobj_subscribe_event(publisher, event, kw, subscriber) {
|
|
|
2789
2912
|
json_array_append(subscriber.dl_subscribings, subs);
|
|
2790
2913
|
if (__trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher)) {
|
|
2791
2914
|
trace_machine(sprintf("💜💜👍 subscribing event '%s', publisher '%s', subscriber %s", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
|
|
2792
|
-
if (kw && (__trace_gobj_ev_kw__(subscriber) || __trace_gobj_ev_kw__(publisher)))
|
|
2915
|
+
if (kw && (__trace_gobj_ev_kw__(subscriber) || __trace_gobj_ev_kw__(publisher))) trace_json_masked(kw);
|
|
2793
2916
|
}
|
|
2794
2917
|
if (publisher.gclass.gmt.mt_subscription_added) {
|
|
2795
2918
|
let result = publisher.gclass.gmt.mt_subscription_added(publisher, subs);
|
|
@@ -2831,16 +2954,22 @@ function gobj_unsubscribe_event(publisher, event, kw, subscriber) {
|
|
|
2831
2954
|
}
|
|
2832
2955
|
}
|
|
2833
2956
|
} else event = "";
|
|
2834
|
-
let
|
|
2957
|
+
let match = _subscription_match_kw(kw, event);
|
|
2958
|
+
let dl_subs = _find_subscriptions(publisher.dl_subscriptions, publisher, event, match.renamed_event, match.kw, subscriber);
|
|
2835
2959
|
let deleted = 0;
|
|
2960
|
+
let kept_hard = 0;
|
|
2961
|
+
let already_removed = 0;
|
|
2836
2962
|
for (let i = 0; i < dl_subs.length; i++) {
|
|
2837
2963
|
let subs = dl_subs[i];
|
|
2838
|
-
_delete_subscription(publisher, subs, false, false);
|
|
2839
|
-
deleted++;
|
|
2964
|
+
let ret = _delete_subscription(publisher, subs, false, false);
|
|
2965
|
+
if (ret === 0) deleted++;
|
|
2966
|
+
else if (ret < 0) kept_hard++;
|
|
2967
|
+
else already_removed++;
|
|
2840
2968
|
}
|
|
2841
|
-
if (
|
|
2969
|
+
if (kept_hard) log_warning(`${gobj_short_name(publisher)}: Hard subscription not removed, only gobj_unsubscribe_list() with force removes it (event: ${event}, hard: ${kept_hard})`);
|
|
2970
|
+
else if (!deleted && !already_removed) {
|
|
2842
2971
|
log_warning(`${gobj_short_name(publisher)}: No subscription found`);
|
|
2843
|
-
|
|
2972
|
+
trace_json_masked(kw, "No subscription found");
|
|
2844
2973
|
}
|
|
2845
2974
|
return 0;
|
|
2846
2975
|
}
|
|
@@ -2849,10 +2978,12 @@ function gobj_unsubscribe_event(publisher, event, kw, subscriber) {
|
|
|
2849
2978
|
***************************************************************************/
|
|
2850
2979
|
function gobj_unsubscribe_list(gobj, dl_subs, force) {
|
|
2851
2980
|
let dl = [...dl_subs];
|
|
2981
|
+
let already_removed = 0;
|
|
2852
2982
|
for (let i = 0; i < dl.length; i++) {
|
|
2853
2983
|
let subs = dl[i];
|
|
2854
|
-
_delete_subscription(gobj, subs, force, false)
|
|
2984
|
+
if (_delete_subscription(gobj, subs, force, false) > 0) already_removed++;
|
|
2855
2985
|
}
|
|
2986
|
+
if (already_removed) log_warning(`${gobj_short_name(gobj)}: Subscription(s) already removed, nothing to remove (count: ${already_removed})`);
|
|
2856
2987
|
return 0;
|
|
2857
2988
|
}
|
|
2858
2989
|
/***************************************************************************
|
|
@@ -2864,7 +2995,7 @@ function gobj_unsubscribe_list(gobj, dl_subs, force) {
|
|
|
2864
2995
|
***************************************************************************/
|
|
2865
2996
|
function gobj_find_subscriptions(publisher, event, kw, subscriber) {
|
|
2866
2997
|
if (kw == null) kw = {};
|
|
2867
|
-
return _find_subscriptions(publisher.dl_subscriptions, publisher, event, kw, subscriber);
|
|
2998
|
+
return _find_subscriptions(publisher.dl_subscriptions, publisher, event, null, kw, subscriber);
|
|
2868
2999
|
}
|
|
2869
3000
|
/***************************************************************************
|
|
2870
3001
|
*
|
|
@@ -2903,7 +3034,7 @@ function gobj_list_subscriptions(gobj2view) {
|
|
|
2903
3034
|
* subscriber
|
|
2904
3035
|
***************************************************************************/
|
|
2905
3036
|
function gobj_find_subscribings(subscriber, event, kw, publisher) {
|
|
2906
|
-
return _find_subscriptions(subscriber.dl_subscribings, publisher, event, kw, subscriber);
|
|
3037
|
+
return _find_subscriptions(subscriber.dl_subscribings, publisher, event, null, kw, subscriber);
|
|
2907
3038
|
}
|
|
2908
3039
|
/***************************************************************************
|
|
2909
3040
|
* Return the sum of returns of gobj_send_event
|
|
@@ -2929,7 +3060,7 @@ function gobj_publish_event(publisher, event, kw) {
|
|
|
2929
3060
|
if (tracea) {
|
|
2930
3061
|
if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔝 %s %s%s %s", event ? event : "", !publisher.running ? "!!" : "", gobj_short_name(publisher), publisher.current_state.state_name));
|
|
2931
3062
|
else trace_machine(sprintf("🔝🔝 mach(%s%s^%s), st: %s, ev: %s%s%s", !publisher.running ? "!!" : "", gobj_gclass_name(publisher), gobj_name(publisher), publisher.current_state.state_name, "", event ? event : "", ""));
|
|
2932
|
-
if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw))
|
|
3063
|
+
if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw)) trace_json_masked(kw);
|
|
2933
3064
|
}
|
|
2934
3065
|
if (publisher.gclass.gmt.mt_publish_event) {
|
|
2935
3066
|
let topublish = publisher.gclass.gmt.mt_publish_event(publisher, event, kw);
|
|
@@ -2954,6 +3085,8 @@ function gobj_publish_event(publisher, event, kw) {
|
|
|
2954
3085
|
let __global__ = kw_get_dict(publisher, subs, "__global__", null, 0);
|
|
2955
3086
|
let __local__ = kw_get_dict(publisher, subs, "__local__", null, 0);
|
|
2956
3087
|
let __filter__ = kw_get_dict_value(publisher, subs, "__filter__", null, 0);
|
|
3088
|
+
let event_name = subs.renamed_event;
|
|
3089
|
+
if (empty_string(event_name)) event_name = event;
|
|
2957
3090
|
let topublish = 1;
|
|
2958
3091
|
if (publisher.gclass.gmt.mt_publication_filter) topublish = publisher.gclass.gmt.mt_publication_filter(publisher, event, kw, subscriber);
|
|
2959
3092
|
else if (json_size(__filter__) > 0) {
|
|
@@ -2977,11 +3110,11 @@ function gobj_publish_event(publisher, event, kw) {
|
|
|
2977
3110
|
if (__config__) {}
|
|
2978
3111
|
if (json_size(__global__) > 0) json_object_update(kw2publish, json_deep_copy(__global__));
|
|
2979
3112
|
if (tracea) {
|
|
2980
|
-
if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "",
|
|
2981
|
-
else trace_machine(sprintf("🔝🔄 mach(%s%s), st: %s, ev: %s, from(%s%s)", !subscriber.running ? "!!" : "", gobj_short_name(subscriber), gobj_current_state(subscriber), event ? event : "", publisher && !publisher.running ? "!!" : "", gobj_short_name(publisher)));
|
|
2982
|
-
if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw2publish))
|
|
3113
|
+
if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "", event_name ? event_name : "", !subscriber.running ? "!!" : "", gobj_short_name(subscriber)));
|
|
3114
|
+
else trace_machine(sprintf("🔝🔄 mach(%s%s), st: %s, ev: %s (%s), from(%s%s)", !subscriber.running ? "!!" : "", gobj_short_name(subscriber), gobj_current_state(subscriber), event ? event : "", event_name ? event_name : "", publisher && !publisher.running ? "!!" : "", gobj_short_name(publisher)));
|
|
3115
|
+
if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw2publish)) trace_json_masked(kw2publish);
|
|
2983
3116
|
}
|
|
2984
|
-
let ret_ = gobj_send_event(subscriber,
|
|
3117
|
+
let ret_ = gobj_send_event(subscriber, event_name, kw2publish, publisher);
|
|
2985
3118
|
if (ret_ < 0 && subs_flag & subs_flag_t.__own_event__) {
|
|
2986
3119
|
sent_count = -1;
|
|
2987
3120
|
break;
|
|
@@ -3005,8 +3138,9 @@ function gobj_command(gobj, command, kw, src) {
|
|
|
3005
3138
|
return -1;
|
|
3006
3139
|
}
|
|
3007
3140
|
if (is_commands_tracing(gobj) || is_machine_tracing(gobj, null) && !is_machine_not_tracing(src, null)) {
|
|
3008
|
-
|
|
3009
|
-
|
|
3141
|
+
let command_shown = mask_secrets_inline(command);
|
|
3142
|
+
trace_machine(sprintf("🌀🌀 mach(%s%s), cmd: %s, src: %s", !gobj_is_running(gobj) ? "!!" : "", gobj_short_name(gobj), command_shown !== null ? command_shown : command, gobj_short_name(src)));
|
|
3143
|
+
if (__trace_gobj_ev_kw__(gobj)) trace_json_masked(kw);
|
|
3010
3144
|
}
|
|
3011
3145
|
if (gobj.gclass.gmt.mt_command_parser) return gobj.gclass.gmt.mt_command_parser(gobj, command, kw, src);
|
|
3012
3146
|
if (gobj.gclass.command_table) {
|
|
@@ -3142,10 +3276,22 @@ function set_remote_log_functions(remote_log_fn) {
|
|
|
3142
3276
|
f_warning = _console.warn;
|
|
3143
3277
|
}
|
|
3144
3278
|
}
|
|
3279
|
+
/************************************************************
|
|
3280
|
+
* JSON.stringify for a log line: a circular object (a gobj,
|
|
3281
|
+
* a DOM node) must not make the log call itself throw.
|
|
3282
|
+
************************************************************/
|
|
3283
|
+
function log_stringify(v) {
|
|
3284
|
+
try {
|
|
3285
|
+
return JSON.stringify(v);
|
|
3286
|
+
} catch (e) {
|
|
3287
|
+
return String(v);
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3145
3290
|
function format_log(format) {
|
|
3146
3291
|
const args = Array.prototype.slice.call(arguments);
|
|
3147
3292
|
let output = "";
|
|
3148
3293
|
if (typeof format === "string") {
|
|
3294
|
+
if (args.length === 1) return format;
|
|
3149
3295
|
let i = 1;
|
|
3150
3296
|
output = format.replace(/%[sdifoO]/g, (match) => {
|
|
3151
3297
|
const val = args[i++];
|
|
@@ -3155,17 +3301,17 @@ function format_log(format) {
|
|
|
3155
3301
|
case "%i": return parseInt(val);
|
|
3156
3302
|
case "%f": return parseFloat(val);
|
|
3157
3303
|
case "%o":
|
|
3158
|
-
case "%O": return typeof val === "object" ?
|
|
3304
|
+
case "%O": return typeof val === "object" ? log_stringify(val) : String(val);
|
|
3159
3305
|
default: return match;
|
|
3160
3306
|
}
|
|
3161
3307
|
});
|
|
3162
|
-
const rest = args.slice(i).map((arg) => typeof arg === "object" ?
|
|
3308
|
+
const rest = args.slice(i).map((arg) => typeof arg === "object" ? log_stringify(arg) : String(arg));
|
|
3163
3309
|
if (rest.length > 0) output += " " + rest.join(" ");
|
|
3164
|
-
} else output = args.map((arg) => typeof arg === "object" ?
|
|
3310
|
+
} else output = args.map((arg) => typeof arg === "object" ? log_stringify(arg) : String(arg)).join(" ");
|
|
3165
3311
|
return output;
|
|
3166
3312
|
}
|
|
3167
|
-
function log_error(format) {
|
|
3168
|
-
let msg = format_log(format);
|
|
3313
|
+
function log_error(format, ...args) {
|
|
3314
|
+
let msg = format_log(format, ...args);
|
|
3169
3315
|
let hora = current_timestamp();
|
|
3170
3316
|
if (f_error) {
|
|
3171
3317
|
if (f_error === _console.error) {
|
|
@@ -3177,8 +3323,8 @@ function log_error(format) {
|
|
|
3177
3323
|
}
|
|
3178
3324
|
emit_log_callback("error", msg, hora);
|
|
3179
3325
|
}
|
|
3180
|
-
function log_warning(format) {
|
|
3181
|
-
let msg = format_log(format);
|
|
3326
|
+
function log_warning(format, ...args) {
|
|
3327
|
+
let msg = format_log(format, ...args);
|
|
3182
3328
|
let hora = current_timestamp();
|
|
3183
3329
|
if (f_warning) {
|
|
3184
3330
|
if (f_warning === _console.warn) {
|
|
@@ -3190,24 +3336,24 @@ function log_warning(format) {
|
|
|
3190
3336
|
}
|
|
3191
3337
|
emit_log_callback("warning", msg, hora);
|
|
3192
3338
|
}
|
|
3193
|
-
function log_info(format) {
|
|
3194
|
-
let msg = format_log(format);
|
|
3339
|
+
function log_info(format, ...args) {
|
|
3340
|
+
let msg = format_log(format, ...args);
|
|
3195
3341
|
let hora = current_timestamp();
|
|
3196
3342
|
if (f_info) {
|
|
3197
3343
|
if (console_wants("info", msg)) f_info("%c" + hora + " INFO: " + String(msg), "color:cyan");
|
|
3198
3344
|
}
|
|
3199
3345
|
emit_log_callback("info", msg, hora);
|
|
3200
3346
|
}
|
|
3201
|
-
function log_debug(format) {
|
|
3202
|
-
let msg = format_log(format);
|
|
3347
|
+
function log_debug(format, ...args) {
|
|
3348
|
+
let msg = format_log(format, ...args);
|
|
3203
3349
|
let hora = current_timestamp();
|
|
3204
3350
|
if (f_debug) {
|
|
3205
3351
|
if (console_wants("debug", msg)) f_debug("%c" + hora + " DEBUG: " + String(msg), "color:silver");
|
|
3206
3352
|
}
|
|
3207
3353
|
emit_log_callback("debug", msg, hora);
|
|
3208
3354
|
}
|
|
3209
|
-
function trace_msg(format) {
|
|
3210
|
-
let msg = format_log(format);
|
|
3355
|
+
function trace_msg(format, ...args) {
|
|
3356
|
+
let msg = format_log(format, ...args);
|
|
3211
3357
|
let hora = current_timestamp();
|
|
3212
3358
|
if (f_debug) {
|
|
3213
3359
|
if (console_wants("msg", msg)) f_debug("%c" + hora + " MSG: " + String(msg), "color:cyan");
|
|
@@ -3222,6 +3368,268 @@ function trace_json(jn, msg) {
|
|
|
3222
3368
|
emit_log_callback("json", jn, current_timestamp());
|
|
3223
3369
|
}
|
|
3224
3370
|
/************************************************************
|
|
3371
|
+
* The names of the secrets (is_secret_name()). The same lists
|
|
3372
|
+
* as the C kernel's helpers.c: a name that holds one of these
|
|
3373
|
+
* (any case) is a secret.
|
|
3374
|
+
************************************************************/
|
|
3375
|
+
var SECRET_NAME_PARTS = [
|
|
3376
|
+
"passw",
|
|
3377
|
+
"pwd",
|
|
3378
|
+
"passphrase",
|
|
3379
|
+
"secret",
|
|
3380
|
+
"token",
|
|
3381
|
+
"jwt",
|
|
3382
|
+
"bearer",
|
|
3383
|
+
"authorization",
|
|
3384
|
+
"cookie",
|
|
3385
|
+
"credential",
|
|
3386
|
+
"salt"
|
|
3387
|
+
];
|
|
3388
|
+
var SECRET_NAME_JOINED = [
|
|
3389
|
+
"apikey",
|
|
3390
|
+
"sessionid",
|
|
3391
|
+
"sessionkey",
|
|
3392
|
+
"authdata"
|
|
3393
|
+
];
|
|
3394
|
+
var NOT_SECRET_SEGMENTS = /* @__PURE__ */ new Set([
|
|
3395
|
+
"endpoint",
|
|
3396
|
+
"url",
|
|
3397
|
+
"uri",
|
|
3398
|
+
"domain",
|
|
3399
|
+
"path",
|
|
3400
|
+
"file",
|
|
3401
|
+
"public",
|
|
3402
|
+
"pub",
|
|
3403
|
+
"count",
|
|
3404
|
+
"counts",
|
|
3405
|
+
"type",
|
|
3406
|
+
"name",
|
|
3407
|
+
"len",
|
|
3408
|
+
"length",
|
|
3409
|
+
"size",
|
|
3410
|
+
"max",
|
|
3411
|
+
"min",
|
|
3412
|
+
"ttl",
|
|
3413
|
+
"timeout",
|
|
3414
|
+
"expiry",
|
|
3415
|
+
"expires",
|
|
3416
|
+
"mode"
|
|
3417
|
+
]);
|
|
3418
|
+
/************************************************************
|
|
3419
|
+
* TRUE if `name` is the name of a secret: a password, a token,
|
|
3420
|
+
* a key... Any case. As the C kernel's is_secret_name().
|
|
3421
|
+
************************************************************/
|
|
3422
|
+
function is_secret_name(name) {
|
|
3423
|
+
if (typeof name !== "string" || name.length < 3) return false;
|
|
3424
|
+
let lower = name.toLowerCase();
|
|
3425
|
+
let hit = false;
|
|
3426
|
+
for (const part of SECRET_NAME_PARTS) if (lower.indexOf(part) >= 0) {
|
|
3427
|
+
hit = true;
|
|
3428
|
+
break;
|
|
3429
|
+
}
|
|
3430
|
+
if (!hit) {
|
|
3431
|
+
let joined = lower.replace(/[_\-. \t]/g, "");
|
|
3432
|
+
for (const part of SECRET_NAME_JOINED) if (joined.indexOf(part) >= 0) {
|
|
3433
|
+
hit = true;
|
|
3434
|
+
break;
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
if (!hit) hit = lower.indexOf("priv") >= 0 && lower.indexOf("key") >= 0;
|
|
3438
|
+
if (!hit) return false;
|
|
3439
|
+
for (const segment of lower.split(/[_\-. \t]/)) if (NOT_SECRET_SEGMENTS.has(segment)) return false;
|
|
3440
|
+
return true;
|
|
3441
|
+
}
|
|
3442
|
+
/************************************************************
|
|
3443
|
+
* Where an unquoted secret value that begins at `p` ends: at
|
|
3444
|
+
* the end, at the quote that closes an outer quoted value, or
|
|
3445
|
+
* before the next "word=" -- a plain word after a blank is still
|
|
3446
|
+
* part of it ("password=correct horse battery", "password=
|
|
3447
|
+
* hunter2"). As the C kernel's inline_secret_value_end().
|
|
3448
|
+
************************************************************/
|
|
3449
|
+
function inline_secret_value_end(str, p, outer) {
|
|
3450
|
+
const blank = (c) => c === " " || c === " ";
|
|
3451
|
+
const closes_outer = (i) => outer && str[i] === outer && (i + 1 >= str.length || blank(str[i + 1]));
|
|
3452
|
+
let end = p;
|
|
3453
|
+
while (true) {
|
|
3454
|
+
while (end < str.length && !blank(str[end])) {
|
|
3455
|
+
if (closes_outer(end)) return end;
|
|
3456
|
+
end++;
|
|
3457
|
+
}
|
|
3458
|
+
if (end >= str.length) return end;
|
|
3459
|
+
let w = end;
|
|
3460
|
+
while (w < str.length && blank(str[w])) w++;
|
|
3461
|
+
if (w >= str.length || closes_outer(w)) return end;
|
|
3462
|
+
for (let e = w; e < str.length && !blank(str[e]) && !closes_outer(e); e++) if (str[e] === "=" && e > w) return end;
|
|
3463
|
+
end = w;
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3466
|
+
/************************************************************
|
|
3467
|
+
* A text (a command line) with the value of every "name=value"
|
|
3468
|
+
* whose name is a secret's written as "********", quoted or not
|
|
3469
|
+
* (and the "value" of a write-attr whose attribute names a
|
|
3470
|
+
* secret). The rest as it is. Return null when there was nothing
|
|
3471
|
+
* to mask. As the C kernel's mask_secrets_inline().
|
|
3472
|
+
************************************************************/
|
|
3473
|
+
var MASK_MAX_NAME = 128;
|
|
3474
|
+
var MASK_MAX_BYTES = 4194304;
|
|
3475
|
+
var MASK_TOO_LARGE = "<not shown: too large to mask>";
|
|
3476
|
+
function mask_secrets_inline(str) {
|
|
3477
|
+
if (typeof str !== "string" || str.indexOf("=") < 0) return null;
|
|
3478
|
+
if (str.length > MASK_MAX_BYTES) return MASK_TOO_LARGE;
|
|
3479
|
+
let value_is_secret = false;
|
|
3480
|
+
let re_attr = /(^|[ \t])attribute=["']?([^ \t"']*)/g;
|
|
3481
|
+
let m;
|
|
3482
|
+
while ((m = re_attr.exec(str)) !== null) if (is_secret_name(m[2].slice(-128))) value_is_secret = true;
|
|
3483
|
+
let parts = [];
|
|
3484
|
+
let copied = 0;
|
|
3485
|
+
let changed = false;
|
|
3486
|
+
let outer = "";
|
|
3487
|
+
let word = 0;
|
|
3488
|
+
let p = 0;
|
|
3489
|
+
const is_blank_or_end = (i) => i >= str.length || str[i] === " " || str[i] === " ";
|
|
3490
|
+
while (p < str.length) {
|
|
3491
|
+
let c = str[p];
|
|
3492
|
+
if (c === " " || c === " ") {
|
|
3493
|
+
p++;
|
|
3494
|
+
word = p;
|
|
3495
|
+
continue;
|
|
3496
|
+
}
|
|
3497
|
+
if (c === "\"" || c === "'") {
|
|
3498
|
+
if (!outer && (p === 0 || str[p - 1] === " " || str[p - 1] === " " || str[p - 1] === "=")) outer = c;
|
|
3499
|
+
else if (c === outer && is_blank_or_end(p + 1)) outer = "";
|
|
3500
|
+
}
|
|
3501
|
+
if (c !== "=") {
|
|
3502
|
+
p++;
|
|
3503
|
+
continue;
|
|
3504
|
+
}
|
|
3505
|
+
let name = str.substring(Math.max(word, p - MASK_MAX_NAME), p);
|
|
3506
|
+
word = p + 1;
|
|
3507
|
+
if (!(is_secret_name(name) || value_is_secret && name.toLowerCase() === "value")) {
|
|
3508
|
+
p++;
|
|
3509
|
+
continue;
|
|
3510
|
+
}
|
|
3511
|
+
p++;
|
|
3512
|
+
let quote = str[p] === "\"" || str[p] === "'" ? str[p] : "";
|
|
3513
|
+
let end;
|
|
3514
|
+
if (quote) {
|
|
3515
|
+
end = p + 1;
|
|
3516
|
+
while (end < str.length && str[end] !== quote) end++;
|
|
3517
|
+
if (str[end] === quote) end++;
|
|
3518
|
+
} else end = inline_secret_value_end(str, p, outer);
|
|
3519
|
+
if (end > p) {
|
|
3520
|
+
parts.push(str.substring(copied, p));
|
|
3521
|
+
parts.push("********");
|
|
3522
|
+
copied = end;
|
|
3523
|
+
changed = true;
|
|
3524
|
+
}
|
|
3525
|
+
p = end;
|
|
3526
|
+
word = p;
|
|
3527
|
+
}
|
|
3528
|
+
if (!changed) return null;
|
|
3529
|
+
parts.push(str.substring(copied));
|
|
3530
|
+
return parts.join("");
|
|
3531
|
+
}
|
|
3532
|
+
/************************************************************
|
|
3533
|
+
* A json as a log or a trace may show it: at any depth, the
|
|
3534
|
+
* value of a key with a secret's name is "********", whatever
|
|
3535
|
+
* its type (not an absent one, a null or an empty string); so is
|
|
3536
|
+
* the "value" of a dict whose "attribute" names a secret; and a
|
|
3537
|
+
* string is masked as mask_secrets_inline(). Return a masked
|
|
3538
|
+
* copy, or `jn` itself when there was nothing to mask. As the C
|
|
3539
|
+
* kernel's json_mask_secrets().
|
|
3540
|
+
*
|
|
3541
|
+
* Only JSON is walked: plain objects (their prototype is
|
|
3542
|
+
* Object.prototype or null) and arrays. Anything else -- a gobj,
|
|
3543
|
+
* a DOM node, a class instance, a typed array, a function -- is
|
|
3544
|
+
* passed as it is, never walked, as trace_json() always showed it
|
|
3545
|
+
* (a kw may carry a gobj: its parent and children make a cycle).
|
|
3546
|
+
* A plain object met twice is masked once, the same everywhere; a
|
|
3547
|
+
* cycle back to one is "<cycle>"; below MASK_MAX_DEPTH levels
|
|
3548
|
+
* (64, as in C) nothing is shown.
|
|
3549
|
+
* It never throws: a failure is the placeholder below.
|
|
3550
|
+
************************************************************/
|
|
3551
|
+
var MASK_MAX_DEPTH = 64;
|
|
3552
|
+
var MASK_FAILED = "<not shown: the masking failed>";
|
|
3553
|
+
function is_plain_object(value) {
|
|
3554
|
+
if (value === null || typeof value !== "object") return false;
|
|
3555
|
+
let proto = Object.getPrototypeOf(value);
|
|
3556
|
+
return proto === Object.prototype || proto === null;
|
|
3557
|
+
}
|
|
3558
|
+
var MASK_IN_PROGRESS = Symbol("mask-in-progress");
|
|
3559
|
+
function _json_mask_secrets(jn, memo, depth, budget) {
|
|
3560
|
+
if (typeof jn === "string") {
|
|
3561
|
+
if (jn.length > budget.left) {
|
|
3562
|
+
budget.left = 0;
|
|
3563
|
+
return MASK_TOO_LARGE;
|
|
3564
|
+
}
|
|
3565
|
+
budget.left -= jn.length;
|
|
3566
|
+
let masked = mask_secrets_inline(jn);
|
|
3567
|
+
return masked !== null ? masked : jn;
|
|
3568
|
+
}
|
|
3569
|
+
let is_array = Array.isArray(jn);
|
|
3570
|
+
if (!is_array && !is_plain_object(jn)) return jn;
|
|
3571
|
+
if (budget.left <= 0) return MASK_TOO_LARGE;
|
|
3572
|
+
if (memo.has(jn)) {
|
|
3573
|
+
let seen = memo.get(jn);
|
|
3574
|
+
return seen === MASK_IN_PROGRESS ? "<cycle>" : seen;
|
|
3575
|
+
}
|
|
3576
|
+
if (depth >= MASK_MAX_DEPTH) return "<deeper not shown>";
|
|
3577
|
+
budget.left -= 1;
|
|
3578
|
+
memo.set(jn, MASK_IN_PROGRESS);
|
|
3579
|
+
let changed = false;
|
|
3580
|
+
let truncated = false;
|
|
3581
|
+
let result;
|
|
3582
|
+
if (is_array) {
|
|
3583
|
+
result = [];
|
|
3584
|
+
for (let i = 0; i < jn.length; i++) {
|
|
3585
|
+
if (budget.left <= 0) {
|
|
3586
|
+
truncated = true;
|
|
3587
|
+
break;
|
|
3588
|
+
}
|
|
3589
|
+
budget.left -= 1;
|
|
3590
|
+
let shown = _json_mask_secrets(jn[i], memo, depth + 1, budget);
|
|
3591
|
+
if (shown !== jn[i]) changed = true;
|
|
3592
|
+
result.push(shown);
|
|
3593
|
+
}
|
|
3594
|
+
if (truncated) result.push(MASK_TOO_LARGE);
|
|
3595
|
+
} else {
|
|
3596
|
+
result = Object.create(Object.getPrototypeOf(jn));
|
|
3597
|
+
let value_is_secret = typeof jn.attribute === "string" && is_secret_name(jn.attribute.slice(-128));
|
|
3598
|
+
for (const key in jn) {
|
|
3599
|
+
if (!Object.prototype.hasOwnProperty.call(jn, key)) continue;
|
|
3600
|
+
if (budget.left <= 0) {
|
|
3601
|
+
truncated = true;
|
|
3602
|
+
break;
|
|
3603
|
+
}
|
|
3604
|
+
budget.left -= 1 + key.length;
|
|
3605
|
+
let value = jn[key];
|
|
3606
|
+
let shown;
|
|
3607
|
+
if ((is_secret_name(key.slice(-128)) || value_is_secret && key === "value") && value !== void 0 && value !== null && value !== "") shown = "********";
|
|
3608
|
+
else shown = _json_mask_secrets(value, memo, depth + 1, budget);
|
|
3609
|
+
if (shown !== value) changed = true;
|
|
3610
|
+
result[key] = shown;
|
|
3611
|
+
}
|
|
3612
|
+
if (truncated) result["<more>"] = MASK_TOO_LARGE;
|
|
3613
|
+
}
|
|
3614
|
+
if (!changed && !truncated) result = jn;
|
|
3615
|
+
memo.set(jn, result);
|
|
3616
|
+
return result;
|
|
3617
|
+
}
|
|
3618
|
+
function json_mask_secrets(jn) {
|
|
3619
|
+
try {
|
|
3620
|
+
return _json_mask_secrets(jn, /* @__PURE__ */ new WeakMap(), 0, { left: MASK_MAX_BYTES });
|
|
3621
|
+
} catch (e) {
|
|
3622
|
+
return MASK_FAILED;
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
/************************************************************
|
|
3626
|
+
* trace_json() of a json that can hold a credential: what
|
|
3627
|
+
* json_mask_secrets() masks is shown masked
|
|
3628
|
+
************************************************************/
|
|
3629
|
+
function trace_json_masked(jn, msg) {
|
|
3630
|
+
trace_json(json_mask_secrets(jn), msg);
|
|
3631
|
+
}
|
|
3632
|
+
/************************************************************
|
|
3225
3633
|
* Duplicate an object (new references)
|
|
3226
3634
|
* using the modern structuredClone (Deep copy of a single object)
|
|
3227
3635
|
************************************************************/
|
|
@@ -3494,6 +3902,8 @@ function cmp_two_simple_json(jn_var1, jn_var2) {
|
|
|
3494
3902
|
if (is_number(jn_var1) || is_number(jn_var2)) {
|
|
3495
3903
|
let val1 = Number(jn_var1);
|
|
3496
3904
|
let val2 = Number(jn_var2);
|
|
3905
|
+
if (Number.isNaN(val1)) val1 = 0;
|
|
3906
|
+
if (Number.isNaN(val2)) val2 = 0;
|
|
3497
3907
|
if (val1 > val2) return 1;
|
|
3498
3908
|
else if (val1 < val2) return -1;
|
|
3499
3909
|
else return 0;
|
|
@@ -3523,8 +3933,8 @@ function strstr(haystack, needle, bool) {
|
|
|
3523
3933
|
***************************************************************************/
|
|
3524
3934
|
function is_metadata_key(key) {
|
|
3525
3935
|
if (!is_string(key)) return false;
|
|
3526
|
-
let i;
|
|
3527
|
-
for (
|
|
3936
|
+
let i = 0;
|
|
3937
|
+
for (; i < key.length; i++) {
|
|
3528
3938
|
if (key[i] !== "_") break;
|
|
3529
3939
|
if (i > 2) break;
|
|
3530
3940
|
}
|
|
@@ -3535,8 +3945,8 @@ function is_metadata_key(key) {
|
|
|
3535
3945
|
***************************************************************************/
|
|
3536
3946
|
function is_private_key(key) {
|
|
3537
3947
|
if (!is_string(key)) return false;
|
|
3538
|
-
let i;
|
|
3539
|
-
for (
|
|
3948
|
+
let i = 0;
|
|
3949
|
+
for (; i < key.length; i++) {
|
|
3540
3950
|
if (key[i] !== "_") break;
|
|
3541
3951
|
if (i > 2) break;
|
|
3542
3952
|
}
|
|
@@ -3561,6 +3971,28 @@ function kw_has_key(kw, key) {
|
|
|
3561
3971
|
return false;
|
|
3562
3972
|
}
|
|
3563
3973
|
/************************************************************
|
|
3974
|
+
* A key that reaches the prototype chain instead of the data:
|
|
3975
|
+
* "__proto__", "constructor" or "prototype" when the object
|
|
3976
|
+
* does not hold it as its OWN key. A walk through one of them
|
|
3977
|
+
* read, or WROTE, Object.prototype: the flat id
|
|
3978
|
+
* "__proto__`polluted" set a key on every object of the page.
|
|
3979
|
+
* In C they are keys like any other, so here too: read them
|
|
3980
|
+
* only as own keys, and write "__proto__" as an own key.
|
|
3981
|
+
************************************************************/
|
|
3982
|
+
function is_prototype_segment(obj, key) {
|
|
3983
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") return !Object.prototype.hasOwnProperty.call(obj, key);
|
|
3984
|
+
return false;
|
|
3985
|
+
}
|
|
3986
|
+
function set_own_key(obj, key, value) {
|
|
3987
|
+
if (key === "__proto__") Object.defineProperty(obj, key, {
|
|
3988
|
+
value,
|
|
3989
|
+
writable: true,
|
|
3990
|
+
enumerable: true,
|
|
3991
|
+
configurable: true
|
|
3992
|
+
});
|
|
3993
|
+
else obj[key] = value;
|
|
3994
|
+
}
|
|
3995
|
+
/************************************************************
|
|
3564
3996
|
* The value at `path` (keys joined by a backtick), as the C
|
|
3565
3997
|
* kw_find_path() finds it: undefined when it is not there.
|
|
3566
3998
|
* A kw that is not a dict or a list is LOGGED ("kw must be list
|
|
@@ -3587,7 +4019,12 @@ function kw_find_path(gobj, kw, path, verbose) {
|
|
|
3587
4019
|
}
|
|
3588
4020
|
let ss = path.split("`");
|
|
3589
4021
|
let len = ss.length;
|
|
3590
|
-
for (let i = 0; i < len
|
|
4022
|
+
for (let i = 0; i < len; i++) {
|
|
4023
|
+
if (is_prototype_segment(kw, ss[i])) {
|
|
4024
|
+
if (verbose) log_error(`${prefix}path not found: '${path}'`);
|
|
4025
|
+
return;
|
|
4026
|
+
}
|
|
4027
|
+
if (i === len - 1) break;
|
|
3591
4028
|
kw = kw[ss[i]];
|
|
3592
4029
|
if (kw === void 0 || kw === null) {
|
|
3593
4030
|
if (verbose) log_error(`${prefix}path not found: '${path}'`);
|
|
@@ -3647,7 +4084,7 @@ function kw_get_bool(gobj, kw, path, default_value, flag) {
|
|
|
3647
4084
|
return v;
|
|
3648
4085
|
} else if (required) {
|
|
3649
4086
|
log_error(`path not found: '${path}'`);
|
|
3650
|
-
|
|
4087
|
+
trace_json_masked(kw);
|
|
3651
4088
|
}
|
|
3652
4089
|
return Boolean(default_value);
|
|
3653
4090
|
}
|
|
@@ -3661,11 +4098,11 @@ function kw_get_bool(gobj, kw, path, default_value, flag) {
|
|
|
3661
4098
|
} else if (wild && b === null) value = false;
|
|
3662
4099
|
else if (wild) {
|
|
3663
4100
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
|
|
3664
|
-
|
|
4101
|
+
trace_json_masked(kw);
|
|
3665
4102
|
return false;
|
|
3666
4103
|
} else {
|
|
3667
4104
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json boolean: '${path}'`);
|
|
3668
|
-
|
|
4105
|
+
trace_json_masked(kw);
|
|
3669
4106
|
return Boolean(default_value);
|
|
3670
4107
|
}
|
|
3671
4108
|
if (extract) kw_delete(gobj, kw, path);
|
|
@@ -3715,7 +4152,7 @@ function kw_get_int(gobj, kw, path, default_value, flag) {
|
|
|
3715
4152
|
return v;
|
|
3716
4153
|
} else if (required) {
|
|
3717
4154
|
log_error(`path not found: '${path}'`);
|
|
3718
|
-
|
|
4155
|
+
trace_json_masked(kw);
|
|
3719
4156
|
}
|
|
3720
4157
|
return parseInt(default_value);
|
|
3721
4158
|
}
|
|
@@ -3723,14 +4160,14 @@ function kw_get_int(gobj, kw, path, default_value, flag) {
|
|
|
3723
4160
|
if (is_number(v)) value = Math.trunc(v);
|
|
3724
4161
|
else if (!wild) {
|
|
3725
4162
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json integer: '${path}'`);
|
|
3726
|
-
|
|
4163
|
+
trace_json_masked(kw);
|
|
3727
4164
|
return parseInt(default_value);
|
|
3728
4165
|
} else if (is_boolean(v)) value = v ? 1 : 0;
|
|
3729
4166
|
else if (is_string(v)) value = strtoll_base0(v);
|
|
3730
4167
|
else if (v === null) value = 0;
|
|
3731
4168
|
else {
|
|
3732
4169
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
|
|
3733
|
-
|
|
4170
|
+
trace_json_masked(kw);
|
|
3734
4171
|
return 0;
|
|
3735
4172
|
}
|
|
3736
4173
|
if (extract) kw_delete(gobj, kw, path);
|
|
@@ -3762,7 +4199,7 @@ function kw_get_real(gobj, kw, path, default_value, flag) {
|
|
|
3762
4199
|
return v;
|
|
3763
4200
|
} else if (required) {
|
|
3764
4201
|
log_error(`path not found: '${path}'`);
|
|
3765
|
-
|
|
4202
|
+
trace_json_masked(kw);
|
|
3766
4203
|
}
|
|
3767
4204
|
return Number(default_value);
|
|
3768
4205
|
}
|
|
@@ -3770,7 +4207,7 @@ function kw_get_real(gobj, kw, path, default_value, flag) {
|
|
|
3770
4207
|
if (is_number(v)) value = v;
|
|
3771
4208
|
else if (!wild) {
|
|
3772
4209
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json real: '${path}'`);
|
|
3773
|
-
|
|
4210
|
+
trace_json_masked(kw);
|
|
3774
4211
|
return Number(default_value);
|
|
3775
4212
|
} else if (is_boolean(v)) value = v ? 1 : 0;
|
|
3776
4213
|
else if (is_string(v)) {
|
|
@@ -3779,7 +4216,7 @@ function kw_get_real(gobj, kw, path, default_value, flag) {
|
|
|
3779
4216
|
} else if (v === null) value = 0;
|
|
3780
4217
|
else {
|
|
3781
4218
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
|
|
3782
|
-
|
|
4219
|
+
trace_json_masked(kw);
|
|
3783
4220
|
return 0;
|
|
3784
4221
|
}
|
|
3785
4222
|
if (extract) kw_delete(gobj, kw, path);
|
|
@@ -3831,14 +4268,14 @@ function kw_get_str(gobj, kw, path, default_value, flag) {
|
|
|
3831
4268
|
return default_value;
|
|
3832
4269
|
} else if (required && !kw_path_holds_key(kw, path)) {
|
|
3833
4270
|
log_error(`path not found: '${path}'`);
|
|
3834
|
-
|
|
4271
|
+
trace_json_masked(kw);
|
|
3835
4272
|
}
|
|
3836
4273
|
return default_value;
|
|
3837
4274
|
}
|
|
3838
4275
|
if (!is_string(v)) {
|
|
3839
4276
|
if (v !== null) {
|
|
3840
4277
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json str: '${path}'`);
|
|
3841
|
-
|
|
4278
|
+
trace_json_masked(kw);
|
|
3842
4279
|
}
|
|
3843
4280
|
return default_value;
|
|
3844
4281
|
}
|
|
@@ -3861,7 +4298,7 @@ function kw_get_pointer(gobj, kw, path, default_value, flag) {
|
|
|
3861
4298
|
return v;
|
|
3862
4299
|
} else if (required) {
|
|
3863
4300
|
log_error(`path not found: '${path}'`);
|
|
3864
|
-
|
|
4301
|
+
trace_json_masked(kw);
|
|
3865
4302
|
}
|
|
3866
4303
|
return default_value;
|
|
3867
4304
|
}
|
|
@@ -3888,14 +4325,14 @@ function kw_get_dict(gobj, kw, path, default_value, flag) {
|
|
|
3888
4325
|
}
|
|
3889
4326
|
if (required) {
|
|
3890
4327
|
log_error(`path not found: '${path}'`);
|
|
3891
|
-
|
|
4328
|
+
trace_json_masked(kw);
|
|
3892
4329
|
}
|
|
3893
4330
|
return default_value;
|
|
3894
4331
|
}
|
|
3895
4332
|
if (!is_object(v)) {
|
|
3896
4333
|
if (required) {
|
|
3897
4334
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json dict: '${path}'`);
|
|
3898
|
-
|
|
4335
|
+
trace_json_masked(kw);
|
|
3899
4336
|
}
|
|
3900
4337
|
return default_value;
|
|
3901
4338
|
}
|
|
@@ -3918,7 +4355,7 @@ function kw_get_dict_value(gobj, kw, path, default_value, flag) {
|
|
|
3918
4355
|
return v;
|
|
3919
4356
|
} else if (required) {
|
|
3920
4357
|
log_error(`path not found: '${path}'`);
|
|
3921
|
-
|
|
4358
|
+
trace_json_masked(kw);
|
|
3922
4359
|
}
|
|
3923
4360
|
return default_value;
|
|
3924
4361
|
}
|
|
@@ -3946,14 +4383,14 @@ function kw_get_list(gobj, kw, path, default_value, flag) {
|
|
|
3946
4383
|
}
|
|
3947
4384
|
if (required) {
|
|
3948
4385
|
log_error(`path not found: '${path}'`);
|
|
3949
|
-
|
|
4386
|
+
trace_json_masked(kw);
|
|
3950
4387
|
}
|
|
3951
4388
|
return default_value;
|
|
3952
4389
|
}
|
|
3953
4390
|
if (!is_array(v)) {
|
|
3954
4391
|
if (required) {
|
|
3955
4392
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json list: '${path}'`);
|
|
3956
|
-
|
|
4393
|
+
trace_json_masked(kw);
|
|
3957
4394
|
}
|
|
3958
4395
|
return default_value;
|
|
3959
4396
|
}
|
|
@@ -3970,17 +4407,13 @@ function kw_set_dict_value(gobj, kw, path, value) {
|
|
|
3970
4407
|
return -1;
|
|
3971
4408
|
}
|
|
3972
4409
|
let ss = path.split("`");
|
|
3973
|
-
if (ss.length <= 1) {
|
|
3974
|
-
kw[path] = value;
|
|
3975
|
-
return 0;
|
|
3976
|
-
}
|
|
3977
4410
|
let len = ss.length;
|
|
3978
4411
|
for (let i = 0; i < len; i++) {
|
|
3979
4412
|
let key = ss[i];
|
|
3980
|
-
if (i === len - 1) kw
|
|
4413
|
+
if (i === len - 1) set_own_key(kw, key, value);
|
|
3981
4414
|
else {
|
|
3982
|
-
let seg = kw[key];
|
|
3983
|
-
if (seg === void 0) kw
|
|
4415
|
+
let seg = is_prototype_segment(kw, key) ? void 0 : kw[key];
|
|
4416
|
+
if (seg === void 0) set_own_key(kw, key, {});
|
|
3984
4417
|
else if (!is_object(seg) && !is_array(seg)) {
|
|
3985
4418
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}kw_set_dict_value(): segment '${key}' is not a dict or a list: '${path}'`);
|
|
3986
4419
|
return -1;
|
|
@@ -4035,9 +4468,9 @@ function _kw_match_simple(kw, jn_filter, prefix_path) {
|
|
|
4035
4468
|
if (!matched) break;
|
|
4036
4469
|
continue;
|
|
4037
4470
|
}
|
|
4038
|
-
let jn_record_value = kw_get_dict_value(0, kw, path, 0, 0);
|
|
4039
|
-
if (
|
|
4040
|
-
if (
|
|
4471
|
+
let jn_record_value = kw_get_dict_value(0, kw, path, void 0, 0);
|
|
4472
|
+
if (jn_record_value === void 0) jn_record_value = json_object_get(kw, path);
|
|
4473
|
+
if (jn_record_value === void 0) {
|
|
4041
4474
|
matched = false;
|
|
4042
4475
|
break;
|
|
4043
4476
|
}
|
|
@@ -4156,10 +4589,11 @@ If paths are empty return empty
|
|
|
4156
4589
|
***************************************************************************/
|
|
4157
4590
|
function kw_clone_by_not_keys(gobj, kw, keys, verbose) {
|
|
4158
4591
|
let kw_clone = {};
|
|
4592
|
+
if (!is_object(kw)) return kw_clone;
|
|
4159
4593
|
json_object_update(kw_clone, kw);
|
|
4160
4594
|
if (is_string(keys) && !empty_string(keys)) {
|
|
4161
4595
|
let key = keys;
|
|
4162
|
-
if (
|
|
4596
|
+
if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
|
|
4163
4597
|
else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
|
|
4164
4598
|
} else if (is_object(keys) && json_object_size(keys) > 0) {
|
|
4165
4599
|
for (let key of Object.keys(keys)) if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
|
|
@@ -5119,9 +5553,15 @@ parent: document.body
|
|
|
5119
5553
|
* will be 'data-i18n' attr
|
|
5120
5554
|
*
|
|
5121
5555
|
* content -> string | [createElement2() or parameters of createElement2]
|
|
5556
|
+
* | HTMLElement | SVGElement | Text
|
|
5122
5557
|
* if string begins with '<' then
|
|
5123
5558
|
* it will be converted to HTMLElement
|
|
5124
5559
|
* content = createOneHtml(string)
|
|
5560
|
+
* ⚠️ So a string is MARKUP when it starts with '<': never
|
|
5561
|
+
* pass DATA (a value from a backend, a name a user typed)
|
|
5562
|
+
* as a bare string, or "<img src=x onerror=...>" runs.
|
|
5563
|
+
* Pass it as a Text node, which is always text:
|
|
5564
|
+
* ['span', {}, document.createTextNode(value)]
|
|
5125
5565
|
* if attrs['i18n'] is not empty then (or 'data-i18n' or 'data_i18next')
|
|
5126
5566
|
* it will be overridden with the translation
|
|
5127
5567
|
* content = translate(attrs['i18n']));
|
|
@@ -5560,7 +6000,7 @@ function flat2json(flat) {
|
|
|
5560
6000
|
current[seg] = flat[key];
|
|
5561
6001
|
} else {
|
|
5562
6002
|
if (Object.prototype.hasOwnProperty.call(current, seg)) throw new Error(`flat2json: '${key}' is written twice, or once as a value and once as a container`);
|
|
5563
|
-
current
|
|
6003
|
+
set_own_key(current, seg, flat[key]);
|
|
5564
6004
|
}
|
|
5565
6005
|
break;
|
|
5566
6006
|
}
|
|
@@ -5573,10 +6013,10 @@ function flat2json(flat) {
|
|
|
5573
6013
|
current[seg] = child;
|
|
5574
6014
|
}
|
|
5575
6015
|
} else {
|
|
5576
|
-
child = current[seg];
|
|
6016
|
+
child = is_prototype_segment(current, seg) ? void 0 : current[seg];
|
|
5577
6017
|
if (child === void 0) {
|
|
5578
6018
|
child = next_is_index ? [] : {};
|
|
5579
|
-
current
|
|
6019
|
+
set_own_key(current, seg, child);
|
|
5580
6020
|
}
|
|
5581
6021
|
}
|
|
5582
6022
|
if (child === null || typeof child !== "object") throw new Error(`flat2json: '${key}' walks through a value: the same id is a leaf and a container at once`);
|
|
@@ -6339,6 +6779,7 @@ function mt_stop$1(gobj) {
|
|
|
6339
6779
|
***************************************************************/
|
|
6340
6780
|
function mt_play(gobj) {
|
|
6341
6781
|
let default_service = gobj_default_service();
|
|
6782
|
+
if (!default_service) return 0;
|
|
6342
6783
|
if (!gobj_is_running(default_service)) gobj_start(default_service);
|
|
6343
6784
|
if (!gobj_is_playing(default_service)) gobj_play(default_service);
|
|
6344
6785
|
return 0;
|
|
@@ -6347,7 +6788,8 @@ function mt_play(gobj) {
|
|
|
6347
6788
|
* Framework Method: Pause
|
|
6348
6789
|
***************************************************************/
|
|
6349
6790
|
function mt_pause(gobj) {
|
|
6350
|
-
|
|
6791
|
+
let default_service = gobj_default_service();
|
|
6792
|
+
if (default_service && gobj_is_playing(default_service)) gobj_pause(default_service);
|
|
6351
6793
|
return 0;
|
|
6352
6794
|
}
|
|
6353
6795
|
/***************************************************************
|
|
@@ -6603,6 +7045,7 @@ var __gclass__ = null;
|
|
|
6603
7045
|
function mt_create(gobj) {
|
|
6604
7046
|
let priv = gobj.priv;
|
|
6605
7047
|
priv.gobj_timer = gobj_create_pure_child(gobj_name(gobj), "C_TIMER", {}, gobj);
|
|
7048
|
+
priv.ws_seq = 0;
|
|
6606
7049
|
priv.url = gobj_read_str_attr(gobj, "url");
|
|
6607
7050
|
priv.remote_yuno_name = gobj_read_str_attr(gobj, "remote_yuno_name");
|
|
6608
7051
|
priv.remote_yuno_role = gobj_read_str_attr(gobj, "remote_yuno_role");
|
|
@@ -6637,6 +7080,16 @@ function mt_writing(gobj, path) {
|
|
|
6637
7080
|
function mt_start(gobj) {
|
|
6638
7081
|
let priv = gobj.priv;
|
|
6639
7082
|
priv.retry_ms = 0;
|
|
7083
|
+
if (gobj_current_state(gobj) !== "ST_DISCONNECTED") {
|
|
7084
|
+
gobj_send_event(gobj, "EV_ON_CLOSE", {
|
|
7085
|
+
url: priv.url,
|
|
7086
|
+
ws_seq: priv.ws_seq,
|
|
7087
|
+
code: 1e3,
|
|
7088
|
+
reason: "restarted",
|
|
7089
|
+
was_clean: true
|
|
7090
|
+
}, gobj);
|
|
7091
|
+
clear_timeout(priv.gobj_timer);
|
|
7092
|
+
}
|
|
6640
7093
|
priv.websocket = setup_websocket(gobj);
|
|
6641
7094
|
return 0;
|
|
6642
7095
|
}
|
|
@@ -6771,10 +7224,16 @@ function setup_websocket(gobj) {
|
|
|
6771
7224
|
log_error(`${gobj_short_name(gobj)}: Failed to initialize WebSocket.`);
|
|
6772
7225
|
return null;
|
|
6773
7226
|
}
|
|
7227
|
+
const ws_seq = ++gobj.priv.ws_seq;
|
|
6774
7228
|
websocket.onopen = () => {
|
|
6775
|
-
|
|
7229
|
+
if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
|
|
7230
|
+
gobj_send_event(gobj, "EV_ON_OPEN", {
|
|
7231
|
+
url,
|
|
7232
|
+
ws_seq
|
|
7233
|
+
}, gobj);
|
|
6776
7234
|
};
|
|
6777
7235
|
websocket.onmessage = (e) => {
|
|
7236
|
+
if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
|
|
6778
7237
|
gobj_send_event(gobj, "EV_ON_MESSAGE", {
|
|
6779
7238
|
url,
|
|
6780
7239
|
data: e.data
|
|
@@ -6782,9 +7241,13 @@ function setup_websocket(gobj) {
|
|
|
6782
7241
|
};
|
|
6783
7242
|
websocket.onclose = (e) => {
|
|
6784
7243
|
if (gobj_is_destroying(gobj)) return;
|
|
7244
|
+
if (ws_seq !== gobj.priv.ws_seq) return;
|
|
6785
7245
|
if (!gobj_read_bool_attr(gobj_yuno(), "browser_beforeunload")) gobj_send_event(gobj, "EV_ON_CLOSE", {
|
|
6786
7246
|
url,
|
|
6787
|
-
|
|
7247
|
+
ws_seq,
|
|
7248
|
+
code: e.code,
|
|
7249
|
+
reason: e.reason,
|
|
7250
|
+
was_clean: e.wasClean
|
|
6788
7251
|
}, gobj);
|
|
6789
7252
|
else log_warning("Close websocket by unload page");
|
|
6790
7253
|
};
|
|
@@ -6805,7 +7268,7 @@ function close_websocket(gobj, code = 1e3, reason = "") {
|
|
|
6805
7268
|
try {
|
|
6806
7269
|
websocket.close(code, reason);
|
|
6807
7270
|
} catch (e) {
|
|
6808
|
-
log_error(
|
|
7271
|
+
log_error(`${gobj_short_name(gobj)}: Error closing WebSocket: ${e.message}`);
|
|
6809
7272
|
}
|
|
6810
7273
|
}
|
|
6811
7274
|
/***************************************************************
|
|
@@ -6815,7 +7278,7 @@ function trace_inter_event(gobj, prefix, iev) {
|
|
|
6815
7278
|
let hora = current_timestamp();
|
|
6816
7279
|
try {
|
|
6817
7280
|
log_debug("\n" + hora + " " + prefix + "\n");
|
|
6818
|
-
|
|
7281
|
+
trace_json_masked(iev);
|
|
6819
7282
|
} catch (e) {
|
|
6820
7283
|
log_debug("ERROR in trace_inter_event: " + e);
|
|
6821
7284
|
}
|
|
@@ -6931,29 +7394,29 @@ function iev_create_from_json(gobj, data) {
|
|
|
6931
7394
|
try {
|
|
6932
7395
|
x = JSON.parse(data);
|
|
6933
7396
|
} catch (e) {
|
|
6934
|
-
|
|
7397
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event json: ${e}`);
|
|
6935
7398
|
return null;
|
|
6936
7399
|
}
|
|
6937
7400
|
if (!(x instanceof Object)) {
|
|
6938
|
-
|
|
7401
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: websocket data not a json object`);
|
|
6939
7402
|
return null;
|
|
6940
7403
|
}
|
|
6941
7404
|
let event = x["event"];
|
|
6942
7405
|
if (!event) {
|
|
6943
|
-
|
|
7406
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: no event`);
|
|
6944
7407
|
return null;
|
|
6945
7408
|
}
|
|
6946
7409
|
if (typeof event !== "string") {
|
|
6947
|
-
|
|
7410
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: event not a string`);
|
|
6948
7411
|
return null;
|
|
6949
7412
|
}
|
|
6950
7413
|
let kw = x["kw"];
|
|
6951
7414
|
if (!kw) {
|
|
6952
|
-
|
|
7415
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_kw: no kw`);
|
|
6953
7416
|
return null;
|
|
6954
7417
|
}
|
|
6955
7418
|
if (!(kw instanceof Object)) {
|
|
6956
|
-
|
|
7419
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: kw not a json object`);
|
|
6957
7420
|
return null;
|
|
6958
7421
|
}
|
|
6959
7422
|
return {
|
|
@@ -7013,10 +7476,9 @@ function ac_on_open(gobj, event, kw, src) {
|
|
|
7013
7476
|
***************************************************************/
|
|
7014
7477
|
function ac_on_close(gobj, event, kw, src) {
|
|
7015
7478
|
let priv = gobj.priv;
|
|
7016
|
-
let e = kw.e;
|
|
7017
7479
|
let url = kw.url;
|
|
7018
7480
|
set_remote_log_functions();
|
|
7019
|
-
log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${
|
|
7481
|
+
log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
|
|
7020
7482
|
if (priv.websocket) {
|
|
7021
7483
|
priv.websocket.onopen = null;
|
|
7022
7484
|
priv.websocket.onmessage = null;
|
|
@@ -7033,15 +7495,15 @@ function ac_on_close(gobj, event, kw, src) {
|
|
|
7033
7495
|
remote_yuno_service: priv.remote_yuno_service
|
|
7034
7496
|
});
|
|
7035
7497
|
} else {
|
|
7036
|
-
log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${
|
|
7498
|
+
log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
|
|
7037
7499
|
gobj_publish_event(gobj, "EV_ON_OPEN_ERROR", {
|
|
7038
7500
|
url,
|
|
7039
7501
|
remote_yuno_name: priv.remote_yuno_name,
|
|
7040
7502
|
remote_yuno_role: priv.remote_yuno_role,
|
|
7041
7503
|
remote_yuno_service: priv.remote_yuno_service,
|
|
7042
|
-
code:
|
|
7043
|
-
reason:
|
|
7044
|
-
was_clean:
|
|
7504
|
+
code: kw.code,
|
|
7505
|
+
reason: kw.reason,
|
|
7506
|
+
was_clean: kw.was_clean
|
|
7045
7507
|
});
|
|
7046
7508
|
}
|
|
7047
7509
|
if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer, next_retry(gobj));
|
|
@@ -7139,6 +7601,10 @@ function ac_identity_card_ack(gobj, event, kw, src) {
|
|
|
7139
7601
|
function ac_on_message(gobj, event, kw, src) {
|
|
7140
7602
|
let url = gobj.priv.url;
|
|
7141
7603
|
let iev_msg = iev_create_from_json(gobj, kw.data);
|
|
7604
|
+
if (!iev_msg) {
|
|
7605
|
+
log_warning(`${gobj_short_name(gobj)}: frame dropped from ${url}: ${String(kw.data).substring(0, 256)}`);
|
|
7606
|
+
return -1;
|
|
7607
|
+
}
|
|
7142
7608
|
if (is_traffic_tracing(gobj)) {
|
|
7143
7609
|
let prefix = gobj_name(gobj_yuno()) + " <== " + url;
|
|
7144
7610
|
let size = kw.data.length;
|
|
@@ -7164,8 +7630,14 @@ function ac_on_message(gobj, event, kw, src) {
|
|
|
7164
7630
|
return 0;
|
|
7165
7631
|
}
|
|
7166
7632
|
let iev_dst_service = kw_get_str(gobj, event_id, "dst_service", "");
|
|
7167
|
-
if (msg_type === "__subscribing__")
|
|
7168
|
-
|
|
7633
|
+
if (msg_type === "__subscribing__") {
|
|
7634
|
+
log_warning(`${gobj_short_name(gobj)}: subscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
|
|
7635
|
+
return -1;
|
|
7636
|
+
}
|
|
7637
|
+
if (msg_type === "__unsubscribing__") {
|
|
7638
|
+
log_warning(`${gobj_short_name(gobj)}: unsubscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
|
|
7639
|
+
return -1;
|
|
7640
|
+
}
|
|
7169
7641
|
if (gobj_has_event(gobj, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
|
|
7170
7642
|
gobj_send_event(gobj, iev_event, iev_kw, gobj);
|
|
7171
7643
|
return 0;
|
|
@@ -7497,6 +7969,7 @@ exports.is_number = is_number;
|
|
|
7497
7969
|
exports.is_object = is_object;
|
|
7498
7970
|
exports.is_private_key = is_private_key;
|
|
7499
7971
|
exports.is_pure_number = is_pure_number;
|
|
7972
|
+
exports.is_secret_name = is_secret_name;
|
|
7500
7973
|
exports.is_string = is_string;
|
|
7501
7974
|
exports.jdb_delete = jdb_delete;
|
|
7502
7975
|
exports.jdb_get = jdb_get;
|
|
@@ -7512,6 +7985,7 @@ exports.json_array_remove = json_array_remove;
|
|
|
7512
7985
|
exports.json_array_size = json_array_size;
|
|
7513
7986
|
exports.json_deep_copy = json_deep_copy;
|
|
7514
7987
|
exports.json_is_identical = json_is_identical;
|
|
7988
|
+
exports.json_mask_secrets = json_mask_secrets;
|
|
7515
7989
|
exports.json_object_del = json_object_del;
|
|
7516
7990
|
exports.json_object_get = json_object_get;
|
|
7517
7991
|
exports.json_object_set = json_object_set;
|
|
@@ -7559,6 +8033,7 @@ exports.log_debug = log_debug;
|
|
|
7559
8033
|
exports.log_error = log_error;
|
|
7560
8034
|
exports.log_info = log_info;
|
|
7561
8035
|
exports.log_warning = log_warning;
|
|
8036
|
+
exports.mask_secrets_inline = mask_secrets_inline;
|
|
7562
8037
|
exports.msg_iev_get_msg_type = msg_iev_get_msg_type;
|
|
7563
8038
|
exports.msg_iev_get_stack = msg_iev_get_stack;
|
|
7564
8039
|
exports.msg_iev_push_stack = msg_iev_push_stack;
|
|
@@ -7592,6 +8067,7 @@ exports.strstr = strstr;
|
|
|
7592
8067
|
exports.template_get_field_desc = template_get_field_desc;
|
|
7593
8068
|
exports.timeTracker = timeTracker;
|
|
7594
8069
|
exports.trace_json = trace_json;
|
|
8070
|
+
exports.trace_json_masked = trace_json_masked;
|
|
7595
8071
|
exports.trace_level_t = trace_level_t;
|
|
7596
8072
|
exports.trace_msg = trace_msg;
|
|
7597
8073
|
exports.treedb_decoder_fkey = treedb_decoder_fkey;
|