@iobroker/db-objects-redis 5.0.18 → 5.0.20-alpha.0-20240131-ea40ee4f
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.
|
@@ -48,6 +48,31 @@ const semver_1 = __importDefault(require("semver"));
|
|
|
48
48
|
const CONSTS = __importStar(require("./constants"));
|
|
49
49
|
const ERRORS = CONSTS.ERRORS;
|
|
50
50
|
class ObjectsInRedisClient {
|
|
51
|
+
client;
|
|
52
|
+
fileNamespace;
|
|
53
|
+
redisNamespace;
|
|
54
|
+
fileNamespaceL;
|
|
55
|
+
objNamespace;
|
|
56
|
+
setNamespace;
|
|
57
|
+
metaNamespace;
|
|
58
|
+
objNamespaceL;
|
|
59
|
+
supportedProtocolVersions;
|
|
60
|
+
stop;
|
|
61
|
+
sub;
|
|
62
|
+
subSystem;
|
|
63
|
+
settings;
|
|
64
|
+
preserveSettings;
|
|
65
|
+
defaultNewAcl;
|
|
66
|
+
namespace;
|
|
67
|
+
hostname;
|
|
68
|
+
scripts;
|
|
69
|
+
existingMetaObjects;
|
|
70
|
+
log;
|
|
71
|
+
activeProtocolVersion;
|
|
72
|
+
useSets;
|
|
73
|
+
noLegacyMultihost;
|
|
74
|
+
userSubscriptions;
|
|
75
|
+
systemSubscriptions;
|
|
51
76
|
constructor(settings) {
|
|
52
77
|
this.settings = settings || {};
|
|
53
78
|
this.redisNamespace = `${this.settings.redisNamespace ||
|
|
@@ -811,7 +836,7 @@ class ObjectsInRedisClient {
|
|
|
811
836
|
if (typeof options === 'string') {
|
|
812
837
|
options = { mimeType: options };
|
|
813
838
|
}
|
|
814
|
-
if (options
|
|
839
|
+
if (options?.acl) {
|
|
815
840
|
options.acl = null;
|
|
816
841
|
}
|
|
817
842
|
if (!callback) {
|
|
@@ -2154,7 +2179,6 @@ class ObjectsInRedisClient {
|
|
|
2154
2179
|
return new Promise((resolve, reject) => this.unsubscribeUser(pattern, options, err => (err ? reject(err) : resolve())));
|
|
2155
2180
|
}
|
|
2156
2181
|
async _objectHelper(keys, objs) {
|
|
2157
|
-
var _a;
|
|
2158
2182
|
if (!keys.length) {
|
|
2159
2183
|
return;
|
|
2160
2184
|
}
|
|
@@ -2172,7 +2196,7 @@ class ObjectsInRedisClient {
|
|
|
2172
2196
|
// add the object to the set + set object atomic
|
|
2173
2197
|
commands.push(['sadd', `${this.setNamespace}object.type.${obj.type}`, id]);
|
|
2174
2198
|
}
|
|
2175
|
-
if (
|
|
2199
|
+
if (obj.common?.custom) {
|
|
2176
2200
|
// add to "common" set
|
|
2177
2201
|
commands.push(['sadd', `${this.setNamespace}object.common.custom`, id]);
|
|
2178
2202
|
}
|
|
@@ -2448,7 +2472,7 @@ class ObjectsInRedisClient {
|
|
|
2448
2472
|
return new Promise((resolve, reject) => this.getObject(id, options, (err, obj) => (err ? reject(err) : resolve(obj))));
|
|
2449
2473
|
}
|
|
2450
2474
|
if (typeof callback === 'function') {
|
|
2451
|
-
if (options
|
|
2475
|
+
if (options?.acl) {
|
|
2452
2476
|
options.acl = null;
|
|
2453
2477
|
}
|
|
2454
2478
|
utils.checkObjectRights(this, null, null, options, CONSTS.ACCESS_READ, (err, options) => {
|
|
@@ -2642,7 +2666,7 @@ class ObjectsInRedisClient {
|
|
|
2642
2666
|
// @ts-expect-error need to clarify, that objs is not undefined if no error is provided
|
|
2643
2667
|
this.getObjects(keys, options, (err, objs) => (err ? reject(err) : resolve(objs)), dontModify));
|
|
2644
2668
|
}
|
|
2645
|
-
if (options
|
|
2669
|
+
if (options?.acl) {
|
|
2646
2670
|
options.acl = null;
|
|
2647
2671
|
}
|
|
2648
2672
|
if (typeof callback === 'function') {
|
|
@@ -2706,7 +2730,6 @@ class ObjectsInRedisClient {
|
|
|
2706
2730
|
return new Promise((resolve, reject) => this.getObjectsByPattern(pattern, options, (err, objs) => (err ? reject(err) : resolve(objs))));
|
|
2707
2731
|
}
|
|
2708
2732
|
async _setObject(id, obj, options) {
|
|
2709
|
-
var _a, _b, _c, _d, _e;
|
|
2710
2733
|
if (!id || typeof id !== 'string' || utils.REG_CHECK_ID.test(id)) {
|
|
2711
2734
|
throw new Error(`Invalid ID: ${id}`);
|
|
2712
2735
|
}
|
|
@@ -2737,9 +2760,9 @@ class ObjectsInRedisClient {
|
|
|
2737
2760
|
throw new Error('Invalid password for update of vendor information');
|
|
2738
2761
|
}
|
|
2739
2762
|
// we need to know if custom has been added/deleted
|
|
2740
|
-
const oldObjHasCustom =
|
|
2763
|
+
const oldObjHasCustom = oldObj?.common?.custom;
|
|
2741
2764
|
// do not delete common settings, like "history" or "mobile". It can be erased only with "null"
|
|
2742
|
-
if (oldObj
|
|
2765
|
+
if (oldObj?.common) {
|
|
2743
2766
|
for (const commonSetting of this.preserveSettings) {
|
|
2744
2767
|
// special case if "custom"
|
|
2745
2768
|
if (commonSetting === 'custom') {
|
|
@@ -2763,7 +2786,7 @@ class ObjectsInRedisClient {
|
|
|
2763
2786
|
obj.common = obj.common || {};
|
|
2764
2787
|
obj.common.custom = oldObj.common.custom;
|
|
2765
2788
|
}
|
|
2766
|
-
else if (
|
|
2789
|
+
else if (obj.common?.custom && oldObj.common.custom) {
|
|
2767
2790
|
// merge together
|
|
2768
2791
|
for (const attr of Object.keys(oldObj.common.custom)) {
|
|
2769
2792
|
if (obj.common.custom[attr] === null) {
|
|
@@ -2775,7 +2798,7 @@ class ObjectsInRedisClient {
|
|
|
2775
2798
|
}
|
|
2776
2799
|
}
|
|
2777
2800
|
// remove custom if no one attribute inside
|
|
2778
|
-
if (
|
|
2801
|
+
if (obj.common?.custom) {
|
|
2779
2802
|
for (const attr of Object.keys(obj.common.custom)) {
|
|
2780
2803
|
if (obj.common.custom[attr] === null) {
|
|
2781
2804
|
delete obj.common.custom[attr];
|
|
@@ -2823,7 +2846,7 @@ class ObjectsInRedisClient {
|
|
|
2823
2846
|
}
|
|
2824
2847
|
}
|
|
2825
2848
|
}
|
|
2826
|
-
if (
|
|
2849
|
+
if (oldObj?.acl && !obj.acl) {
|
|
2827
2850
|
obj.acl = oldObj.acl;
|
|
2828
2851
|
}
|
|
2829
2852
|
// add user default rights if no acl provided
|
|
@@ -2850,7 +2873,7 @@ class ObjectsInRedisClient {
|
|
|
2850
2873
|
const message = JSON.stringify(obj);
|
|
2851
2874
|
const commands = [];
|
|
2852
2875
|
if (this.useSets) {
|
|
2853
|
-
if (obj.type && !
|
|
2876
|
+
if (obj.type && !oldObj?.type) {
|
|
2854
2877
|
// new object or oldObj had no type -> add to set + set object
|
|
2855
2878
|
commands.push(['sadd', `${this.setNamespace}object.type.${obj.type}`, this.objNamespace + id]);
|
|
2856
2879
|
}
|
|
@@ -2858,16 +2881,16 @@ class ObjectsInRedisClient {
|
|
|
2858
2881
|
// the old obj had a type which differs from the new type -> rem old, add new
|
|
2859
2882
|
commands.push(['sadd', `${this.setNamespace}object.type.${obj.type}`, this.objNamespace + id], ['srem', `${this.setNamespace}object.type.${oldObj.type}`, this.objNamespace + id]);
|
|
2860
2883
|
}
|
|
2861
|
-
else if (
|
|
2884
|
+
else if (oldObj?.type && !obj.type) {
|
|
2862
2885
|
// the oldObj had a type, the new one has no -> rem
|
|
2863
2886
|
// @ts-expect-error TODO remove in v5.1, for now support objs without type for legacy design objects
|
|
2864
2887
|
commands.push(['srem', `${this.setNamespace}object.type.${obj.type}`, this.objNamespace + id]);
|
|
2865
2888
|
}
|
|
2866
|
-
if (
|
|
2889
|
+
if (obj.common?.custom && !oldObjHasCustom) {
|
|
2867
2890
|
// we now have custom, old object had no custom
|
|
2868
2891
|
commands.push(['sadd', `${this.setNamespace}object.common.custom`, this.objNamespace + id]);
|
|
2869
2892
|
}
|
|
2870
|
-
else if (oldObjHasCustom && !
|
|
2893
|
+
else if (oldObjHasCustom && !obj.common?.custom) {
|
|
2871
2894
|
// we no longer have custom
|
|
2872
2895
|
commands.push(['srem', `${this.setNamespace}object.common.custom`, this.objNamespace + id]);
|
|
2873
2896
|
}
|
|
@@ -2881,7 +2904,7 @@ class ObjectsInRedisClient {
|
|
|
2881
2904
|
await this.client.multi(commands).exec();
|
|
2882
2905
|
}
|
|
2883
2906
|
// object updated -> if type changed to meta -> cache
|
|
2884
|
-
if (
|
|
2907
|
+
if (oldObj?.type === 'meta' && this.existingMetaObjects[id] === false) {
|
|
2885
2908
|
this.existingMetaObjects[id] = true;
|
|
2886
2909
|
}
|
|
2887
2910
|
await this.client.publish(this.objNamespace + id, message);
|
|
@@ -2930,7 +2953,6 @@ class ObjectsInRedisClient {
|
|
|
2930
2953
|
this.setObject(id, obj, options, (err, res) => (err ? reject(err) : resolve(res))));
|
|
2931
2954
|
}
|
|
2932
2955
|
async _delObject(id, options) {
|
|
2933
|
-
var _a;
|
|
2934
2956
|
if (!id || typeof id !== 'string' || utils.REG_CHECK_ID.test(id)) {
|
|
2935
2957
|
throw new Error(`Invalid ID: ${id}`);
|
|
2936
2958
|
}
|
|
@@ -2970,7 +2992,7 @@ class ObjectsInRedisClient {
|
|
|
2970
2992
|
// del the object from the set + del object atomic
|
|
2971
2993
|
commands.push(['srem', `${this.setNamespace}object.type.${oldObj.type}`, this.objNamespace + id]);
|
|
2972
2994
|
}
|
|
2973
|
-
if (
|
|
2995
|
+
if (oldObj.common?.custom) {
|
|
2974
2996
|
// del the object from "custom" set
|
|
2975
2997
|
commands.push(['srem', `${this.setNamespace}object.common.custom`, this.objNamespace + id]);
|
|
2976
2998
|
}
|
|
@@ -2999,7 +3021,7 @@ class ObjectsInRedisClient {
|
|
|
2999
3021
|
if (!callback) {
|
|
3000
3022
|
return new Promise((resolve, reject) => this.delObject(id, options, err => (err ? reject(err) : resolve())));
|
|
3001
3023
|
}
|
|
3002
|
-
if (options
|
|
3024
|
+
if (options?.acl) {
|
|
3003
3025
|
options.acl = null;
|
|
3004
3026
|
}
|
|
3005
3027
|
utils.checkObjectRights(this, null, null, options, CONSTS.ACCESS_DELETE, async (err, options) => {
|
|
@@ -3038,7 +3060,6 @@ class ObjectsInRedisClient {
|
|
|
3038
3060
|
}
|
|
3039
3061
|
// this function is very ineffective. Because reads all objects and then process them
|
|
3040
3062
|
async _applyViewFunc(func, params, options = {}) {
|
|
3041
|
-
var _a;
|
|
3042
3063
|
if (!this.client) {
|
|
3043
3064
|
throw new Error(ERRORS.ERROR_DB_CLOSED);
|
|
3044
3065
|
}
|
|
@@ -3085,7 +3106,7 @@ class ObjectsInRedisClient {
|
|
|
3085
3106
|
}
|
|
3086
3107
|
const matches = func.map.match(/if\s\(doc\.type\s?===?\s?'(\w+)'\)\semit\(([^,]+),\s?doc\s?\)/);
|
|
3087
3108
|
// filter by type
|
|
3088
|
-
if (wildCardLastPos &&
|
|
3109
|
+
if (wildCardLastPos && func?.map && this.scripts.filter && matches) {
|
|
3089
3110
|
let cursor = '0';
|
|
3090
3111
|
let filterRequired = true;
|
|
3091
3112
|
do {
|
|
@@ -3179,7 +3200,7 @@ class ObjectsInRedisClient {
|
|
|
3179
3200
|
else if (
|
|
3180
3201
|
// filter by script
|
|
3181
3202
|
wildCardLastPos &&
|
|
3182
|
-
|
|
3203
|
+
func?.map &&
|
|
3183
3204
|
this.scripts.script &&
|
|
3184
3205
|
func.map.includes('doc.common.engineType')) {
|
|
3185
3206
|
let cursor = '0';
|
|
@@ -3236,7 +3257,7 @@ class ObjectsInRedisClient {
|
|
|
3236
3257
|
else if (
|
|
3237
3258
|
// filter by hm-rega programs
|
|
3238
3259
|
wildCardLastPos &&
|
|
3239
|
-
|
|
3260
|
+
func?.map &&
|
|
3240
3261
|
this.scripts.programs &&
|
|
3241
3262
|
func.map.includes("doc.native.TypeName === 'PROGRAM'")) {
|
|
3242
3263
|
let cursor = '0';
|
|
@@ -3291,7 +3312,7 @@ class ObjectsInRedisClient {
|
|
|
3291
3312
|
else if (
|
|
3292
3313
|
// filter by hm-rega variables
|
|
3293
3314
|
wildCardLastPos &&
|
|
3294
|
-
|
|
3315
|
+
func?.map &&
|
|
3295
3316
|
this.scripts.variables &&
|
|
3296
3317
|
func.map.includes("doc.native.TypeName === 'ALARMDP'")) {
|
|
3297
3318
|
let cursor = '0';
|
|
@@ -3346,7 +3367,7 @@ class ObjectsInRedisClient {
|
|
|
3346
3367
|
else if (
|
|
3347
3368
|
// filter by custom, redis also returns if common.custom is not present
|
|
3348
3369
|
wildCardLastPos &&
|
|
3349
|
-
|
|
3370
|
+
func?.map &&
|
|
3350
3371
|
this.scripts.custom &&
|
|
3351
3372
|
func.map.includes('doc.common.custom')) {
|
|
3352
3373
|
let cursor = '0';
|
|
@@ -3390,7 +3411,7 @@ class ObjectsInRedisClient {
|
|
|
3390
3411
|
this.log.error(`${this.namespace} Cannot parse JSON: ${_obj}`);
|
|
3391
3412
|
continue;
|
|
3392
3413
|
}
|
|
3393
|
-
if (
|
|
3414
|
+
if (obj?.common?.custom) {
|
|
3394
3415
|
if (useFullObject) {
|
|
3395
3416
|
result.rows.push({ id: obj._id, value: obj });
|
|
3396
3417
|
}
|
|
@@ -3497,7 +3518,6 @@ class ObjectsInRedisClient {
|
|
|
3497
3518
|
}
|
|
3498
3519
|
}
|
|
3499
3520
|
async _getObjectView(design, search, params, options) {
|
|
3500
|
-
var _a;
|
|
3501
3521
|
if (!this.client) {
|
|
3502
3522
|
throw new Error(ERRORS.ERROR_DB_CLOSED);
|
|
3503
3523
|
}
|
|
@@ -3517,7 +3537,7 @@ class ObjectsInRedisClient {
|
|
|
3517
3537
|
this.log.error(`${this.namespace} Cannot parse JSON: ${obj}`);
|
|
3518
3538
|
throw new Error(`Cannot parse JSON: "_design/${design}" / "${obj}"`);
|
|
3519
3539
|
}
|
|
3520
|
-
if (
|
|
3540
|
+
if (obj.views?.[search]) {
|
|
3521
3541
|
return this._applyViewFunc(obj.views[search], params, options);
|
|
3522
3542
|
}
|
|
3523
3543
|
else {
|
|
@@ -3538,7 +3558,7 @@ class ObjectsInRedisClient {
|
|
|
3538
3558
|
if (!callback) {
|
|
3539
3559
|
return new Promise((resolve, reject) => this.getObjectView(design, search, params, options, (err, obj) => (err ? reject(err) : resolve(obj))));
|
|
3540
3560
|
}
|
|
3541
|
-
if (options
|
|
3561
|
+
if (options?.acl) {
|
|
3542
3562
|
options.acl = null;
|
|
3543
3563
|
}
|
|
3544
3564
|
if (typeof callback === 'function') {
|
|
@@ -3565,7 +3585,6 @@ class ObjectsInRedisClient {
|
|
|
3565
3585
|
if (!this.client) {
|
|
3566
3586
|
throw new Error(ERRORS.ERROR_DB_CLOSED);
|
|
3567
3587
|
}
|
|
3568
|
-
//params = {startkey, endkey, include_docs}
|
|
3569
3588
|
params = params || {};
|
|
3570
3589
|
params.startkey = params.startkey || '';
|
|
3571
3590
|
params.endkey = params.endkey || '\u9999';
|
|
@@ -3634,7 +3653,7 @@ class ObjectsInRedisClient {
|
|
|
3634
3653
|
if (!callback) {
|
|
3635
3654
|
return new Promise((resolve, reject) => this.getObjectList(params, options, (err, obj) => (err ? reject(err) : resolve(obj))));
|
|
3636
3655
|
}
|
|
3637
|
-
if (options
|
|
3656
|
+
if (options?.acl) {
|
|
3638
3657
|
options.acl = null;
|
|
3639
3658
|
}
|
|
3640
3659
|
if (typeof callback === 'function') {
|
|
@@ -3659,7 +3678,6 @@ class ObjectsInRedisClient {
|
|
|
3659
3678
|
}
|
|
3660
3679
|
// could be optimized, to read object only once. Now it will read 3 times
|
|
3661
3680
|
async _extendObject(id, obj, options, callback) {
|
|
3662
|
-
var _a;
|
|
3663
3681
|
if (!id || typeof id !== 'string' || utils.REG_CHECK_ID.test(id)) {
|
|
3664
3682
|
// @ts-expect-error we fix when removing cb
|
|
3665
3683
|
return db_base_1.tools.maybeCallbackWithError(callback, `Invalid ID: ${id}`);
|
|
@@ -3686,12 +3704,12 @@ class ObjectsInRedisClient {
|
|
|
3686
3704
|
return db_base_1.tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION);
|
|
3687
3705
|
}
|
|
3688
3706
|
let _oldObj;
|
|
3689
|
-
if (oldObj
|
|
3707
|
+
if (oldObj?.nonEdit) {
|
|
3690
3708
|
// copy object
|
|
3691
3709
|
_oldObj = (0, deep_clone_1.default)(oldObj);
|
|
3692
3710
|
}
|
|
3693
3711
|
// we need to know if custom has been added/deleted
|
|
3694
|
-
const oldObjHasCustom = !!
|
|
3712
|
+
const oldObjHasCustom = !!oldObj?.common?.custom;
|
|
3695
3713
|
oldObj = oldObj || {};
|
|
3696
3714
|
obj = (0, deep_clone_1.default)(obj); // copy here to prevent "sandboxed" objects from JavaScript adapter
|
|
3697
3715
|
if (oldObj.common &&
|
|
@@ -3864,7 +3882,7 @@ class ObjectsInRedisClient {
|
|
|
3864
3882
|
this.log.error(`${this.namespace} Cannot parse JSON ${keys[i]}: ${objs[i]}`);
|
|
3865
3883
|
continue;
|
|
3866
3884
|
}
|
|
3867
|
-
if (
|
|
3885
|
+
if (obj?.common &&
|
|
3868
3886
|
obj.common.name === idOrName &&
|
|
3869
3887
|
(!type || ('type' in obj.common && obj.common.type === type))) {
|
|
3870
3888
|
return db_base_1.tools.maybeCallbackWithError(callback, null, obj._id, idOrName);
|
|
@@ -3888,7 +3906,7 @@ class ObjectsInRedisClient {
|
|
|
3888
3906
|
if (!callback) {
|
|
3889
3907
|
return new Promise((resolve, reject) => this.findObject(idOrName, type, options, (err, id, _idOrName) => (err ? reject(err) : resolve(id))));
|
|
3890
3908
|
}
|
|
3891
|
-
if (options
|
|
3909
|
+
if (options?.acl) {
|
|
3892
3910
|
options.acl = null;
|
|
3893
3911
|
}
|
|
3894
3912
|
if (typeof callback === 'function') {
|
|
@@ -4107,7 +4125,6 @@ class ObjectsInRedisClient {
|
|
|
4107
4125
|
* @return number of migrated sets
|
|
4108
4126
|
*/
|
|
4109
4127
|
async migrateToSets() {
|
|
4110
|
-
var _a;
|
|
4111
4128
|
if (!this.useSets) {
|
|
4112
4129
|
return 0;
|
|
4113
4130
|
}
|
|
@@ -4133,7 +4150,7 @@ class ObjectsInRedisClient {
|
|
|
4133
4150
|
noMigrated += migrated;
|
|
4134
4151
|
}
|
|
4135
4152
|
// check for custom
|
|
4136
|
-
if (
|
|
4153
|
+
if (obj.value.common?.custom) {
|
|
4137
4154
|
const migrated = await this.client.sadd(`${this.setNamespace}object.common.custom`, this.objNamespace + obj.id);
|
|
4138
4155
|
noMigrated += migrated;
|
|
4139
4156
|
}
|