Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/util/node/jsonFile.ts
13397 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { readFile, writeFile } from 'fs/promises';
7
import { TaskQueue } from '../common/async';
8
import { deepClone } from '../vs/base/common/objects';
9
10
export class JSONFile<T> {
11
public static async readOrCreate<T>(filePath: string, initialValue: T, indent: string | number = 4): Promise<JSONFile<T>> {
12
let data: T = initialValue;
13
14
const result = await readFileTextOrUndefined(filePath);
15
if (result !== undefined) {
16
const parsed = tryParseJson(result) as T | undefined;
17
if (parsed !== undefined) {
18
data = parsed;
19
}
20
}
21
22
return new JSONFile(filePath, data, indent);
23
}
24
25
private _value: T;
26
public get value(): Readonly<T> { return deepClone(this._value); }
27
28
private constructor(
29
public readonly filePath: string,
30
initialValue: T,
31
private readonly indent: string | number = 4,
32
) {
33
this._value = initialValue;
34
}
35
36
private readonly _writeQueue = new TaskQueue();
37
38
async setValue(value: T): Promise<void> {
39
this._value = value;
40
this._writeQueue.clearPending();
41
await this._writeQueue.scheduleSkipIfCleared(() => this._write());
42
}
43
44
private async _write(): Promise<void> {
45
await writeFile(this.filePath, JSON.stringify(this._value, null, this.indent), { encoding: 'utf8' });
46
}
47
}
48
49
export async function readFileTextOrUndefined(filePath: string): Promise<string | undefined> {
50
try {
51
return await readFile(filePath, 'utf8');
52
}
53
catch (e) {
54
if (e.code === 'ENOENT') {
55
return undefined;
56
}
57
throw e;
58
}
59
}
60
61
export function tryParseJson(str: string): unknown | undefined {
62
try {
63
return JSON.parse(str);
64
} catch (e) {
65
if (e instanceof SyntaxError) {
66
console.error(e);
67
return undefined;
68
}
69
throw e;
70
}
71
}
72
73