@autofleet/settings 2.0.0-beta.0 → 2.0.1-beta-context
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/.eslintrc.json +3 -1
- package/dist/index.d.ts +5 -8
- package/dist/index.js +53 -33
- package/dist/index.test.js +7 -6
- package/package.json +21 -12
- package/src/index.test.ts +6 -6
- package/src/index.ts +33 -43
- package/tsconfig.json +2 -1
package/.eslintrc.json
CHANGED
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
],
|
|
22
22
|
"@typescript-eslint/no-unused-vars": ["error"],
|
|
23
23
|
"@typescript-eslint/no-var-requires": ["off"],
|
|
24
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
24
25
|
"@typescript-eslint/camelcase": ["off"],
|
|
25
26
|
"max-len": ["off"],
|
|
26
|
-
"@typescript-eslint/explicit-function-return-type": ["off"]
|
|
27
|
+
"@typescript-eslint/explicit-function-return-type": ["off"],
|
|
28
|
+
"class-methods-use-this": "off"
|
|
27
29
|
},
|
|
28
30
|
"overrides": [
|
|
29
31
|
{
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { LoggerInstanceManager } from '@autofleet/logger';
|
|
3
1
|
import NodeCache from 'node-cache';
|
|
4
2
|
import EventEmitter from 'events';
|
|
5
3
|
interface SettingsClassOptions {
|
|
6
4
|
serviceUrl?: string;
|
|
7
5
|
ttl?: number;
|
|
8
6
|
disableTestEnvCheck?: boolean;
|
|
9
|
-
logger?: LoggerInstanceManager;
|
|
10
7
|
}
|
|
11
8
|
type SettingValue = string | boolean | number | any[] | any;
|
|
12
9
|
interface Location {
|
|
@@ -16,6 +13,7 @@ interface Location {
|
|
|
16
13
|
interface Label {
|
|
17
14
|
businessModelId?: string;
|
|
18
15
|
demandSourceId?: string;
|
|
16
|
+
contextId?: string;
|
|
19
17
|
fleetId?: string;
|
|
20
18
|
vendorId?: string;
|
|
21
19
|
time?: string | Date;
|
|
@@ -31,13 +29,12 @@ declare class SettingsManager {
|
|
|
31
29
|
settingsCache: NodeCache;
|
|
32
30
|
networkEvents: EventEmitter;
|
|
33
31
|
network: any;
|
|
34
|
-
logger?: LoggerInstanceManager;
|
|
35
32
|
NEVER_DEFAULT_VALUE: string;
|
|
36
33
|
disableTestEnvCheck: boolean;
|
|
37
|
-
static get NEVER_DEFAULT_VALUE():
|
|
38
|
-
static readNetworkValue(networkValue: SettingValue, defaultValue: SettingValue): any;
|
|
39
|
-
constructor({ serviceUrl, ttl, disableTestEnvCheck
|
|
40
|
-
get(key: SettingValue, defaultValue?:
|
|
34
|
+
static get NEVER_DEFAULT_VALUE(): 'NEVER_DEFAULT_VALUE';
|
|
35
|
+
static readNetworkValue(networkValue: SettingValue, defaultValue: SettingValue, key: string): any;
|
|
36
|
+
constructor({ serviceUrl, ttl, disableTestEnvCheck }?: SettingsClassOptions);
|
|
37
|
+
get(key: SettingValue, defaultValue?: SettingValue, labels?: LabelsArray, { timeout, rejectOnFail }?: GetSettingOption): Promise<SettingValue>;
|
|
41
38
|
getMultiple(settingsToGet: {
|
|
42
39
|
key: SettingValue;
|
|
43
40
|
defaultValue: any;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -12,18 +35,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
36
|
};
|
|
14
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
/* eslint-disable consistent-return */
|
|
16
|
-
/* eslint-disable array-callback-return */
|
|
17
38
|
// eslint-disable-next-line max-classes-per-file
|
|
18
39
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
19
40
|
const network_1 = __importDefault(require("@autofleet/network"));
|
|
41
|
+
const logger_1 = __importDefault(require("@autofleet/logger"));
|
|
20
42
|
const node_cache_1 = __importDefault(require("node-cache"));
|
|
21
|
-
const events_1 =
|
|
22
|
-
const util_1 = __importDefault(require("util"));
|
|
43
|
+
const events_1 = __importStar(require("events"));
|
|
23
44
|
const moment_1 = __importDefault(require("moment"));
|
|
24
45
|
const h3_js_1 = __importDefault(require("h3-js"));
|
|
25
46
|
dotenv_1.default.config();
|
|
26
|
-
const
|
|
47
|
+
const logger = (0, logger_1.default)();
|
|
27
48
|
const fiveMinutes = 60 * 5;
|
|
28
49
|
const waitingToNetwork = 'waitingToNetwork';
|
|
29
50
|
const findUrl = (serviceUrl) => serviceUrl
|
|
@@ -35,14 +56,18 @@ class SettingsManager {
|
|
|
35
56
|
static get NEVER_DEFAULT_VALUE() {
|
|
36
57
|
return 'NEVER_DEFAULT_VALUE';
|
|
37
58
|
}
|
|
38
|
-
static readNetworkValue(networkValue, defaultValue) {
|
|
39
|
-
|
|
59
|
+
static readNetworkValue(networkValue, defaultValue, key) {
|
|
60
|
+
let returnValue = networkValue;
|
|
61
|
+
if (typeof networkValue === 'undefined') {
|
|
62
|
+
returnValue = defaultValue;
|
|
63
|
+
logger.info('Setting falling back to default as network value was defined', { key, defaultValue });
|
|
64
|
+
}
|
|
40
65
|
if (returnValue === SettingsManager.NEVER_DEFAULT_VALUE) {
|
|
41
66
|
throw new Error('Cannot find value from network or cache, default value is set to never');
|
|
42
67
|
}
|
|
43
68
|
return returnValue;
|
|
44
69
|
}
|
|
45
|
-
constructor({ serviceUrl, ttl = fiveMinutes, disableTestEnvCheck = false
|
|
70
|
+
constructor({ serviceUrl, ttl = fiveMinutes, disableTestEnvCheck = false } = {}) {
|
|
46
71
|
const localServiceUrl = findUrl(serviceUrl);
|
|
47
72
|
this.NEVER_DEFAULT_VALUE = SettingsManager.NEVER_DEFAULT_VALUE;
|
|
48
73
|
this.ttl = ttl;
|
|
@@ -51,33 +76,29 @@ class SettingsManager {
|
|
|
51
76
|
this.networkEvents = new events_1.default();
|
|
52
77
|
this.network = new network_1.default({
|
|
53
78
|
serviceUrl: localServiceUrl,
|
|
54
|
-
keepAlive: false,
|
|
55
79
|
});
|
|
56
|
-
this.logger = logger;
|
|
57
80
|
}
|
|
58
|
-
get(
|
|
59
|
-
|
|
60
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
get(key_1, defaultValue_1) {
|
|
82
|
+
return __awaiter(this, arguments, void 0, function* (key, defaultValue, labels = [], { timeout = 5000, rejectOnFail = false } = {}) {
|
|
61
83
|
if (typeof defaultValue === 'undefined') {
|
|
62
84
|
throw new Error('Can\'t get a key without defaultValue');
|
|
63
85
|
}
|
|
64
86
|
const cacheKey = this.getCacheKey(key, labels);
|
|
65
87
|
const cacheValue = this.settingsCache.get(cacheKey);
|
|
66
88
|
if (cacheValue !== undefined) {
|
|
89
|
+
logger.info('setting found in cache', { cacheKey });
|
|
67
90
|
if (waitingToNetwork === cacheValue) {
|
|
68
|
-
yield
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
resolve(SettingsManager.readNetworkValue(networkValue, defaultValue));
|
|
75
|
-
});
|
|
76
|
-
});
|
|
91
|
+
yield Promise.resolve();
|
|
92
|
+
const [networkValue] = yield (0, events_1.once)(this.networkEvents, cacheKey);
|
|
93
|
+
if (networkValue instanceof Error && rejectOnFail) {
|
|
94
|
+
throw networkValue;
|
|
95
|
+
}
|
|
96
|
+
return SettingsManager.readNetworkValue(networkValue, defaultValue, key);
|
|
77
97
|
}
|
|
78
98
|
return cacheValue;
|
|
79
99
|
}
|
|
80
100
|
if (!this.disableTestEnvCheck && process.env.NODE_ENV === 'test') {
|
|
101
|
+
logger.info('returning default value setting in TEST mode', { cacheKey });
|
|
81
102
|
return defaultValue;
|
|
82
103
|
}
|
|
83
104
|
let networkValue;
|
|
@@ -92,7 +113,7 @@ class SettingsManager {
|
|
|
92
113
|
networkValue = networkResponse.data.value;
|
|
93
114
|
}
|
|
94
115
|
catch (error) {
|
|
95
|
-
|
|
116
|
+
logger.error('Cant get setting from network', { error, rejectOnFail, key });
|
|
96
117
|
if (rejectOnFail) {
|
|
97
118
|
const errorToThrow = new CannotGetNetworkValueError();
|
|
98
119
|
this.networkEvents.emit(cacheKey, errorToThrow);
|
|
@@ -102,7 +123,7 @@ class SettingsManager {
|
|
|
102
123
|
this.networkEvents.emit(cacheKey, networkValue);
|
|
103
124
|
let returnValue;
|
|
104
125
|
try {
|
|
105
|
-
returnValue = SettingsManager.readNetworkValue(networkValue, defaultValue);
|
|
126
|
+
returnValue = SettingsManager.readNetworkValue(networkValue, defaultValue, key);
|
|
106
127
|
}
|
|
107
128
|
catch (e) {
|
|
108
129
|
this.settingsCache.del(cacheKey);
|
|
@@ -112,12 +133,11 @@ class SettingsManager {
|
|
|
112
133
|
return returnValue;
|
|
113
134
|
});
|
|
114
135
|
}
|
|
115
|
-
getMultiple(
|
|
116
|
-
|
|
117
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
getMultiple(settingsToGet_1, labels_1) {
|
|
137
|
+
return __awaiter(this, arguments, void 0, function* (settingsToGet, labels, { timeout = 5000, rejectOnFail = false } = {}) {
|
|
118
138
|
const settingsToReturn = new Map();
|
|
119
139
|
const settingsToFetch = [];
|
|
120
|
-
settingsToGet.
|
|
140
|
+
settingsToGet.forEach((obj) => {
|
|
121
141
|
const cacheKey = this.getCacheKey(obj.key, labels);
|
|
122
142
|
const cacheValue = this.settingsCache.get(cacheKey);
|
|
123
143
|
if (cacheValue !== undefined && cacheValue !== waitingToNetwork) {
|
|
@@ -141,12 +161,12 @@ class SettingsManager {
|
|
|
141
161
|
timeout,
|
|
142
162
|
});
|
|
143
163
|
values = data;
|
|
144
|
-
settingsToFetch.
|
|
164
|
+
settingsToFetch.forEach((key, index) => {
|
|
145
165
|
settingsToReturn.set(key, values[index].value);
|
|
146
166
|
});
|
|
147
167
|
}
|
|
148
168
|
catch (err) {
|
|
149
|
-
|
|
169
|
+
logger.error('Cant get setting from network', { err, settingsToFetch, labels });
|
|
150
170
|
if (rejectOnFail) {
|
|
151
171
|
throw new CannotGetNetworkValueError();
|
|
152
172
|
}
|
|
@@ -156,7 +176,7 @@ class SettingsManager {
|
|
|
156
176
|
const cacheKey = this.getCacheKey(setting.key, labels);
|
|
157
177
|
let returnValue;
|
|
158
178
|
try {
|
|
159
|
-
returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue);
|
|
179
|
+
returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue, setting.key);
|
|
160
180
|
}
|
|
161
181
|
catch (err) {
|
|
162
182
|
this.settingsCache.del(cacheKey);
|
|
@@ -176,13 +196,13 @@ class SettingsManager {
|
|
|
176
196
|
flush() {
|
|
177
197
|
return this.settingsCache.flushAll();
|
|
178
198
|
}
|
|
179
|
-
// eslint-disable-next-line class-methods-use-this
|
|
180
199
|
getCacheKey(key, labels) {
|
|
181
200
|
const newLabels = labels.map((l) => {
|
|
201
|
+
var _a, _b;
|
|
182
202
|
if (l.time) {
|
|
183
203
|
return Object.assign(Object.assign({}, l), { time: (0, moment_1.default)(l.time).startOf('hour').format(), day: (0, moment_1.default)(l.time).day() });
|
|
184
204
|
}
|
|
185
|
-
if (l.location
|
|
205
|
+
if (((_a = l.location) === null || _a === void 0 ? void 0 : _a.lat) && ((_b = l.location) === null || _b === void 0 ? void 0 : _b.lng)) {
|
|
186
206
|
const h3Index = h3_js_1.default.latLngToCell(l.location.lat, l.location.lng, 8);
|
|
187
207
|
return Object.assign(Object.assign({}, l), { location: h3Index });
|
|
188
208
|
}
|
package/dist/index.test.js
CHANGED
|
@@ -12,20 +12,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const index_1 = __importDefault(require("./index"));
|
|
16
15
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
17
|
-
const
|
|
16
|
+
const nock_1 = __importDefault(require("nock"));
|
|
17
|
+
const index_1 = __importDefault(require("./index"));
|
|
18
18
|
process.env.NODE_ENV = 'node-common-test';
|
|
19
19
|
const serviceUrl = 'localhost:8085';
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
21
|
const mockSetting = (key, value, labels = undefined, response = 200) => {
|
|
22
|
-
const n =
|
|
23
|
-
|
|
24
|
-
.query(
|
|
22
|
+
const n = (0, nock_1.default)(`http://${serviceUrl}`).get(`/api/v1/settings/get-setting/${key}`);
|
|
23
|
+
if (labels) {
|
|
24
|
+
n.query({ labels: labels.map((label) => JSON.stringify(label)) });
|
|
25
|
+
}
|
|
25
26
|
return n.reply(response, { value });
|
|
26
27
|
};
|
|
27
28
|
const mockMultipleSettings = (keys, values, response = 200) => {
|
|
28
|
-
const n =
|
|
29
|
+
const n = (0, nock_1.default)(`http://${serviceUrl}`)
|
|
29
30
|
.post('/api/v1/settings/get-settings/_multiple', {
|
|
30
31
|
keys,
|
|
31
32
|
labels: [],
|
package/package.json
CHANGED
|
@@ -1,36 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/settings",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1-beta-context",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "ts-node src/index.ts",
|
|
8
8
|
"example": "ts-node src/example.ts",
|
|
9
9
|
"build": "tsc",
|
|
10
|
+
"prepublish": "npm run build",
|
|
10
11
|
"linter": "./node_modules/.bin/eslint .",
|
|
11
12
|
"test": "jest --forceExit",
|
|
12
13
|
"coverage": "jest --coverage --forceExit --runInBand && rm -rf ./coverage",
|
|
13
14
|
"dev": "nodemon"
|
|
14
15
|
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=16.0.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@autofleet/logger": ">=4.0.0"
|
|
21
|
+
},
|
|
15
22
|
"dependencies": {
|
|
16
|
-
"@autofleet/
|
|
17
|
-
"@autofleet/network": "^1.5.1",
|
|
23
|
+
"@autofleet/network": "^1.4.2",
|
|
18
24
|
"dotenv": "^8.2.0",
|
|
19
25
|
"h3-js": "^4.1.0",
|
|
20
26
|
"moment": "^2.29.1",
|
|
21
27
|
"node-cache": "^5.1.2"
|
|
22
28
|
},
|
|
23
29
|
"devDependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"typescript": "^
|
|
30
|
+
"@autofleet/logger": "^4.0.6",
|
|
31
|
+
"@types/jest": "^29.5.12",
|
|
32
|
+
"@types/nock": "^10.0.3",
|
|
33
|
+
"@types/node": "^16.18.108",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
35
|
+
"eslint": "^8.56.0",
|
|
36
|
+
"eslint-config-airbnb-typescript": "^18.0.0",
|
|
37
|
+
"eslint-plugin-import": "^2.30.0",
|
|
31
38
|
"jest": "^29.7.0",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
39
|
+
"nock": "^10.0.2",
|
|
40
|
+
"ts-jest": "^29.2.3",
|
|
41
|
+
"ts-node": "^8.6.2",
|
|
42
|
+
"typescript": "^5.5.3"
|
|
34
43
|
},
|
|
35
44
|
"author": "",
|
|
36
45
|
"license": "ISC"
|
package/src/index.test.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import Settings from './index';
|
|
2
|
-
|
|
3
1
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
4
|
-
|
|
2
|
+
import nock from 'nock';
|
|
3
|
+
import Settings from './index';
|
|
5
4
|
|
|
6
5
|
process.env.NODE_ENV = 'node-common-test';
|
|
7
6
|
|
|
@@ -9,9 +8,10 @@ const serviceUrl = 'localhost:8085';
|
|
|
9
8
|
|
|
10
9
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
10
|
const mockSetting = (key: string, value: string | boolean | number | never, labels: any = undefined, response = 200) => {
|
|
12
|
-
const n = nock(`http://${serviceUrl}`)
|
|
13
|
-
|
|
14
|
-
.query(
|
|
11
|
+
const n = nock(`http://${serviceUrl}`).get(`/api/v1/settings/get-setting/${key}`);
|
|
12
|
+
if (labels) {
|
|
13
|
+
n.query({ labels: labels.map((label: any) => JSON.stringify(label)) });
|
|
14
|
+
}
|
|
15
15
|
|
|
16
16
|
return n.reply(response, { value });
|
|
17
17
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
/* eslint-disable consistent-return */
|
|
2
|
-
/* eslint-disable array-callback-return */
|
|
3
1
|
// eslint-disable-next-line max-classes-per-file
|
|
4
2
|
import dotenv from 'dotenv';
|
|
5
3
|
import Network from '@autofleet/network';
|
|
6
|
-
import
|
|
4
|
+
import Logger from '@autofleet/logger';
|
|
7
5
|
import NodeCache from 'node-cache';
|
|
8
|
-
import EventEmitter from 'events';
|
|
9
|
-
import util from 'util';
|
|
6
|
+
import EventEmitter, { once } from 'events';
|
|
10
7
|
import moment from 'moment';
|
|
11
8
|
import h3 from 'h3-js';
|
|
12
9
|
|
|
13
10
|
dotenv.config();
|
|
14
11
|
|
|
15
|
-
const
|
|
12
|
+
const logger = Logger();
|
|
16
13
|
|
|
17
14
|
const fiveMinutes = 60 * 5;
|
|
18
15
|
const waitingToNetwork = 'waitingToNetwork';
|
|
@@ -25,7 +22,6 @@ interface SettingsClassOptions {
|
|
|
25
22
|
serviceUrl?: string;
|
|
26
23
|
ttl?: number;
|
|
27
24
|
disableTestEnvCheck?: boolean;
|
|
28
|
-
logger?: LoggerInstanceManager;
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
type SettingValue = string | boolean | number | any[] | any;
|
|
@@ -37,6 +33,7 @@ interface Location {
|
|
|
37
33
|
interface Label {
|
|
38
34
|
businessModelId?: string;
|
|
39
35
|
demandSourceId?: string;
|
|
36
|
+
contextId?:string;
|
|
40
37
|
fleetId?: string;
|
|
41
38
|
vendorId?: string;
|
|
42
39
|
time?: string | Date;
|
|
@@ -62,18 +59,20 @@ class SettingsManager {
|
|
|
62
59
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
60
|
network: any;
|
|
64
61
|
|
|
65
|
-
logger?: LoggerInstanceManager;
|
|
66
|
-
|
|
67
62
|
NEVER_DEFAULT_VALUE: string;
|
|
68
63
|
|
|
69
64
|
disableTestEnvCheck: boolean;
|
|
70
65
|
|
|
71
|
-
static get NEVER_DEFAULT_VALUE() {
|
|
66
|
+
static get NEVER_DEFAULT_VALUE(): 'NEVER_DEFAULT_VALUE' {
|
|
72
67
|
return 'NEVER_DEFAULT_VALUE';
|
|
73
68
|
}
|
|
74
69
|
|
|
75
|
-
static readNetworkValue(networkValue: SettingValue, defaultValue: SettingValue) {
|
|
76
|
-
|
|
70
|
+
static readNetworkValue(networkValue: SettingValue, defaultValue: SettingValue, key: string) {
|
|
71
|
+
let returnValue = networkValue;
|
|
72
|
+
if (typeof networkValue === 'undefined') {
|
|
73
|
+
returnValue = defaultValue;
|
|
74
|
+
logger.info('Setting falling back to default as network value was defined', { key, defaultValue });
|
|
75
|
+
}
|
|
77
76
|
|
|
78
77
|
if (returnValue === SettingsManager.NEVER_DEFAULT_VALUE) {
|
|
79
78
|
throw new Error('Cannot find value from network or cache, default value is set to never');
|
|
@@ -82,12 +81,7 @@ class SettingsManager {
|
|
|
82
81
|
return returnValue;
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
constructor({
|
|
86
|
-
serviceUrl,
|
|
87
|
-
ttl = fiveMinutes,
|
|
88
|
-
disableTestEnvCheck = false,
|
|
89
|
-
logger,
|
|
90
|
-
}: SettingsClassOptions = {}) {
|
|
84
|
+
constructor({ serviceUrl, ttl = fiveMinutes, disableTestEnvCheck = false }: SettingsClassOptions = {}) {
|
|
91
85
|
const localServiceUrl = findUrl(serviceUrl);
|
|
92
86
|
|
|
93
87
|
this.NEVER_DEFAULT_VALUE = SettingsManager.NEVER_DEFAULT_VALUE;
|
|
@@ -97,17 +91,15 @@ class SettingsManager {
|
|
|
97
91
|
this.networkEvents = new EventEmitter();
|
|
98
92
|
this.network = new Network({
|
|
99
93
|
serviceUrl: localServiceUrl,
|
|
100
|
-
keepAlive: false,
|
|
101
94
|
});
|
|
102
|
-
this.logger = logger;
|
|
103
95
|
}
|
|
104
96
|
|
|
105
97
|
async get(
|
|
106
98
|
key: SettingValue,
|
|
107
|
-
defaultValue?:
|
|
108
|
-
labels:LabelsArray = [],
|
|
99
|
+
defaultValue?: SettingValue,
|
|
100
|
+
labels: LabelsArray = [],
|
|
109
101
|
{ timeout = 5000, rejectOnFail = false } : GetSettingOption = {},
|
|
110
|
-
) {
|
|
102
|
+
): Promise<SettingValue> {
|
|
111
103
|
if (typeof defaultValue === 'undefined') {
|
|
112
104
|
throw new Error('Can\'t get a key without defaultValue');
|
|
113
105
|
}
|
|
@@ -115,21 +107,20 @@ class SettingsManager {
|
|
|
115
107
|
const cacheKey = this.getCacheKey(key, labels);
|
|
116
108
|
const cacheValue = this.settingsCache.get(cacheKey);
|
|
117
109
|
if (cacheValue !== undefined) {
|
|
110
|
+
logger.info('setting found in cache', { cacheKey });
|
|
118
111
|
if (waitingToNetwork === cacheValue) {
|
|
119
|
-
await
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
resolve(SettingsManager.readNetworkValue(networkValue, defaultValue));
|
|
126
|
-
});
|
|
127
|
-
});
|
|
112
|
+
await Promise.resolve();
|
|
113
|
+
const [networkValue] = await once(this.networkEvents, cacheKey);
|
|
114
|
+
if (networkValue instanceof Error && rejectOnFail) {
|
|
115
|
+
throw networkValue;
|
|
116
|
+
}
|
|
117
|
+
return SettingsManager.readNetworkValue(networkValue, defaultValue, key);
|
|
128
118
|
}
|
|
129
119
|
return cacheValue;
|
|
130
120
|
}
|
|
131
121
|
|
|
132
122
|
if (!this.disableTestEnvCheck && process.env.NODE_ENV === 'test') {
|
|
123
|
+
logger.info('returning default value setting in TEST mode', { cacheKey });
|
|
133
124
|
return defaultValue;
|
|
134
125
|
}
|
|
135
126
|
|
|
@@ -144,7 +135,7 @@ class SettingsManager {
|
|
|
144
135
|
});
|
|
145
136
|
networkValue = networkResponse.data.value;
|
|
146
137
|
} catch (error) {
|
|
147
|
-
|
|
138
|
+
logger.error('Cant get setting from network', { error, rejectOnFail, key });
|
|
148
139
|
if (rejectOnFail) {
|
|
149
140
|
const errorToThrow = new CannotGetNetworkValueError();
|
|
150
141
|
this.networkEvents.emit(cacheKey, errorToThrow);
|
|
@@ -155,7 +146,7 @@ class SettingsManager {
|
|
|
155
146
|
this.networkEvents.emit(cacheKey, networkValue);
|
|
156
147
|
let returnValue;
|
|
157
148
|
try {
|
|
158
|
-
returnValue = SettingsManager.readNetworkValue(networkValue, defaultValue);
|
|
149
|
+
returnValue = SettingsManager.readNetworkValue(networkValue, defaultValue, key);
|
|
159
150
|
} catch (e) {
|
|
160
151
|
this.settingsCache.del(cacheKey);
|
|
161
152
|
throw e;
|
|
@@ -175,7 +166,7 @@ class SettingsManager {
|
|
|
175
166
|
const settingsToReturn = new Map();
|
|
176
167
|
const settingsToFetch: any[] = [];
|
|
177
168
|
|
|
178
|
-
settingsToGet.
|
|
169
|
+
settingsToGet.forEach((obj) => {
|
|
179
170
|
const cacheKey = this.getCacheKey(obj.key, labels);
|
|
180
171
|
const cacheValue = this.settingsCache.get(cacheKey);
|
|
181
172
|
if (cacheValue !== undefined && cacheValue !== waitingToNetwork) {
|
|
@@ -201,11 +192,11 @@ class SettingsManager {
|
|
|
201
192
|
});
|
|
202
193
|
values = data;
|
|
203
194
|
|
|
204
|
-
settingsToFetch.
|
|
195
|
+
settingsToFetch.forEach((key, index) => {
|
|
205
196
|
settingsToReturn.set(key, values[index].value);
|
|
206
197
|
});
|
|
207
198
|
} catch (err) {
|
|
208
|
-
|
|
199
|
+
logger.error('Cant get setting from network', { err, settingsToFetch, labels });
|
|
209
200
|
if (rejectOnFail) {
|
|
210
201
|
throw new CannotGetNetworkValueError();
|
|
211
202
|
}
|
|
@@ -216,7 +207,7 @@ class SettingsManager {
|
|
|
216
207
|
const cacheKey = this.getCacheKey(setting.key, labels);
|
|
217
208
|
let returnValue;
|
|
218
209
|
try {
|
|
219
|
-
returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue);
|
|
210
|
+
returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue, setting.key);
|
|
220
211
|
} catch (err) {
|
|
221
212
|
this.settingsCache.del(cacheKey);
|
|
222
213
|
throw err;
|
|
@@ -228,17 +219,16 @@ class SettingsManager {
|
|
|
228
219
|
});
|
|
229
220
|
}
|
|
230
221
|
|
|
231
|
-
setLocal(key: string, labels: LabelsArray, value: SettingValue) {
|
|
222
|
+
setLocal(key: string, labels: LabelsArray, value: SettingValue): void {
|
|
232
223
|
const cacheKey = this.getCacheKey(key, labels);
|
|
233
224
|
this.settingsCache.set(cacheKey, value, this.ttl);
|
|
234
225
|
}
|
|
235
226
|
|
|
236
|
-
flush() {
|
|
227
|
+
flush(): void {
|
|
237
228
|
return this.settingsCache.flushAll();
|
|
238
229
|
}
|
|
239
230
|
|
|
240
|
-
|
|
241
|
-
getCacheKey(key: SettingValue, labels: LabelsArray) {
|
|
231
|
+
getCacheKey(key: SettingValue, labels: LabelsArray): string {
|
|
242
232
|
const newLabels = labels.map((l) => {
|
|
243
233
|
if (l.time) {
|
|
244
234
|
return {
|
|
@@ -248,7 +238,7 @@ class SettingsManager {
|
|
|
248
238
|
};
|
|
249
239
|
}
|
|
250
240
|
|
|
251
|
-
if (l.location
|
|
241
|
+
if (l.location?.lat && l.location?.lng) {
|
|
252
242
|
const h3Index = h3.latLngToCell(l.location.lat, l.location.lng, 8);
|
|
253
243
|
return {
|
|
254
244
|
...l,
|