23import * as fs from
'fs/promises';
24import * as
path from
'path';
61suite(
'LazyFileLoader Test Suite',
function () {
74 tempDir = await fs.mkdtemp(
path.join(__dirname,
'temp-lazyloader-'));
75 testFilePath =
path.join(tempDir,
'test-config.json');
82 teardown(async () => {
85 await fs.rm(tempDir, { recursive:
true, force:
true });
95 suite(
'Basic File Loading', () => {
100 test(
'should load and parse JSON file correctly', async () => {
101 const testData:
TestConfig = { name:
'test', value: 42, enabled:
true };
102 await fs.writeFile(testFilePath, JSON.stringify(testData));
104 await loader.updateFilePath(testFilePath);
105 const result = await loader.get();
107 assert.strictEqual(result?.name,
'test');
108 assert.strictEqual(result?.value, 42);
109 assert.strictEqual(result?.enabled,
true);
116 test(
'should load plain text file as string', async () => {
118 const textFile =
path.join(tempDir,
'test.txt');
119 const testContent =
'Hello, World!\nThis is a test file.';
121 await fs.writeFile(textFile, testContent);
122 await loader.updateFilePath(textFile);
124 const result = await loader.get();
125 assert.strictEqual(result, testContent);
132 test(
'should handle empty JSON file', async () => {
133 await fs.writeFile(testFilePath,
'{}');
134 await loader.updateFilePath(testFilePath);
136 const result = await loader.get();
137 assert.strictEqual(typeof result,
'object');
138 assert.strictEqual(Object.keys(result || {}).length, 0);
146 suite(
'Caching Behavior', () => {
151 test(
'should cache loaded content and not reload on subsequent calls', async () => {
152 const testData:
TestConfig = { name:
'cached', value: 100, enabled:
false };
153 await fs.writeFile(testFilePath, JSON.stringify(testData));
154 await loader.updateFilePath(testFilePath);
157 const result1 = await loader.get();
160 const modifiedData:
TestConfig = { name:
'modified', value: 200, enabled:
true };
161 await fs.writeFile(testFilePath, JSON.stringify(modifiedData));
164 const result2 = await loader.get();
166 assert.strictEqual(result1?.name, result2?.name);
167 assert.strictEqual(result1?.value, result2?.value);
168 assert.strictEqual(result2?.name,
'cached');
175 test(
'should reload content after calling reload()', async () => {
176 const initialData:
TestConfig = { name:
'initial', value: 1, enabled:
true };
177 await fs.writeFile(testFilePath, JSON.stringify(initialData));
178 await loader.updateFilePath(testFilePath);
181 const result1 = await loader.get();
182 assert.strictEqual(result1?.name,
'initial');
185 const updatedData:
TestConfig = { name:
'updated', value: 2, enabled:
false };
186 await fs.writeFile(testFilePath, JSON.stringify(updatedData));
188 const result2 = await loader.reload();
189 assert.strictEqual(result2?.name,
'updated');
190 assert.strictEqual(result2?.value, 2);
197 test(
'should clear cache with unload()', async () => {
198 const testData:
TestConfig = { name:
'test', value: 42, enabled:
true };
199 await fs.writeFile(testFilePath, JSON.stringify(testData));
200 await loader.updateFilePath(testFilePath);
203 const result1 = await loader.get();
210 const newData:
TestConfig = { name:
'new', value: 99, enabled:
false };
211 await fs.writeFile(testFilePath, JSON.stringify(newData));
214 const result2 = await loader.get();
215 assert.strictEqual(result2?.name,
'new');
216 assert.strictEqual(result2?.value, 99);
224 suite(
'Path Resolution', () => {
229 test(
'should handle absolute paths correctly', async () => {
230 const testData:
TestConfig = { name:
'absolute', value: 123, enabled:
true };
231 await fs.writeFile(testFilePath, JSON.stringify(testData));
233 await loader.updateFilePath(testFilePath);
234 const result = await loader.get();
236 assert.strictEqual(result?.name,
'absolute');
243 test(
'should resolve relative paths with working directory', async () => {
244 const testData:
TestConfig = { name:
'relative', value: 456, enabled:
false };
245 await fs.writeFile(testFilePath, JSON.stringify(testData));
247 await loader.updateCurrentWorkingDirectory(tempDir);
248 await loader.updateFilePath(
'test-config.json');
250 const result = await loader.get();
251 assert.strictEqual(result?.name,
'relative');
258 test(
'should validate working directory exists', async () => {
259 const nonExistentPath =
path.join(tempDir,
'nonexistent');
260 const success = await loader.updateCurrentWorkingDirectory(nonExistentPath);
261 assert.strictEqual(success,
false);
269 suite(
'Error Handling', () => {
274 test(
'should return undefined for non-existent file', async () => {
275 const nonExistentPath =
path.join(tempDir,
'nonexistent.json');
276 await loader.updateFilePath(nonExistentPath);
279 const result = await loader.get();
280 assert.strictEqual(result, undefined,
'Should return undefined for non-existent file');
287 test(
'should handle malformed JSON gracefully', async () => {
288 const malformedJson =
'{ name: "test", value: 42, invalid }';
289 await fs.writeFile(testFilePath, malformedJson);
290 await loader.updateFilePath(testFilePath);
292 const result = await loader.get();
294 assert.strictEqual(result, malformedJson);
301 test(
'should return undefined when no file path is set', async () => {
302 const result = await loader.get();
303 assert.strictEqual(result, undefined);
311 suite(
'File Path Management', () => {
316 test(
'should update file path successfully', async () => {
317 const testData:
TestConfig = { name:
'test', value: 42, enabled:
true };
318 await fs.writeFile(testFilePath, JSON.stringify(testData));
320 const success = await loader.updateFilePath(testFilePath);
321 assert.strictEqual(success,
true);
323 const retrievedPath = loader.getFilePath();
324 assert.strictEqual(retrievedPath, testFilePath);
331 test(
'should reload content when updating file path with cached data', async () => {
333 const firstData:
TestConfig = { name:
'first', value: 1, enabled:
true };
334 await fs.writeFile(testFilePath, JSON.stringify(firstData));
335 await loader.updateFilePath(testFilePath);
339 const secondFilePath =
path.join(tempDir,
'second.json');
340 const secondData:
TestConfig = { name:
'second', value: 2, enabled:
false };
341 await fs.writeFile(secondFilePath, JSON.stringify(secondData));
344 const success = await loader.updateFilePath(secondFilePath);
345 assert.strictEqual(success,
true);
347 const result = await loader.get();
348 assert.strictEqual(result?.name,
'second');
355 test(
'should return false when updating to invalid file with cached data', async () => {
357 const testData:
TestConfig = { name:
'test', value: 42, enabled:
true };
358 await fs.writeFile(testFilePath, JSON.stringify(testData));
359 await loader.updateFilePath(testFilePath);
363 const nonExistentPath =
path.join(tempDir,
'nonexistent.json');
365 const success = await loader.updateFilePath(nonExistentPath);
366 assert.fail(
'Expected error when updating to invalid file');
368 assert.ok((error as any).code ===
'ENOENT',
'Should throw ENOENT error for invalid file path');
377 suite(
'Type Safety and Complex Data', () => {
382 test(
'should handle complex nested objects with type safety', async () => {
384 const complexFile =
path.join(tempDir,
'complex.json');
389 author:
'Test Author'
391 items: [
'item1',
'item2',
'item3']
394 await fs.writeFile(complexFile, JSON.stringify(testData));
395 await complexLoader.updateFilePath(complexFile);
397 const result = await complexLoader.get();
401 assert.strictEqual(result.metadata.version,
'1.0.0');
402 assert.strictEqual(result.metadata.author,
'Test Author');
403 assert.ok(Array.isArray(result.items));
404 assert.strictEqual(result.items.length, 3);
412 test(
'should support JSONC files with comments', async () => {
413 const jsoncFile =
path.join(tempDir,
'config.jsonc');
414 const jsoncContent = `{
416 "name":
"jsonc-test",
422 await fs.writeFile(jsoncFile, jsoncContent);
423 await loader.updateFilePath(jsoncFile);
425 const result = await loader.get();
428 assert.ok(result !== undefined,
'JSONC file should be parsed successfully');
429 assert.strictEqual((result as any).name,
'jsonc-test');
430 assert.strictEqual((result as any).value, 789);
431 assert.strictEqual((result as any).enabled,
true);
439 suite(
'Path Utilities', () => {
444 test(
'should check path existence correctly', async () => {
446 const exists = await loader.pathExists(testFilePath);
447 assert.strictEqual(exists,
false);
450 await fs.writeFile(testFilePath,
'{}');
451 const existsAfterCreation = await loader.pathExists(testFilePath);
452 assert.strictEqual(existsAfterCreation,
true);
459 test(
'should handle directory paths in pathExists', async () => {
460 const exists = await loader.pathExists(tempDir);
461 assert.strictEqual(exists,
true);
469 suite(
'Edge Cases and Performance', () => {
474 test(
'should handle large JSON files efficiently', async () => {
475 const largeArray = Array.from({ length: 1000 }, (_, i) => ({
481 const largeFile =
path.join(tempDir,
'large.json');
482 await fs.writeFile(largeFile, JSON.stringify(largeArray));
485 await largeLoader.updateFilePath(largeFile);
487 const startTime = Date.now();
488 const result = await largeLoader.get();
489 const loadTime = Date.now() - startTime;
492 assert.strictEqual(result.length, 1000);
493 assert.ok(loadTime < 1000,
'Loading should complete within 1 second');
496 const cachedStartTime = Date.now();
497 const cachedResult = await largeLoader.get();
498 const cachedLoadTime = Date.now() - cachedStartTime;
502 assert.deepStrictEqual(cachedResult, result,
'Cached result should be identical to original');
503 assert.ok(cachedLoadTime <= loadTime + 50,
'Cached access should be at least as fast as initial load');
510 test(
'should handle empty file paths gracefully', async () => {
511 const success = await loader.updateFilePath(
'');
512 assert.strictEqual(success,
true);
516 const result = await loader.get();
517 assert.fail(
'Expected error for empty file path');
519 assert.ok((error as any).code ===
'EISDIR',
'Should throw EISDIR error for directory path');
527 test(
'should handle concurrent file loading requests', async () => {
528 const testFile =
path.join(tempDir,
'concurrent.json');
530 name:
'concurrent-test',
535 await fs.writeFile(testFile, JSON.stringify(testData));
536 await loader.updateFilePath(testFile);
539 const promises = Array.from({ length: 5 }, () => loader.get());
540 const results = await Promise.all(
promises);
543 results.forEach((result, index) => {
544 assert.ok(result, `Result ${index} should not be
null or undefined`);
545 assert.strictEqual(result?.name,
'concurrent-test', `Result ${index} should have correct name`);
546 assert.strictEqual(result?.value, 42, `Result ${index} should have correct value`);
547 assert.strictEqual(result?.enabled,
true, `Result ${index} should have correct enabled status`);
551 assert.deepStrictEqual(result, results[0], `Result ${index} should have identical content to result 0`);
556 const cachedResult = await loader.get();
557 assert.deepStrictEqual(cachedResult, results[0],
'Cached result after concurrent loading should match');
564 test(
'should maintain independence between loader instances', async () => {
568 const file1 =
path.join(tempDir,
'config1.json');
569 const file2 =
path.join(tempDir,
'config2.json');
571 const data1:
TestConfig = { name:
'loader1', value: 1, enabled:
true };
572 const data2:
TestConfig = { name:
'loader2', value: 2, enabled:
false };
574 await fs.writeFile(file1, JSON.stringify(data1));
575 await fs.writeFile(file2, JSON.stringify(data2));
577 await loader1.updateFilePath(file1);
578 await loader2.updateFilePath(file2);
580 const result1 = await loader1.get();
581 const result2 = await loader2.get();
583 assert.strictEqual(result1?.name,
'loader1');
584 assert.strictEqual(result2?.name,
'loader2');
585 assert.notStrictEqual(result1, result2);
Generic lazy file loader with caching and type safety @template T The expected type of the loaded fil...
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAAv3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbEsMgCPznFD2CAho5jknTmd6gx qtNJMEqCKH4h lRj6dADxVZugptTqwzYer65UeIe5DWUctXFzIXEu5EdIHqrWYry UL6xZmlG7UnJa57b oHlEkAAAGEaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDUBSFT1OlKhWHFhFxyFA72UVFHGsVilAh1AqtOpi89A aNCQpLo6Ca8HBn8Wqg4uzrg6ugiD4A IuOCm6SIn3JYUWsT64vI z3jncdx8gNCpMs3rigKbbZjqZELO5VTHwin4MU4UQlZllzElSCl3X1z18fL L8azu9 Ma56LLAM8NmJj1PHCYWix2sdDArmRrxNHFE1XTKF7Ieq5y3OGuVGmv1yV8YzOsry1ynGkMSi1iCBBEKaiijAhsx2nVSLKTpPNHFP r6JXIp5CqDkWMBVWiQXT yerVWYmvSSggmg98VxPsaBwC7QrDvO97HjNE8A zNwpbf91QYw KqFQAN7P6JtyQOgWGFjz5tY6x kDkKFZpW6Ag0MgWqTs9S7v7uuc2793WvP7AZKlcrMQx gGAAANcmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDowOWQ3ODk3OS03YjNiLTRhMTgtODM5ZS1lMDgwOGNjMmUzY2EiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTM2YWE3YmMtN2QzZS00ZDJkLWIxMjItYTFhZjQwMjkzYjI5IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTc2ZWEzNTgtNTNlNy00ODZkLWIzMzQtMjhmZWY1N2IyZWIzIgogICBHSU1QOkFQST0iMy4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3NTg1MzI3OTM2NzA4NzIiCiAgIEdJTVA6VmVyc2lvbj0iMy4wLjQiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjU6MDk6MjJUMTE6MTk6NTArMDI6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI1OjA5OjIyVDExOjE5OjUwKzAyOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGE1MDJhZWEtNDM0MS00NjdjLTgwMzEtYjUwMmU2OGFhYjkwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHSU1QIDMuMC40IChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjUtMDktMjJUMTE6MTk6NTMrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8 QZaInQAAAAZiS0dEAAAAAAAA UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB kJFgkTNb1wNOYAABokSURBVHja7V15dFRF1r9V7 WW7mwsAZJ0SJpElARhUBM0gKNwjsM2gIMw oF Ss4MHy5DmBEB56g4Is6ZIQGRJYownzIalCUzLnj0Cx7GBZhAWISIMGaTYIBgku5Od7 t7vdH8pruTifpzkaAd8 pk8573fWqbv3q3lu3bt1HEPEkAAyAThLf8uNBna2AQhfJW4EkSV2rgOd5SEpKavWF yv QjEZjq58rigLJyclAqfdZZMaMGbX5 fmDAQAIItb2jbnQWVK70KUK8Kp2IWAuYOcrSEpKAkJIwG0GQ5OtXekCBUDabss6qIABEAaEEKitrXVnZ2eLwaSy3w uPI2CLCtAgAMAgLFjx oqKyt59b7a3VZMbJYDzXJBp NAUZoFSWVlJa sKCgoK6NLgSXBSdOnGhseQAiImRnZ0u T21TFiAqmJgYj3PmzHF4ryiK7PuNDipAHDhwICIirly58kJ1daUz8L4XylarFX744YdW45CcnNzcmSvyAMrLy vqXOiKPBgEV4koXGXqmw0YOnQoDB06NKQK9u3bdz6YWdPpBqhGRWjoZsBQBkIxQBD12hA0y1vVBiOEgCIrYVmLXWxAs7z2teE4noPt27fbw7Gyg89PijA02RpETalWZ7N42rJlCzDlSl8kSYKpU6fqAAAEQYCHHnzIuWv3Lsvx48drb7311sGt6vO1zhARGWNotVrRarUiYwzbJwWLiz rSUyMR0QFRVFEH6mNR44caXK73aLH45EREQsKCjy JTMzEyPeiclJQVGjhwZYTQadZRSTpIkGDx4sCAIgtguB1TV0pZ6aY8DiIhlZWVNKjMREQVBUH7 ziBhdaEVB8KtINzva8qo29cH3dEAvKGHQGtA322AIivQG hs1QDGGAwdOhQoR0OSclarFbKysuq7zyZk4dmEiAoQgu16tXoNA1fHKPUrV5kDhBCQJAkYY73VABZQAEpKShyKokB fr49JPM80ESSJRmtVqufW7A9kywhYQhmZd3xk2qSqYYtImJCQkKHNdC2etbsEWABrljFb UkCBLwvB4I4bzM3L17d OpU6caEBFmzZrlfuaZZ wqOIOBlA JiCQnJLkddu0tS7Ytm2brCgKL8uy99Y777xD33vvvUhCCJyvOS lpqUq fv MREBE3btzoREQ8ePCgK3Ct0U4DWEgLE98GFBYWlvvenTRpknP8 PGNKp6C1dnFBiAmJibi7bff lPg9dTUVCmwjtWrVzcsW7bM3o3rAn9yu91gMplAkRU4 e1pXpZl0Ol03vsVFRVcQUGBpV05QCgJw RmV1bIwKCkpMSh1sHxnPfhJ0 etCMiBD682yXhkiVLdOqqWd0tYYzBiBEjotrqTLfoggiTBQAoHD582Hju3Dk3YzJyHIGH uvXrltuucXruAjJKmaMQXJyMlRVVYVsDwRzdQc2dO3atbWzZs1q5R g21KrgQBqiziO83 U16fK Bgc7OFtrgsCvdo9uTjVFiZaA7QGXPX9ght BDQGaAzQGKAx4GpSyEuSr7 Kysru7xDodK ffvOP LII GEEBgyZEj9oUOHYvsUAhDR6zP0vdZ1BjQvWhjKgKgA5Tg PyMi6ZR5r8mAnpIBPcZ7NegSA pSuSFfxTtzTffbLbZbKb09HRp0aJF5mPHjkWkp6db3n777foZM2Y4rxIDWBil60j45JNP6jdv3txYVVVVDwCg1 th vz5sRcvXoTDhw b6 rq3L0kAxjwPA83DU8FURSDOmWuqAraLq8REbZt2ybzvA4o5QGZKvlbj8mAAQN0c fONZ49e9Yv5Pf2228X586d22 hfqX3ieB47j DYcgu3tuN1uZenSpdx export const string
Complex nested data structure interface for advanced type safety testing.
Basic test configuration interface for LazyFileLoader testing.
import *as path from path
import *as assert from assert
import *as fs from fs promises