@autofleet/settings 2.0.1 → 3.0.1

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/src/index.ts DELETED
@@ -1,257 +0,0 @@
1
- // eslint-disable-next-line max-classes-per-file
2
- import dotenv from 'dotenv';
3
- import Network from '@autofleet/network';
4
- import Logger from '@autofleet/logger';
5
- import NodeCache from 'node-cache';
6
- import EventEmitter, { once } from 'events';
7
- import moment from 'moment';
8
- import h3 from 'h3-js';
9
-
10
- dotenv.config();
11
-
12
- const logger = Logger();
13
-
14
- const fiveMinutes = 60 * 5;
15
- const waitingToNetwork = 'waitingToNetwork';
16
-
17
- const findUrl = (serviceUrl?: string) => serviceUrl
18
- || (process.env.SETTING_MS_SERVICE_HOST && process.env.SETTING_MS_SERVICE_HOST.length > 0 ? `http://${process.env.SETTING_MS_SERVICE_HOST}/` : undefined)
19
- || (process.env.NODE_ENV !== 'test' ? 'http://setting-ms.autofleet.io/' : 'http://localhost:9999/');
20
-
21
- interface SettingsClassOptions {
22
- serviceUrl?: string;
23
- ttl?: number;
24
- disableTestEnvCheck?: boolean;
25
- }
26
-
27
- type SettingValue = string | boolean | number | any[] | any;
28
-
29
- interface Location {
30
- lat: number;
31
- lng: number;
32
- }
33
- interface Label {
34
- businessModelId?: string;
35
- demandSourceId?: string;
36
- fleetId?: string;
37
- vendorId?: string;
38
- time?: string | Date;
39
- location?: Location;
40
- contextId?: string;
41
- }
42
-
43
- type LabelsArray = Label[];
44
-
45
- interface GetSettingOption {
46
- timeout?: number;
47
- rejectOnFail?: boolean;
48
- }
49
-
50
- class CannotGetNetworkValueError extends Error {}
51
-
52
- class SettingsManager {
53
- ttl: number;
54
-
55
- settingsCache: NodeCache;
56
-
57
- networkEvents: EventEmitter;
58
-
59
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
- network: any;
61
-
62
- NEVER_DEFAULT_VALUE: string;
63
-
64
- disableTestEnvCheck: boolean;
65
-
66
- static get NEVER_DEFAULT_VALUE(): 'NEVER_DEFAULT_VALUE' {
67
- return 'NEVER_DEFAULT_VALUE';
68
- }
69
-
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
- }
76
-
77
- if (returnValue === SettingsManager.NEVER_DEFAULT_VALUE) {
78
- throw new Error('Cannot find value from network or cache, default value is set to never');
79
- }
80
-
81
- return returnValue;
82
- }
83
-
84
- constructor({ serviceUrl, ttl = fiveMinutes, disableTestEnvCheck = false }: SettingsClassOptions = {}) {
85
- const localServiceUrl = findUrl(serviceUrl);
86
-
87
- this.NEVER_DEFAULT_VALUE = SettingsManager.NEVER_DEFAULT_VALUE;
88
- this.ttl = ttl;
89
- this.disableTestEnvCheck = disableTestEnvCheck;
90
- this.settingsCache = new NodeCache();
91
- this.networkEvents = new EventEmitter();
92
- this.network = new Network({
93
- serviceUrl: localServiceUrl,
94
- });
95
- }
96
-
97
- async get(
98
- key: SettingValue,
99
- defaultValue?: SettingValue,
100
- labels: LabelsArray = [],
101
- { timeout = 5000, rejectOnFail = false } : GetSettingOption = {},
102
- ): Promise<SettingValue> {
103
- if (typeof defaultValue === 'undefined') {
104
- throw new Error('Can\'t get a key without defaultValue');
105
- }
106
-
107
- const cacheKey = this.getCacheKey(key, labels);
108
- const cacheValue = this.settingsCache.get(cacheKey);
109
- if (cacheValue !== undefined) {
110
- logger.info('setting found in cache', { cacheKey });
111
- if (waitingToNetwork === cacheValue) {
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);
118
- }
119
- return cacheValue;
120
- }
121
-
122
- if (!this.disableTestEnvCheck && process.env.NODE_ENV === 'test') {
123
- logger.info('returning default value setting in TEST mode', { cacheKey });
124
- return defaultValue;
125
- }
126
-
127
- let networkValue;
128
- try {
129
- this.settingsCache.set(cacheKey, waitingToNetwork, this.ttl);
130
- const networkResponse = await this.network.get(`/api/v1/settings/get-setting/${key}`, {
131
- params: {
132
- labels: labels.map((label) => JSON.stringify(label)),
133
- },
134
- timeout,
135
- });
136
- networkValue = networkResponse.data.value;
137
- } catch (error) {
138
- logger.error('Cant get setting from network', { error, rejectOnFail, key });
139
- if (rejectOnFail) {
140
- const errorToThrow = new CannotGetNetworkValueError();
141
- this.networkEvents.emit(cacheKey, errorToThrow);
142
- throw errorToThrow;
143
- }
144
- }
145
-
146
- this.networkEvents.emit(cacheKey, networkValue);
147
- let returnValue;
148
- try {
149
- returnValue = SettingsManager.readNetworkValue(networkValue, defaultValue, key);
150
- } catch (e) {
151
- this.settingsCache.del(cacheKey);
152
- throw e;
153
- }
154
- this.settingsCache.set(cacheKey, returnValue, this.ttl);
155
- return returnValue;
156
- }
157
-
158
- async getMultiple(
159
- settingsToGet: {
160
- key: SettingValue,
161
- defaultValue: any,
162
- }[],
163
- labels: LabelsArray,
164
- { timeout = 5000, rejectOnFail = false } : GetSettingOption = {},
165
- ): Promise<any> {
166
- const settingsToReturn = new Map();
167
- const settingsToFetch: any[] = [];
168
-
169
- settingsToGet.forEach((obj) => {
170
- const cacheKey = this.getCacheKey(obj.key, labels);
171
- const cacheValue = this.settingsCache.get(cacheKey);
172
- if (cacheValue !== undefined && cacheValue !== waitingToNetwork) {
173
- settingsToReturn.set(obj.key, cacheValue);
174
- } else {
175
- settingsToFetch.push(obj.key);
176
- }
177
- });
178
-
179
- if (process.env.NODE_ENV === 'test') {
180
- return settingsToGet.map((obj) => (settingsToReturn.get(obj.key) !== undefined ? settingsToReturn.get(obj.key) : obj.defaultValue));
181
- }
182
-
183
- if (settingsToFetch.length > 0) {
184
- let values: any[];
185
- try {
186
- const { data } = await this.network.post('/api/v1/settings/get-settings/_multiple', {
187
- keys: settingsToFetch,
188
- labels,
189
- skipEntityQueryAddition: true,
190
- }, {
191
- timeout,
192
- });
193
- values = data;
194
-
195
- settingsToFetch.forEach((key, index) => {
196
- settingsToReturn.set(key, values[index].value);
197
- });
198
- } catch (err) {
199
- logger.error('Cant get setting from network', { err, settingsToFetch, labels });
200
- if (rejectOnFail) {
201
- throw new CannotGetNetworkValueError();
202
- }
203
- }
204
- }
205
-
206
- return settingsToGet.map((setting: any) => {
207
- const cacheKey = this.getCacheKey(setting.key, labels);
208
- let returnValue;
209
- try {
210
- returnValue = SettingsManager.readNetworkValue(settingsToReturn.get(setting.key), setting.defaultValue, setting.key);
211
- } catch (err) {
212
- this.settingsCache.del(cacheKey);
213
- throw err;
214
- }
215
- if (settingsToFetch.indexOf(setting.key) !== -1) {
216
- this.settingsCache.set(cacheKey, returnValue, this.ttl);
217
- }
218
- return returnValue;
219
- });
220
- }
221
-
222
- setLocal(key: string, labels: LabelsArray, value: SettingValue): void {
223
- const cacheKey = this.getCacheKey(key, labels);
224
- this.settingsCache.set(cacheKey, value, this.ttl);
225
- }
226
-
227
- flush(): void {
228
- return this.settingsCache.flushAll();
229
- }
230
-
231
- getCacheKey(key: SettingValue, labels: LabelsArray): string {
232
- const newLabels = labels.map((l) => {
233
- if (l.time) {
234
- return {
235
- ...l,
236
- time: moment(l.time).startOf('hour').format(),
237
- day: moment(l.time).day(),
238
- };
239
- }
240
-
241
- if (l.location?.lat && l.location?.lng) {
242
- const h3Index = h3.latLngToCell(l.location.lat, l.location.lng, 8);
243
- return {
244
- ...l,
245
- location: h3Index,
246
- };
247
- }
248
-
249
- return l;
250
- });
251
-
252
- const cacheKey = `${key}_${JSON.stringify(newLabels)}`;
253
- return cacheKey;
254
- }
255
- }
256
-
257
- export default SettingsManager;
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es6",
4
- "module": "commonjs",
5
- "declaration": true,
6
- "outDir": "./dist",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- }
11
- }