import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; import type { SettingValue } from '@rocket.chat/core-typings'; import { sdk } from '../../utils/client/lib/SDKClient'; type SettingComposedValue = { key: string; value: T }; type SettingCallback = (key: string, value: SettingValue, initialLoad?: boolean) => void; interface ISettingRegexCallbacks { regex: RegExp; callbacks: SettingCallback[]; } export class SettingsBase { private callbacks = new Map(); private regexCallbacks = new Map(); // private ts = new Date() public get(_id: RegExp, callback: SettingCallback): void; public get(_id: string, callback: SettingCallback): void; public get(_id: RegExp): SettingComposedValue[]; public get(_id: string): T | undefined; public get( _id: string | RegExp, callback?: SettingCallback, ): T | undefined | SettingComposedValue[] | void { if (callback != null) { this.onload(_id, callback); if (!Meteor.settings) { return; } if (_id === '*') { return Object.keys(Meteor.settings).forEach((key) => { const value = Meteor.settings[key]; callback(key, value); }); } if (_.isRegExp(_id) && Meteor.settings) { return Object.keys(Meteor.settings).forEach((key) => { if (!_id.test(key)) { return; } const value = Meteor.settings[key]; callback(key, value); }); } if (typeof _id === 'string') { const value = Meteor.settings[_id]; if (value != null) { callback(_id, Meteor.settings[_id]); } return; } } if (!Meteor.settings) { return; } if (_.isRegExp(_id)) { return Object.keys(Meteor.settings).reduce((items: SettingComposedValue[], key) => { const value = Meteor.settings[key]; if (_id.test(key)) { items.push({ key, value, }); } return items; }, []); } return Meteor.settings?.[_id]; } set(_id: string, value: SettingValue, callback: (err?: unknown, result?: any) => void): void { sdk .call('saveSetting', _id, value) .then((result) => callback(undefined, result)) .catch(callback); } batchSet(settings: Array<{ _id: string; value: SettingValue }>, callback: (err?: unknown, result?: any) => void): void { sdk .call('saveSettings', settings) .then((result) => callback(undefined, result)) .catch(callback); } load(key: string, value: SettingValue, initialLoad: boolean): void { ['*', key].forEach((item) => { const callbacks = this.callbacks.get(item); if (callbacks) { callbacks.forEach((callback) => callback(key, value, initialLoad)); } }); this.regexCallbacks.forEach((cbValue) => { if (!cbValue?.regex.test(key)) { return; } cbValue.callbacks.forEach((callback) => callback(key, value, initialLoad)); }); } onload(key: string | string[] | RegExp | RegExp[], callback: SettingCallback): void { // if key is '*' // for key, value in Meteor.settings // callback key, value, false // else if Meteor.settings?[_id]? // callback key, Meteor.settings[_id], false const keys: Array = Array.isArray(key) ? key : [key]; keys.forEach((k) => { if (_.isRegExp(k)) { if (!this.regexCallbacks.has(k.source)) { this.regexCallbacks.set(k.source, { regex: k, callbacks: [], }); } this.regexCallbacks.get(k.source)?.callbacks.push(callback); } else { if (!this.callbacks.has(k)) { this.callbacks.set(k, []); } this.callbacks.get(k)?.push(callback); } }); } }