@push.rocks/smartconfig 6.0.0

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.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export declare const commitinfo: {
5
+ name: string;
6
+ version: string;
7
+ description: string;
8
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export const commitinfo = {
5
+ name: '@push.rocks/smartconfig',
6
+ version: '6.0.0',
7
+ description: 'A comprehensive configuration management library providing key-value storage, environment variable mapping, and tool configuration.'
8
+ };
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHFJQUFxSTtDQUNuSixDQUFBIn0=
@@ -0,0 +1,72 @@
1
+ import * as plugins from './plugins.js';
2
+ import { KeyValueStore } from './classes.keyvaluestore.js';
3
+ export interface IAppDataOptions<T = any> {
4
+ dirPath?: string;
5
+ requiredKeys?: Array<keyof T>;
6
+ /**
7
+ * Whether keys should be persisted on disk or not
8
+ */
9
+ ephemeral?: boolean;
10
+ /**
11
+ * @deprecated Use 'ephemeral' instead
12
+ */
13
+ ephermal?: boolean;
14
+ /**
15
+ * kvStoreKey: 'MY_ENV_VAR'
16
+ */
17
+ envMapping?: plugins.tsclass.typeFest.PartialDeep<T>;
18
+ overwriteObject?: plugins.tsclass.typeFest.PartialDeep<T>;
19
+ }
20
+ export declare class AppData<T = any> {
21
+ /**
22
+ * creates appdata. If no pathArg is given, data will be stored here:
23
+ * ${PWD}/.nogit/appdata
24
+ * @param pathArg
25
+ * @returns
26
+ */
27
+ static createAndInit<T = any>(optionsArg?: IAppDataOptions<T>): Promise<AppData<T>>;
28
+ /**
29
+ * Static helper to get an environment variable as a boolean
30
+ * @param envVarName The name of the environment variable
31
+ * @returns boolean value (true if env var is "true", false otherwise)
32
+ */
33
+ static valueAsBoolean(envVarName: string): Promise<boolean>;
34
+ /**
35
+ * Static helper to get an environment variable as parsed JSON
36
+ * @param envVarName The name of the environment variable
37
+ * @returns Parsed JSON object/array
38
+ */
39
+ static valueAsJson<R = any>(envVarName: string): Promise<R | undefined>;
40
+ /**
41
+ * Static helper to get an environment variable as base64 decoded string
42
+ * @param envVarName The name of the environment variable
43
+ * @returns Decoded string
44
+ */
45
+ static valueAsBase64(envVarName: string): Promise<string | undefined>;
46
+ /**
47
+ * Static helper to get an environment variable as a string
48
+ * @param envVarName The name of the environment variable
49
+ * @returns String value
50
+ */
51
+ static valueAsString(envVarName: string): Promise<string | undefined>;
52
+ /**
53
+ * Static helper to get an environment variable as a number
54
+ * @param envVarName The name of the environment variable
55
+ * @returns Number value
56
+ */
57
+ static valueAsNumber(envVarName: string): Promise<number | undefined>;
58
+ readyDeferred: plugins.smartpromise.Deferred<void>;
59
+ options: IAppDataOptions<T>;
60
+ private kvStore;
61
+ constructor(optionsArg?: IAppDataOptions<T>);
62
+ /**
63
+ * inits app data
64
+ */
65
+ private init;
66
+ /**
67
+ * returns a kvstore that resides in appdata
68
+ */
69
+ getKvStore(): Promise<KeyValueStore<T>>;
70
+ logMissingKeys(): Promise<Array<keyof T>>;
71
+ waitForAndGetKey<K extends keyof T>(keyArg: K): Promise<T[K] | undefined>;
72
+ }
@@ -0,0 +1,454 @@
1
+ import * as plugins from './plugins.js';
2
+ import { KeyValueStore } from './classes.keyvaluestore.js';
3
+ // ============================================================================
4
+ // Singleton Qenv Provider
5
+ // ============================================================================
6
+ let sharedQenv;
7
+ function getQenv() {
8
+ if (!sharedQenv) {
9
+ sharedQenv = new plugins.qenv.Qenv(process.cwd(), plugins.path.join(process.cwd(), '.nogit'));
10
+ }
11
+ return sharedQenv;
12
+ }
13
+ // ============================================================================
14
+ // Security - Redaction for sensitive data
15
+ // ============================================================================
16
+ /**
17
+ * Redacts sensitive values in logs to prevent exposure of secrets
18
+ */
19
+ function redactSensitiveValue(key, value) {
20
+ // List of patterns that indicate sensitive data
21
+ const sensitivePatterns = [
22
+ /secret/i, /token/i, /key/i, /password/i, /pass/i,
23
+ /api/i, /credential/i, /auth/i, /private/i, /jwt/i,
24
+ /cert/i, /signature/i, /bearer/i
25
+ ];
26
+ // Check if key contains sensitive pattern
27
+ const isSensitive = sensitivePatterns.some(pattern => pattern.test(key));
28
+ if (isSensitive) {
29
+ if (typeof value === 'string') {
30
+ // Show first 3 chars and length for debugging
31
+ return value.length > 3
32
+ ? `${value.substring(0, 3)}...[${value.length} chars]`
33
+ : '[redacted]';
34
+ }
35
+ return '[redacted]';
36
+ }
37
+ // Check if value looks like a JWT token or base64 secret
38
+ if (typeof value === 'string') {
39
+ // JWT tokens start with eyJ
40
+ if (value.startsWith('eyJ')) {
41
+ return `eyJ...[${value.length} chars]`;
42
+ }
43
+ // Very long strings might be encoded secrets
44
+ if (value.length > 100) {
45
+ return `${value.substring(0, 50)}...[${value.length} chars total]`;
46
+ }
47
+ }
48
+ return JSON.stringify(value);
49
+ }
50
+ // ============================================================================
51
+ // Type Converters - Centralized conversion logic
52
+ // ============================================================================
53
+ function toBoolean(value) {
54
+ // If already boolean, return as-is
55
+ if (typeof value === 'boolean') {
56
+ console.log(` 🔹 toBoolean: value is already boolean: ${value}`);
57
+ return value;
58
+ }
59
+ // Handle null/undefined
60
+ if (value == null) {
61
+ console.log(` 🔹 toBoolean: value is null/undefined, returning false`);
62
+ return false;
63
+ }
64
+ // Handle string representations
65
+ const s = String(value).toLowerCase().trim();
66
+ // True values: "true", "1", "yes", "y", "on"
67
+ if (['true', '1', 'yes', 'y', 'on'].includes(s)) {
68
+ console.log(` 🔹 toBoolean: converting "${value}" to true`);
69
+ return true;
70
+ }
71
+ // False values: "false", "0", "no", "n", "off"
72
+ if (['false', '0', 'no', 'n', 'off'].includes(s)) {
73
+ console.log(` 🔹 toBoolean: converting "${value}" to false`);
74
+ return false;
75
+ }
76
+ // Default: non-empty string = true, empty = false
77
+ const result = s.length > 0;
78
+ console.log(` 🔹 toBoolean: defaulting "${value}" to ${result}`);
79
+ return result;
80
+ }
81
+ function toJson(value) {
82
+ if (value == null)
83
+ return undefined;
84
+ if (typeof value === 'string') {
85
+ try {
86
+ return JSON.parse(value);
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ }
92
+ return value;
93
+ }
94
+ function fromBase64(value) {
95
+ if (value == null)
96
+ return undefined;
97
+ try {
98
+ return Buffer.from(String(value), 'base64').toString('utf8');
99
+ }
100
+ catch {
101
+ return String(value);
102
+ }
103
+ }
104
+ function toNumber(value) {
105
+ if (value == null)
106
+ return undefined;
107
+ const num = Number(value);
108
+ return Number.isNaN(num) ? undefined : num;
109
+ }
110
+ function toString(value) {
111
+ if (value == null)
112
+ return undefined;
113
+ return String(value);
114
+ }
115
+ // Transform registry for extensibility
116
+ const transformRegistry = {
117
+ boolean: toBoolean,
118
+ json: toJson,
119
+ base64: fromBase64,
120
+ number: toNumber,
121
+ };
122
+ /**
123
+ * Parse a mapping string into a declarative spec
124
+ */
125
+ function parseMappingSpec(input) {
126
+ const transforms = [];
127
+ let remaining = input;
128
+ // Check for hardcoded prefixes with type conversion
129
+ if (remaining.startsWith('hard_boolean:')) {
130
+ return {
131
+ source: { type: 'hard', value: remaining.slice(13) },
132
+ transforms: ['boolean']
133
+ };
134
+ }
135
+ if (remaining.startsWith('hard_json:')) {
136
+ return {
137
+ source: { type: 'hard', value: remaining.slice(10) },
138
+ transforms: ['json']
139
+ };
140
+ }
141
+ if (remaining.startsWith('hard_base64:')) {
142
+ return {
143
+ source: { type: 'hard', value: remaining.slice(12) },
144
+ transforms: ['base64']
145
+ };
146
+ }
147
+ // Check for generic hard: prefix
148
+ if (remaining.startsWith('hard:')) {
149
+ remaining = remaining.slice(5);
150
+ // Check for legacy suffixes on hardcoded values
151
+ if (remaining.endsWith('_JSON')) {
152
+ transforms.push('json');
153
+ remaining = remaining.slice(0, -5);
154
+ }
155
+ else if (remaining.endsWith('_BASE64')) {
156
+ transforms.push('base64');
157
+ remaining = remaining.slice(0, -7);
158
+ }
159
+ return {
160
+ source: { type: 'hard', value: remaining },
161
+ transforms
162
+ };
163
+ }
164
+ // Check for env var prefixes
165
+ if (remaining.startsWith('boolean:')) {
166
+ transforms.push('boolean');
167
+ remaining = remaining.slice(8);
168
+ }
169
+ else if (remaining.startsWith('json:')) {
170
+ transforms.push('json');
171
+ remaining = remaining.slice(5);
172
+ }
173
+ else if (remaining.startsWith('base64:')) {
174
+ transforms.push('base64');
175
+ remaining = remaining.slice(7);
176
+ }
177
+ // Check for legacy suffixes on env vars
178
+ if (remaining.endsWith('_JSON')) {
179
+ transforms.push('json');
180
+ remaining = remaining.slice(0, -5);
181
+ }
182
+ else if (remaining.endsWith('_BASE64')) {
183
+ transforms.push('base64');
184
+ remaining = remaining.slice(0, -7);
185
+ }
186
+ return {
187
+ source: { type: 'env', key: remaining },
188
+ transforms
189
+ };
190
+ }
191
+ /**
192
+ * Resolve the source value (env var or hardcoded)
193
+ */
194
+ async function resolveSource(source) {
195
+ if (source.type === 'hard') {
196
+ return source.value;
197
+ }
198
+ // source.type === 'env'
199
+ // Workaround for Qenv bug where empty strings are treated as undefined
200
+ // Check process.env directly first to preserve empty strings
201
+ if (Object.prototype.hasOwnProperty.call(process.env, source.key)) {
202
+ return process.env[source.key];
203
+ }
204
+ // Fall back to Qenv for other sources (env.json, docker secrets, etc.)
205
+ return await getQenv().getEnvVarOnDemand(source.key);
206
+ }
207
+ /**
208
+ * Apply transformations in sequence
209
+ */
210
+ function applyTransforms(value, transforms) {
211
+ return transforms.reduce((acc, transform) => {
212
+ const fn = transformRegistry[transform];
213
+ return fn ? fn(acc) : acc;
214
+ }, value);
215
+ }
216
+ /**
217
+ * Process a mapping value through the complete pipeline
218
+ */
219
+ async function processMappingValue(mappingString) {
220
+ const spec = parseMappingSpec(mappingString);
221
+ const keyName = spec.source.type === 'env' ? spec.source.key : 'hardcoded';
222
+ console.log(` 🔍 Processing mapping: "${mappingString}"`);
223
+ console.log(` Source: ${spec.source.type === 'env' ? `env:${spec.source.key}` : `hard:${spec.source.value}`}`);
224
+ console.log(` Transforms: ${spec.transforms.length > 0 ? spec.transforms.join(', ') : 'none'}`);
225
+ const rawValue = await resolveSource(spec.source);
226
+ console.log(` Raw value: ${redactSensitiveValue(keyName, rawValue)} (type: ${typeof rawValue})`);
227
+ if (rawValue === undefined || rawValue === null) {
228
+ console.log(` ⚠️ Raw value is undefined/null, returning undefined`);
229
+ return undefined;
230
+ }
231
+ const result = applyTransforms(rawValue, spec.transforms);
232
+ console.log(` Final value: ${redactSensitiveValue(keyName, result)} (type: ${typeof result})`);
233
+ return result;
234
+ }
235
+ /**
236
+ * Recursively evaluate mapping values (strings or nested objects)
237
+ */
238
+ async function evaluateMappingValue(mappingValue) {
239
+ // Handle null explicitly - it should return null, not be treated as object
240
+ if (mappingValue === null) {
241
+ console.log(` 📌 Value is null, returning null`);
242
+ return null;
243
+ }
244
+ // Handle strings (mapping specs)
245
+ if (typeof mappingValue === 'string') {
246
+ return processMappingValue(mappingValue);
247
+ }
248
+ // Handle objects (but not arrays or null)
249
+ if (mappingValue && typeof mappingValue === 'object' && !Array.isArray(mappingValue)) {
250
+ console.log(` 📂 Processing nested object with ${Object.keys(mappingValue).length} keys`);
251
+ const result = {};
252
+ for (const [key, value] of Object.entries(mappingValue)) {
253
+ console.log(` → Processing nested key "${key}"`);
254
+ const evaluated = await evaluateMappingValue(value);
255
+ // Important: Don't filter out false or other falsy values!
256
+ // Only skip if explicitly undefined
257
+ if (evaluated !== undefined) {
258
+ result[key] = evaluated;
259
+ console.log(` ✓ Nested key "${key}" = ${redactSensitiveValue(key, evaluated)} (type: ${typeof evaluated})`);
260
+ }
261
+ else {
262
+ console.log(` ⚠️ Nested key "${key}" evaluated to undefined, skipping`);
263
+ }
264
+ }
265
+ return result;
266
+ }
267
+ // For any other type (numbers, booleans, etc.), return as-is
268
+ // Note: We don't have key context here, so we'll just indicate the type
269
+ console.log(` 📎 Returning value as-is: [value] (type: ${typeof mappingValue})`);
270
+ return mappingValue;
271
+ }
272
+ export class AppData {
273
+ /**
274
+ * creates appdata. If no pathArg is given, data will be stored here:
275
+ * ${PWD}/.nogit/appdata
276
+ * @param pathArg
277
+ * @returns
278
+ */
279
+ static async createAndInit(optionsArg = {}) {
280
+ const appData = new AppData(optionsArg);
281
+ await appData.readyDeferred.promise;
282
+ return appData;
283
+ }
284
+ /**
285
+ * Static helper to get an environment variable as a boolean
286
+ * @param envVarName The name of the environment variable
287
+ * @returns boolean value (true if env var is "true", false otherwise)
288
+ */
289
+ static async valueAsBoolean(envVarName) {
290
+ const value = await getQenv().getEnvVarOnDemand(envVarName);
291
+ return toBoolean(value);
292
+ }
293
+ /**
294
+ * Static helper to get an environment variable as parsed JSON
295
+ * @param envVarName The name of the environment variable
296
+ * @returns Parsed JSON object/array
297
+ */
298
+ static async valueAsJson(envVarName) {
299
+ const value = await getQenv().getEnvVarOnDemand(envVarName);
300
+ return toJson(value);
301
+ }
302
+ /**
303
+ * Static helper to get an environment variable as base64 decoded string
304
+ * @param envVarName The name of the environment variable
305
+ * @returns Decoded string
306
+ */
307
+ static async valueAsBase64(envVarName) {
308
+ const value = await getQenv().getEnvVarOnDemand(envVarName);
309
+ return fromBase64(value);
310
+ }
311
+ /**
312
+ * Static helper to get an environment variable as a string
313
+ * @param envVarName The name of the environment variable
314
+ * @returns String value
315
+ */
316
+ static async valueAsString(envVarName) {
317
+ const value = await getQenv().getEnvVarOnDemand(envVarName);
318
+ return toString(value);
319
+ }
320
+ /**
321
+ * Static helper to get an environment variable as a number
322
+ * @param envVarName The name of the environment variable
323
+ * @returns Number value
324
+ */
325
+ static async valueAsNumber(envVarName) {
326
+ const value = await getQenv().getEnvVarOnDemand(envVarName);
327
+ return toNumber(value);
328
+ }
329
+ constructor(optionsArg = {}) {
330
+ // instance
331
+ this.readyDeferred = plugins.smartpromise.defer();
332
+ this.options = optionsArg;
333
+ this.init();
334
+ }
335
+ /**
336
+ * inits app data
337
+ */
338
+ async init() {
339
+ console.log('🚀 Initializing AppData...');
340
+ // Handle backward compatibility for typo
341
+ const isEphemeral = this.options.ephemeral ?? this.options.ephermal ?? false;
342
+ if (this.options.ephermal && !this.options.ephemeral) {
343
+ console.warn('⚠️ Option "ephermal" is deprecated, use "ephemeral" instead.');
344
+ }
345
+ if (this.options.dirPath) {
346
+ console.log(` 📁 Using custom directory: ${this.options.dirPath}`);
347
+ }
348
+ else if (isEphemeral) {
349
+ console.log(` 💨 Using ephemeral storage (in-memory only)`);
350
+ }
351
+ else {
352
+ const appDataDir = '/app/data';
353
+ const dataDir = '/data';
354
+ const nogitAppData = '.nogit/appdata';
355
+ const appDataExists = plugins.smartfile.fs.isDirectory(appDataDir);
356
+ const dataExists = plugins.smartfile.fs.isDirectory(dataDir);
357
+ if (appDataExists) {
358
+ this.options.dirPath = appDataDir;
359
+ console.log(` 📁 Auto-selected container directory: ${appDataDir}`);
360
+ }
361
+ else if (dataExists) {
362
+ this.options.dirPath = dataDir;
363
+ console.log(` 📁 Auto-selected data directory: ${dataDir}`);
364
+ }
365
+ else {
366
+ await plugins.smartfile.fs.ensureDir(nogitAppData);
367
+ this.options.dirPath = nogitAppData;
368
+ console.log(` 📁 Auto-selected local directory: ${nogitAppData}`);
369
+ }
370
+ }
371
+ this.kvStore = new KeyValueStore({
372
+ typeArg: isEphemeral ? 'ephemeral' : 'custom',
373
+ identityArg: 'appkv',
374
+ customPath: this.options.dirPath,
375
+ mandatoryKeys: this.options.requiredKeys,
376
+ });
377
+ if (this.options.envMapping) {
378
+ console.log(`📦 Processing envMapping for AppData...`);
379
+ const totalKeys = Object.keys(this.options.envMapping).length;
380
+ let processedCount = 0;
381
+ // Process each top-level key in envMapping
382
+ for (const key in this.options.envMapping) {
383
+ try {
384
+ const mappingSpec = this.options.envMapping[key];
385
+ const specType = mappingSpec === null ? 'null' :
386
+ typeof mappingSpec === 'string' ? mappingSpec :
387
+ typeof mappingSpec === 'object' ? 'nested object' :
388
+ typeof mappingSpec;
389
+ console.log(` → Processing key "${key}" with spec: ${specType}`);
390
+ const evaluated = await evaluateMappingValue(mappingSpec);
391
+ // Important: Don't skip false, 0, empty string, or null values!
392
+ // Only skip if explicitly undefined
393
+ if (evaluated !== undefined) {
394
+ await this.kvStore.writeKey(key, evaluated);
395
+ processedCount++;
396
+ const valueType = evaluated === null ? 'null' :
397
+ Array.isArray(evaluated) ? 'array' :
398
+ typeof evaluated;
399
+ const valuePreview = evaluated === null ? 'null' :
400
+ typeof evaluated === 'object' ?
401
+ (Array.isArray(evaluated) ? `[${evaluated.length} items]` : `{${Object.keys(evaluated).length} keys}`) :
402
+ redactSensitiveValue(key, evaluated);
403
+ console.log(` ✅ Successfully processed key "${key}" = ${valuePreview} (type: ${valueType})`);
404
+ }
405
+ else {
406
+ console.log(` ⚠️ Key "${key}" evaluated to undefined, skipping`);
407
+ }
408
+ }
409
+ catch (err) {
410
+ console.error(` ❌ Failed to evaluate envMapping for key "${key}":`, err);
411
+ }
412
+ }
413
+ console.log(`📊 EnvMapping complete: ${processedCount}/${totalKeys} keys successfully processed`);
414
+ }
415
+ // Apply overwrite object after env mapping
416
+ if (this.options.overwriteObject) {
417
+ const overwriteKeys = Object.keys(this.options.overwriteObject);
418
+ console.log(`🔄 Applying overwriteObject with ${overwriteKeys.length} key(s)...`);
419
+ for (const key of overwriteKeys) {
420
+ const value = this.options.overwriteObject[key];
421
+ const valueType = Array.isArray(value) ? 'array' : typeof value;
422
+ console.log(` 🔧 Overwriting key "${key}" with ${valueType} value`);
423
+ await this.kvStore.writeKey(key, value);
424
+ }
425
+ console.log(`✅ OverwriteObject complete: ${overwriteKeys.length} key(s) overwritten`);
426
+ }
427
+ this.readyDeferred.resolve();
428
+ console.log('✨ AppData initialization complete!');
429
+ }
430
+ /**
431
+ * returns a kvstore that resides in appdata
432
+ */
433
+ async getKvStore() {
434
+ await this.readyDeferred.promise;
435
+ return this.kvStore;
436
+ }
437
+ async logMissingKeys() {
438
+ const kvStore = await this.getKvStore();
439
+ const missingMandatoryKeys = await kvStore.getMissingMandatoryKeys();
440
+ if (missingMandatoryKeys.length > 0) {
441
+ console.log(`The following mandatory keys are missing in the appdata:\n -> ${missingMandatoryKeys.join(',\n -> ')}`);
442
+ }
443
+ else {
444
+ console.log('All mandatory keys are present in the appdata');
445
+ }
446
+ return missingMandatoryKeys;
447
+ }
448
+ async waitForAndGetKey(keyArg) {
449
+ await this.readyDeferred.promise;
450
+ await this.kvStore.waitForKeysPresent([keyArg]);
451
+ return this.kvStore.readKey(keyArg);
452
+ }
453
+ }
454
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hcHBkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5hcHBkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUUzRCwrRUFBK0U7QUFDL0UsMEJBQTBCO0FBQzFCLCtFQUErRTtBQUMvRSxJQUFJLFVBQXlDLENBQUM7QUFFOUMsU0FBUyxPQUFPO0lBQ2QsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUNoQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQ2IsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUMzQyxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsMENBQTBDO0FBQzFDLCtFQUErRTtBQUMvRTs7R0FFRztBQUNILFNBQVMsb0JBQW9CLENBQUMsR0FBVyxFQUFFLEtBQWM7SUFDdkQsZ0RBQWdEO0lBQ2hELE1BQU0saUJBQWlCLEdBQUc7UUFDeEIsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE9BQU87UUFDakQsTUFBTSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU07UUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTO0tBQ2pDLENBQUM7SUFFRiwwQ0FBMEM7SUFDMUMsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBRXpFLElBQUksV0FBVyxFQUFF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
@@ -0,0 +1,63 @@
1
+ import * as plugins from './plugins.js';
2
+ export type TKeyValueStore = 'custom' | 'userHomeDir' | 'ephemeral';
3
+ export interface IKvStoreConstructorOptions<T> {
4
+ typeArg: TKeyValueStore;
5
+ identityArg: string;
6
+ customPath?: string;
7
+ mandatoryKeys?: Array<keyof T>;
8
+ }
9
+ /**
10
+ * kvStore is a simple key value store to store data about projects between runs
11
+ */
12
+ export declare class KeyValueStore<T = any> {
13
+ private dataObject;
14
+ private deletedObject;
15
+ private mandatoryKeys;
16
+ changeSubject: plugins.smartrx.rxjs.Subject<Partial<T>>;
17
+ private storedStateString;
18
+ syncTask: plugins.taskbuffer.Task<undefined>;
19
+ /**
20
+ * computes the identity and filePath
21
+ */
22
+ private initFilePath;
23
+ type: TKeyValueStore;
24
+ identity: string;
25
+ filePath?: string;
26
+ private customPath?;
27
+ /**
28
+ * the constructor of keyvalue store
29
+ * @param typeArg
30
+ * @param identityArg
31
+ * @param customPath Optional custom path for the keyValue store
32
+ */
33
+ constructor(optionsArg: IKvStoreConstructorOptions<T>);
34
+ /**
35
+ * reads all keyValue pairs at once and returns them
36
+ */
37
+ readAll(): Promise<Partial<T>>;
38
+ /**
39
+ * reads a keyValueFile from disk
40
+ */
41
+ readKey<K extends keyof T>(keyArg: K): Promise<T[K]>;
42
+ /**
43
+ * writes a specific key to the keyValueStore
44
+ */
45
+ writeKey<K extends keyof T>(keyArg: K, valueArg: T[K]): Promise<void>;
46
+ deleteKey<K extends keyof T>(keyArg: K): Promise<void>;
47
+ /**
48
+ * writes all keyValue pairs in the object argument
49
+ */
50
+ writeAll(keyValueObject: Partial<T>): Promise<void>;
51
+ /**
52
+ * wipes a key value store from disk
53
+ */
54
+ wipe(): Promise<void>;
55
+ /**
56
+ * resets the KeyValueStore to the initial state by syncing first, deleting all keys, and then triggering a sync again
57
+ */
58
+ reset(): Promise<void>;
59
+ private setMandatoryKeys;
60
+ getMissingMandatoryKeys(): Promise<Array<keyof T>>;
61
+ waitForKeysPresent<K extends keyof T>(keysArg: K[]): Promise<void>;
62
+ waitForAndGetKey<K extends keyof T>(keyArg: K): Promise<T[K] | undefined>;
63
+ }