1 | import { AsyncOptionalCreatable } from '@salesforce/kit';
|
2 | import { AnyJson, Dictionary, JsonMap, Optional } from '@salesforce/ts-types';
|
3 | import { Crypto } from '../crypto/crypto';
|
4 | /**
|
5 | * The allowed types stored in a config store.
|
6 | */
|
7 | export type ConfigValue = AnyJson;
|
8 | /**
|
9 | * The type of entries in a config store defined by the key and value type of {@link ConfigContents}.
|
10 | */
|
11 | export type ConfigEntry = [string, ConfigValue];
|
12 | /**
|
13 | * The type of content a config stores.
|
14 | */
|
15 | export type ConfigContents<T = ConfigValue> = Dictionary<T>;
|
16 | export type Key<P extends ConfigContents> = Extract<keyof P, string>;
|
17 | /**
|
18 | * An interface for a config object with a persistent store.
|
19 | */
|
20 | export interface ConfigStore<P extends ConfigContents = ConfigContents> {
|
21 | entries(): ConfigEntry[];
|
22 | get<K extends Key<P>>(key: K, decrypt: boolean): P[K];
|
23 | get<T extends ConfigValue>(key: string, decrypt: boolean): T;
|
24 | getKeysByValue(value: ConfigValue): Array<Key<P>>;
|
25 | has(key: string): boolean;
|
26 | keys(): Array<Key<P>>;
|
27 | set<K extends Key<P>>(key: K, value: P[K]): void;
|
28 | set<T extends ConfigValue>(key: string, value: T): void;
|
29 | update<K extends Key<P>>(key: K, value: Partial<P[K]>): void;
|
30 | update<T extends ConfigValue>(key: string, value: Partial<T>): void;
|
31 | unset(key: string): boolean;
|
32 | unsetAll(keys: string[]): boolean;
|
33 | clear(): void;
|
34 | values(): ConfigValue[];
|
35 | forEach(actionFn: (key: string, value: ConfigValue) => void): void;
|
36 | awaitEach(actionFn: (key: string, value: ConfigValue) => Promise<void>): Promise<void>;
|
37 | getContents(): P;
|
38 | setContents(contents?: P): void;
|
39 | }
|
40 | /**
|
41 | * An abstract class that implements all the config management functions but
|
42 | * none of the storage functions.
|
43 | *
|
44 | * **Note:** To see the interface, look in typescripts autocomplete help or the npm package's ConfigStore.d.ts file.
|
45 | */
|
46 | export declare abstract class BaseConfigStore<T extends BaseConfigStore.Options = BaseConfigStore.Options, P extends ConfigContents = ConfigContents> extends AsyncOptionalCreatable<T> implements ConfigStore<P> {
|
47 | protected static encryptedKeys: Array<string | RegExp>;
|
48 | protected options: T;
|
49 | protected crypto?: Crypto;
|
50 | private contents;
|
51 | private statics;
|
52 | /**
|
53 | * Constructor.
|
54 | *
|
55 | * @param options The options for the class instance.
|
56 | * @ignore
|
57 | */
|
58 | constructor(options?: T);
|
59 | /**
|
60 | * Returns an array of {for each element in the config.
ConfigEntry} |
61 | */
|
62 | entries(): ConfigEntry[];
|
63 | /**
|
64 | * Returns the value associated to the key, or undefined if there is none.
|
65 | *
|
66 | * @param key The key. Supports query key like `a.b[0]`.
|
67 | * @param decrypt If it is an encrypted key, decrypt the value.
|
68 | * If the value is an object, a clone will be returned.
|
69 | */
|
70 | get<K extends Key<P>>(key: K, decrypt?: boolean): P[K];
|
71 | get<V = ConfigValue>(key: string, decrypt?: boolean): V;
|
72 | /**
|
73 | * Returns the list of keys that contain a value.
|
74 | *
|
75 | * @param value The value to filter keys on.
|
76 | */
|
77 | getKeysByValue(value: ConfigValue): Array<Key<P>>;
|
78 | /**
|
79 | * Returns a boolean asserting whether a value has been associated to the key in the config object or not.
|
80 | *
|
81 | * @param key The key. Supports query key like `a.b[0]`.
|
82 | */
|
83 | has(key: string): boolean;
|
84 | /**
|
85 | * Returns an array that contains the keys for each element in the config object.
|
86 | */
|
87 | keys(): Array<Key<P>>;
|
88 | /**
|
89 | * Sets the value for the key in the config object. This will override the existing value.
|
90 | * To do a partial update, use {@link BaseConfigStore.update}.
|
91 | *
|
92 | * @param key The key. Supports query key like `a.b[0]`.
|
93 | * @param value The value.
|
94 | */
|
95 | set<K extends Key<P>>(key: K, value: P[K]): void;
|
96 | set<V = ConfigValue>(key: string, value: V): void;
|
97 | /**
|
98 | * Updates the value for the key in the config object. If the value is an object, it
|
99 | * will be merged with the existing object.
|
100 | *
|
101 | * @param key The key. Supports query key like `a.b[0]`.
|
102 | * @param value The value.
|
103 | */
|
104 | update<K extends Key<P>>(key: K, value: Partial<P[K]>): void;
|
105 | update<V = ConfigValue>(key: string, value: Partial<V>): void;
|
106 | /**
|
107 | * Returns `true` if an element in the config object existed and has been removed, or `false` if the element does not
|
108 | * exist. {@link BaseConfigStore.has} will return false afterwards.
|
109 | *
|
110 | * @param key The key. Supports query key like `a.b[0]`.
|
111 | */
|
112 | unset(key: string): boolean;
|
113 | /**
|
114 | * Returns `true` if all elements in the config object existed and have been removed, or `false` if all the elements
|
115 | * do not exist (some may have been removed). {@link BaseConfigStore.has(key)} will return false afterwards.
|
116 | *
|
117 | * @param keys The keys. Supports query keys like `a.b[0]`.
|
118 | */
|
119 | unsetAll(keys: string[]): boolean;
|
120 | /**
|
121 | * Removes all key/value pairs from the config object.
|
122 | */
|
123 | clear(): void;
|
124 | /**
|
125 | * Returns an array that contains the values for each element in the config object.
|
126 | */
|
127 | values(): ConfigValue[];
|
128 | /**
|
129 | * Returns the entire config contents.
|
130 | *
|
131 | * *NOTE:* Data will still be encrypted unless decrypt is passed in. A clone of
|
132 | * the data will be returned to prevent storing un-encrypted data in memory and
|
133 | * potentially saving to the file system.
|
134 | *
|
135 | * @param decrypt: decrypt all data in the config. A clone of the data will be returned.
|
136 | *
|
137 | */
|
138 | getContents(decrypt?: boolean): P;
|
139 | /**
|
140 | * Sets the entire config contents.
|
141 | *
|
142 | * @param contents The contents.
|
143 | */
|
144 | setContents(contents?: P): void;
|
145 | /**
|
146 | * Invokes `actionFn` once for each key-value pair present in the config object.
|
147 | *
|
148 | * @param {function} actionFn The function `(key: string, value: ConfigValue) => void` to be called for each element.
|
149 | */
|
150 | forEach(actionFn: (key: string, value: ConfigValue) => void): void;
|
151 | /**
|
152 | * Asynchronously invokes `actionFn` once for each key-value pair present in the config object.
|
153 | *
|
154 | * @param {function} actionFn The function `(key: string, value: ConfigValue) => Promise<void>` to be called for
|
155 | * each element.
|
156 | * @returns {Promise<void>}
|
157 | */
|
158 | awaitEach(actionFn: (key: string, value: ConfigValue) => Promise<void>): Promise<void>;
|
159 | /**
|
160 | * Convert the config object to a JSON object. Returns the config contents.
|
161 | * Same as calling {@link ConfigStore.getContents}
|
162 | */
|
163 | toObject(): JsonMap;
|
164 | /**
|
165 | * Convert an object to a {@link ConfigContents} and set it as the config contents.
|
166 | *
|
167 | * @param obj The object.
|
168 | */
|
169 | setContentsFromObject<U extends JsonMap>(obj: U): void;
|
170 | protected getEncryptedKeys(): Array<string | RegExp>;
|
171 | /**
|
172 | * This config file has encrypted keys and it should attempt to encrypt them.
|
173 | *
|
174 | * @returns Has encrypted keys
|
175 | */
|
176 | protected hasEncryption(): boolean;
|
177 | protected setMethod(contents: ConfigContents, key: string, value?: ConfigValue): void;
|
178 | protected getMethod(contents: ConfigContents, key: string): Optional<ConfigValue>;
|
179 | protected initialContents(): P;
|
180 | /**
|
181 | * Used to initialize asynchronous components.
|
182 | */
|
183 | protected init(): Promise<void>;
|
184 | /**
|
185 | * Initialize the crypto dependency.
|
186 | */
|
187 | protected initCrypto(): Promise<void>;
|
188 | /**
|
189 | * Closes the crypto dependency. Crypto should be close after it's used and no longer needed.
|
190 | */
|
191 | protected clearCrypto(): Promise<void>;
|
192 | /**
|
193 | * Should the given key be encrypted on set methods and decrypted on get methods.
|
194 | *
|
195 | * @param key The key. Supports query key like `a.b[0]`.
|
196 | * @returns Should encrypt/decrypt
|
197 | */
|
198 | protected isCryptoKey(key: string): string | RegExp | undefined;
|
199 | protected encrypt(value: unknown): Optional<string>;
|
200 | protected decrypt(value: unknown): Optional<string>;
|
201 | /**
|
202 | * Encrypt all values in a nested JsonMap.
|
203 | *
|
204 | * @param keyPaths: The complete path of the (nested) data
|
205 | * @param data: The current (nested) data being worked on.
|
206 | */
|
207 | protected recursiveEncrypt<J extends JsonMap>(data: J, parentKey?: string): J;
|
208 | /**
|
209 | * Decrypt all values in a nested JsonMap.
|
210 | *
|
211 | * @param keyPaths: The complete path of the (nested) data
|
212 | * @param data: The current (nested) data being worked on.
|
213 | */
|
214 | protected recursiveDecrypt(data: JsonMap, parentKey?: string): JsonMap;
|
215 | /**
|
216 | * Encrypt/Decrypt all values in a nested JsonMap.
|
217 | *
|
218 | * @param keyPaths: The complete path of the (nested) data
|
219 | * @param data: The current (nested) data being worked on.
|
220 | */
|
221 | private recursiveCrypto;
|
222 | }
|
223 | /**
|
224 | * @ignore
|
225 | */
|
226 | export declare namespace BaseConfigStore {
|
227 | /**
|
228 | * Options for the config store.
|
229 | */
|
230 | interface Options {
|
231 | /**
|
232 | * Keys to encrypt.
|
233 | *
|
234 | * The preferred way to set encrypted keys is to use {@link BaseConfigStore.encryptedKeys}
|
235 | * so they are constant for all instances of a Config class. However, this is useful for
|
236 | * instantiating subclasses of ConfigStore on the fly (like {@link ConfigFile}) without
|
237 | * defining a new class.
|
238 | */
|
239 | encryptedKeys?: Array<string | RegExp>;
|
240 | }
|
241 | }
|