@reliverse/relifso 1.4.0 → 1.4.2

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.
Files changed (71) hide show
  1. package/LICENSES +16 -0
  2. package/README.md +48 -17
  3. package/bin/impl/bun.d.ts +5 -28
  4. package/bin/impl/bun.js +2 -126
  5. package/bin/impl/copy.js +8 -7
  6. package/bin/impl/create.d.ts +34 -0
  7. package/bin/impl/create.js +54 -0
  8. package/bin/impl/dive.d.ts +10 -0
  9. package/bin/impl/dive.js +89 -0
  10. package/bin/impl/empty.d.ts +28 -0
  11. package/bin/impl/empty.js +75 -0
  12. package/bin/impl/extras.d.ts +22 -2
  13. package/bin/impl/extras.js +68 -3
  14. package/bin/impl/json-utils.d.ts +30 -0
  15. package/bin/impl/json-utils.js +46 -0
  16. package/bin/impl/output-file.d.ts +3 -2
  17. package/bin/impl/output-json.d.ts +7 -2
  18. package/bin/impl/output-json.js +73 -11
  19. package/bin/impl/read-file.d.ts +15 -4
  20. package/bin/impl/read-file.js +88 -10
  21. package/bin/impl/read-json.d.ts +6 -0
  22. package/bin/impl/read-json.js +133 -21
  23. package/bin/impl/stats.d.ts +31 -0
  24. package/bin/impl/stats.js +141 -0
  25. package/bin/impl/write-file.d.ts +19 -8
  26. package/bin/impl/write-file.js +153 -24
  27. package/bin/impl/write-json.d.ts +13 -2
  28. package/bin/impl/write-json.js +46 -7
  29. package/bin/mod.d.ts +84 -36
  30. package/bin/mod.js +108 -39
  31. package/bin/utils/json/helpers/JSONRepairError.d.ts +4 -0
  32. package/bin/utils/json/helpers/JSONRepairError.js +7 -0
  33. package/bin/utils/json/helpers/JsonSchemaError.d.ts +6 -0
  34. package/bin/utils/json/helpers/JsonSchemaError.js +6 -0
  35. package/bin/utils/json/helpers/stringUtils.d.ts +64 -0
  36. package/bin/utils/json/helpers/stringUtils.js +87 -0
  37. package/bin/utils/json/regular/jsonc.d.ts +45 -0
  38. package/bin/utils/json/regular/jsonc.js +88 -0
  39. package/bin/utils/json/regular/jsonrepair.d.ts +17 -0
  40. package/bin/utils/json/regular/jsonrepair.js +576 -0
  41. package/bin/utils/json/regular/validate.d.ts +22 -0
  42. package/bin/utils/json/regular/validate.js +52 -0
  43. package/bin/utils/json/stream/JsonStreamError.d.ts +6 -0
  44. package/bin/utils/json/stream/JsonStreamError.js +6 -0
  45. package/bin/utils/json/stream/buffer/InputBuffer.d.ts +13 -0
  46. package/bin/utils/json/stream/buffer/InputBuffer.js +68 -0
  47. package/bin/utils/json/stream/buffer/OutputBuffer.d.ts +17 -0
  48. package/bin/utils/json/stream/buffer/OutputBuffer.js +101 -0
  49. package/bin/utils/json/stream/core.d.ts +10 -0
  50. package/bin/utils/json/stream/core.js +695 -0
  51. package/bin/utils/json/stream/jsonl.d.ts +21 -0
  52. package/bin/utils/json/stream/jsonl.js +55 -0
  53. package/bin/utils/json/stream/parser.d.ts +14 -0
  54. package/bin/utils/json/stream/parser.js +81 -0
  55. package/bin/utils/json/stream/stack.d.ts +19 -0
  56. package/bin/utils/json/stream/stack.js +43 -0
  57. package/bin/utils/json/stream/stream.d.ts +6 -0
  58. package/bin/utils/json/stream/stream.js +30 -0
  59. package/bin/utils/json/stream/writer.d.ts +14 -0
  60. package/bin/utils/json/stream/writer.js +44 -0
  61. package/package.json +3 -2
  62. package/bin/impl/create-file.d.ts +0 -2
  63. package/bin/impl/create-file.js +0 -21
  64. package/bin/impl/dive-async.d.ts +0 -11
  65. package/bin/impl/dive-async.js +0 -88
  66. package/bin/impl/empty-dir.d.ts +0 -2
  67. package/bin/impl/empty-dir.js +0 -24
  68. package/bin/impl/file-utils.d.ts +0 -20
  69. package/bin/impl/file-utils.js +0 -63
  70. /package/bin/{impl/logger.d.ts → utils/log.d.ts} +0 -0
  71. /package/bin/{impl/logger.js → utils/log.js} +0 -0
@@ -1,15 +1,80 @@
1
1
  import { ensuredir } from "@reliverse/relifso";
2
2
  import { exec } from "node:child_process";
3
+ import { statSync, lstatSync } from "node:fs";
3
4
  import { readdir } from "node:fs/promises";
5
+ import { stat, lstat } from "node:fs/promises";
4
6
  import { promisify } from "node:util";
5
7
  import { pathExists } from "./path-exists.js";
6
8
  import { remove } from "./remove.js";
9
+ import { readFile, readFileSync } from "./read-file.js";
10
+ export async function readText(filePath, options = "utf8") {
11
+ const effectiveOptions = typeof options === "string" ? { encoding: options } : { ...options, encoding: options.encoding || "utf8" };
12
+ return readFile(filePath, effectiveOptions);
13
+ }
14
+ export function readTextSync(filePath, options = "utf8") {
15
+ const effectiveOptions = typeof options === "string" ? { encoding: options } : { ...options, encoding: options.encoding || "utf8" };
16
+ return readFileSync(filePath, effectiveOptions);
17
+ }
18
+ export async function readLines(filePath, options = { encoding: "utf8" }) {
19
+ const effectiveOptions = typeof options === "string" ? { encoding: options } : options;
20
+ const contentBuffer = await readFile(filePath, { ...effectiveOptions, encoding: null });
21
+ return contentBuffer.toString().split(/\r?\n/);
22
+ }
23
+ export function readLinesSync(filePath, options = { encoding: "utf8" }) {
24
+ const effectiveOptions = typeof options === "string" ? { encoding: options } : options;
25
+ const contentBuffer = readFileSync(filePath, { ...effectiveOptions, encoding: null });
26
+ return contentBuffer.toString().split(/\r?\n/);
27
+ }
28
+ export async function isDirectory(filePath) {
29
+ try {
30
+ const stats = await stat(filePath);
31
+ return stats.isDirectory();
32
+ } catch (error) {
33
+ if (error.code === "ENOENT" || error.code === "ENOTDIR") {
34
+ return false;
35
+ }
36
+ throw error;
37
+ }
38
+ }
39
+ export function isDirectorySync(filePath) {
40
+ try {
41
+ const stats = statSync(filePath);
42
+ return stats.isDirectory();
43
+ } catch (error) {
44
+ if (error.code === "ENOENT" || error.code === "ENOTDIR") {
45
+ return false;
46
+ }
47
+ throw error;
48
+ }
49
+ }
50
+ export async function isSymlink(filePath) {
51
+ try {
52
+ const stats = await lstat(filePath);
53
+ return stats.isSymbolicLink();
54
+ } catch (error) {
55
+ if (error.code === "ENOENT") {
56
+ return false;
57
+ }
58
+ throw error;
59
+ }
60
+ }
61
+ export function isSymlinkSync(filePath) {
62
+ try {
63
+ const stats = lstatSync(filePath);
64
+ return stats.isSymbolicLink();
65
+ } catch (error) {
66
+ if (error.code === "ENOENT") {
67
+ return false;
68
+ }
69
+ throw error;
70
+ }
71
+ }
7
72
  export const execAsync = promisify(exec);
8
- export async function setHiddenAttributeOnWindows(folderPath) {
73
+ export async function setHiddenAttribute(folderPath) {
9
74
  if (process.platform === "win32") {
10
75
  try {
11
76
  if (await pathExists(folderPath)) {
12
- const isAlreadyHidden = await isHidden(folderPath);
77
+ const isAlreadyHidden = await isHiddenAttribute(folderPath);
13
78
  if (!isAlreadyHidden) {
14
79
  await execAsync(`attrib +h "${folderPath}"`);
15
80
  }
@@ -19,7 +84,7 @@ export async function setHiddenAttributeOnWindows(folderPath) {
19
84
  }
20
85
  }
21
86
  }
22
- export async function isHidden(filePath) {
87
+ export async function isHiddenAttribute(filePath) {
23
88
  if (process.platform === "win32") {
24
89
  const attributes = await execAsync(`attrib "${filePath}"`);
25
90
  return attributes.stdout.includes("H");
@@ -0,0 +1,30 @@
1
+ import type { WriteJsonOptions } from "./write-json.js";
2
+ export interface JsonUtilsOptions extends WriteJsonOptions {
3
+ /**
4
+ * Whether to preserve comments when reading JSONC files
5
+ * @default false
6
+ */
7
+ preserveComments?: boolean;
8
+ /**
9
+ * Whether to include comments when writing JSONC files
10
+ * @default false
11
+ */
12
+ includeComments?: boolean;
13
+ }
14
+ /**
15
+ * Validates and repairs JSON/JSONC data if necessary.
16
+ * @param data - The JSON/JSONC data to validate and repair
17
+ * @param options - Options for validation and repair
18
+ * @returns The repaired JSON/JSONC data if needed, or the original data if valid
19
+ */
20
+ export declare function validateAndRepairJson(data: unknown, options?: JsonUtilsOptions): unknown;
21
+ /**
22
+ * Ensures that the directory for the JSON/JSONC file exists and then writes the data to the file.
23
+ * This is a utility function to avoid circular dependencies.
24
+ */
25
+ export declare function ensureJsonFileSync(file: string, data: unknown, options?: JsonUtilsOptions): void;
26
+ /**
27
+ * Ensures that the directory for the JSON/JSONC file exists and then asynchronously writes the data to the file.
28
+ * This is a utility function to avoid circular dependencies.
29
+ */
30
+ export declare function ensureJsonFile(file: string, data: unknown, options?: JsonUtilsOptions): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import { dirname } from "node:path";
2
+ import { extname } from "node:path";
3
+ import { parseJsonc, isValidJsonc } from "../utils/json/regular/jsonc.js";
4
+ import { jsonrepair } from "../utils/json/regular/jsonrepair.js";
5
+ import { mkdirsSync } from "./mkdirs.js";
6
+ import { mkdirs } from "./mkdirs.js";
7
+ import { writeJsonSync } from "./write-json.js";
8
+ import { writeJson } from "./write-json.js";
9
+ export function validateAndRepairJson(data, options = {}) {
10
+ if (typeof data === "string") {
11
+ try {
12
+ JSON.parse(data);
13
+ return data;
14
+ } catch {
15
+ const isJsonc = extname(data).toLowerCase() === ".jsonc" || isValidJsonc(data);
16
+ if (isJsonc) {
17
+ try {
18
+ return parseJsonc(data, { preserveComments: options.preserveComments });
19
+ } catch {
20
+ return jsonrepair(data);
21
+ }
22
+ } else {
23
+ return jsonrepair(data);
24
+ }
25
+ }
26
+ }
27
+ return data;
28
+ }
29
+ export function ensureJsonFileSync(file, data, options) {
30
+ const dir = dirname(file);
31
+ mkdirsSync(dir);
32
+ const repairedData = validateAndRepairJson(data, options);
33
+ writeJsonSync(file, repairedData, {
34
+ ...options,
35
+ spaces: 2
36
+ });
37
+ }
38
+ export async function ensureJsonFile(file, data, options) {
39
+ const dir = dirname(file);
40
+ await mkdirs(dir);
41
+ const repairedData = validateAndRepairJson(data, options);
42
+ await writeJson(file, repairedData, {
43
+ ...options,
44
+ spaces: 2
45
+ });
46
+ }
@@ -1,3 +1,4 @@
1
+ import type { WriteFileOptions } from "./write-file.js";
1
2
  /**
2
3
  * Ensures that the directory for the file exists and then writes the data to the file.
3
4
  *
@@ -5,7 +6,7 @@
5
6
  * @param data - The data to write.
6
7
  * @param options - Options for writing the file (e.g., encoding, mode, flag).
7
8
  */
8
- export declare function outputFileSync(file: string, data: string | Uint8Array, options?: unknown): void;
9
+ export declare function outputFileSync(file: string, data: string | Uint8Array, options?: WriteFileOptions): void;
9
10
  /**
10
11
  * Ensures that the directory for the file exists and then asynchronously writes the data to the file.
11
12
  *
@@ -13,4 +14,4 @@ export declare function outputFileSync(file: string, data: string | Uint8Array,
13
14
  * @param data - The data to write.
14
15
  * @param options - Options for writing the file (e.g., encoding, mode, flag).
15
16
  */
16
- export declare function outputFile(file: string, data: string | Uint8Array, options?: unknown): Promise<void>;
17
+ export declare function outputFile(file: string, data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
@@ -1,3 +1,8 @@
1
+ import type { WriteJsonOptions } from "./write-json.js";
2
+ import { type JsonUtilsOptions } from "./json-utils.js";
3
+ export interface OutputJsonOptions extends WriteJsonOptions {
4
+ useStreaming?: boolean;
5
+ }
1
6
  /**
2
7
  * Ensures that the directory for the JSON file exists and then writes the JSON data to the file.
3
8
  *
@@ -5,7 +10,7 @@
5
10
  * @param data - The JSON data to write.
6
11
  * @param options - Options for writing the JSON file (e.g., replacer, spaces).
7
12
  */
8
- export declare function outputJsonSync(file: string, data: unknown, options?: unknown): void;
13
+ export declare function outputJsonSync(file: string, data: unknown, options?: BufferEncoding | OutputJsonOptions): void;
9
14
  /**
10
15
  * Ensures that the directory for the JSON file exists and then asynchronously writes the JSON data to the file.
11
16
  *
@@ -13,4 +18,4 @@ export declare function outputJsonSync(file: string, data: unknown, options?: un
13
18
  * @param data - The JSON data to write.
14
19
  * @param options - Options for writing the JSON file (e.g., replacer, spaces).
15
20
  */
16
- export declare function outputJson(file: string, data: unknown, options?: unknown): Promise<void>;
21
+ export declare function outputJson(file: string, data: unknown, options?: BufferEncoding | OutputJsonOptions | JsonUtilsOptions): Promise<void>;
@@ -1,15 +1,77 @@
1
- import { dirname } from "node:path";
2
- import { mkdirsSync } from "./mkdirs.js";
3
- import { mkdirs } from "./mkdirs.js";
4
- import { writeJsonSync } from "./write-json.js";
5
- import { writeJson } from "./write-json.js";
1
+ import { createWriteStream } from "node:fs";
2
+ import { Transform } from "node:stream";
3
+ import { pipeline } from "node:stream/promises";
4
+ import { logInternal } from "../utils/log.js";
5
+ import { ensureJsonFileSync, ensureJsonFile } from "./json-utils.js";
6
6
  export function outputJsonSync(file, data, options) {
7
- const dir = dirname(file);
8
- mkdirsSync(dir);
9
- writeJsonSync(file, data, options);
7
+ const jsonOptions = typeof options === "string" ? { encoding: options } : options ?? {};
8
+ ensureJsonFileSync(file, data, jsonOptions);
10
9
  }
11
10
  export async function outputJson(file, data, options) {
12
- const dir = dirname(file);
13
- await mkdirs(dir);
14
- await writeJson(file, data, options);
11
+ let useStreaming = false;
12
+ let encoding = "utf8";
13
+ let replacer;
14
+ let spaces;
15
+ let flag;
16
+ let mode;
17
+ let throws = true;
18
+ if (typeof options === "string") {
19
+ encoding = options;
20
+ } else if (options) {
21
+ if ("encoding" in options) {
22
+ encoding = options.encoding ?? encoding;
23
+ }
24
+ if ("replacer" in options) {
25
+ replacer = options.replacer;
26
+ }
27
+ if ("spaces" in options) {
28
+ spaces = options.spaces;
29
+ }
30
+ if ("flag" in options) {
31
+ flag = options.flag;
32
+ }
33
+ if ("mode" in options) {
34
+ mode = options.mode ? Number(options.mode) : void 0;
35
+ }
36
+ if ("useStreaming" in options) {
37
+ useStreaming = options.useStreaming ?? useStreaming;
38
+ }
39
+ if ("throws" in options && options.throws !== void 0) {
40
+ throws = options.throws;
41
+ }
42
+ }
43
+ try {
44
+ if (useStreaming) {
45
+ try {
46
+ const writeStream = createWriteStream(file, { encoding, mode, flags: flag });
47
+ const jsonString = JSON.stringify(data, replacer, spaces);
48
+ if (jsonString === void 0) {
49
+ throw new Error("Failed to stringify JSON object");
50
+ }
51
+ const transform = new Transform({
52
+ transform(chunk, _encoding, callback) {
53
+ callback(null, chunk);
54
+ }
55
+ });
56
+ transform.write(jsonString);
57
+ transform.end();
58
+ await pipeline(transform, writeStream);
59
+ return;
60
+ } catch (streamError) {
61
+ }
62
+ }
63
+ await ensureJsonFile(file, data, {
64
+ encoding,
65
+ replacer,
66
+ spaces,
67
+ flag,
68
+ mode,
69
+ throws,
70
+ useStreaming
71
+ });
72
+ } catch (err) {
73
+ if (throws) {
74
+ throw err;
75
+ }
76
+ }
15
77
  }
@@ -1,20 +1,31 @@
1
1
  export interface ReadFileOptions {
2
2
  encoding?: BufferEncoding | null;
3
3
  flag?: string;
4
+ isJson?: boolean;
5
+ useStreaming?: boolean;
6
+ reviver?: (key: string, value: unknown) => unknown;
4
7
  }
5
8
  /**
6
9
  * Synchronously reads the entire contents of a file.
7
10
  *
8
11
  * @param path - The path to the file.
9
12
  * @param options - Options for reading the file. Can be an encoding string or an object.
10
- * @returns The contents of the file.
13
+ * @returns The contents of the file as a string.
11
14
  */
12
- export declare function readFileSync(path: string, options?: BufferEncoding | ReadFileOptions): string | Buffer;
15
+ export declare function readFileSync(path: string, options?: BufferEncoding | ReadFileOptions): string;
16
+ export declare function readFileSync(path: string, encoding: BufferEncoding): string;
17
+ export declare function readFileSync(path: string, options: {
18
+ encoding: BufferEncoding;
19
+ }): string;
13
20
  /**
14
21
  * Asynchronously reads the entire contents of a file.
15
22
  *
16
23
  * @param path - The path to the file.
17
24
  * @param options - Options for reading the file. Can be an encoding string or an object.
18
- * @returns A promise that resolves with the contents of the file.
25
+ * @returns A promise that resolves with the contents of the file as a string.
19
26
  */
20
- export declare function readFile(path: string, options?: BufferEncoding | ReadFileOptions): Promise<string | Buffer>;
27
+ export declare function readFile(path: string, options?: BufferEncoding | ReadFileOptions): Promise<string>;
28
+ export declare function readFile(path: string, encoding: BufferEncoding): Promise<string>;
29
+ export declare function readFile(path: string, options: {
30
+ encoding: BufferEncoding;
31
+ }): Promise<string>;
@@ -1,7 +1,11 @@
1
1
  import { readFileSync as nodeReadFileSync } from "node:fs";
2
+ import { createReadStream } from "node:fs";
2
3
  import { readFile as nodeReadFileAsync } from "node:fs/promises";
4
+ import { Transform } from "node:stream";
5
+ import { pipeline } from "node:stream/promises";
6
+ import { jsonrepair } from "../utils/json/regular/jsonrepair.js";
7
+ import { logInternal } from "../utils/log.js";
3
8
  import { isBun, getFileBun } from "./bun.js";
4
- import { logInternal } from "./logger.js";
5
9
  export function readFileSync(path, options) {
6
10
  let encoding;
7
11
  let flag;
@@ -34,13 +38,13 @@ export function readFileSync(path, options) {
34
38
  if (buffer instanceof Promise) {
35
39
  throw new Error("Bun's arrayBuffer() returned a Promise in sync context");
36
40
  }
37
- return Buffer.from(buffer);
41
+ return Buffer.from(buffer).toString(encoding || "utf8");
38
42
  } catch (_error) {
39
43
  const text = file.text();
40
44
  if (text instanceof Promise) {
41
45
  throw new Error("Bun's text() returned a Promise in sync context");
42
46
  }
43
- return Buffer.from(text);
47
+ return text;
44
48
  }
45
49
  } catch (error) {
46
50
  }
@@ -48,40 +52,114 @@ export function readFileSync(path, options) {
48
52
  if (encoding) {
49
53
  return nodeReadFileSync(path, { encoding, flag });
50
54
  }
51
- return nodeReadFileSync(path, { encoding: null, flag });
55
+ return nodeReadFileSync(path, { encoding: "utf8", flag });
52
56
  }
53
57
  export async function readFile(path, options) {
54
58
  let encoding;
55
59
  let flag;
60
+ let isJson = false;
61
+ let useStreaming = false;
62
+ let reviver;
56
63
  if (typeof options === "string") {
57
64
  encoding = options;
58
65
  } else if (options) {
59
66
  encoding = options.encoding;
60
67
  flag = options.flag;
68
+ isJson = options.isJson ?? isJson;
69
+ useStreaming = options.useStreaming ?? useStreaming;
70
+ reviver = options.reviver;
61
71
  }
62
72
  if (isBun) {
63
73
  try {
64
74
  const file = getFileBun(path);
65
75
  if (encoding) {
66
76
  try {
67
- return await file.text();
77
+ const result = await file.text();
78
+ if (isJson) {
79
+ try {
80
+ return JSON.stringify(JSON.parse(result, reviver));
81
+ } catch (_parseError) {
82
+ const repaired = jsonrepair(result);
83
+ return JSON.stringify(JSON.parse(repaired, reviver));
84
+ }
85
+ }
86
+ return result;
68
87
  } catch (_error) {
69
88
  const buffer = await file.arrayBuffer();
70
- return Buffer.from(buffer).toString(encoding);
89
+ const text = Buffer.from(buffer).toString(encoding);
90
+ if (isJson) {
91
+ try {
92
+ return JSON.stringify(JSON.parse(text, reviver));
93
+ } catch (_parseError) {
94
+ const repaired = jsonrepair(text);
95
+ return JSON.stringify(JSON.parse(repaired, reviver));
96
+ }
97
+ }
98
+ return text;
71
99
  }
72
100
  }
73
101
  try {
74
102
  const buffer = await file.arrayBuffer();
75
- return Buffer.from(buffer);
103
+ const text = Buffer.from(buffer).toString(encoding || "utf8");
104
+ if (isJson) {
105
+ try {
106
+ return JSON.stringify(JSON.parse(text, reviver));
107
+ } catch (_parseError) {
108
+ const repaired = jsonrepair(text);
109
+ return JSON.stringify(JSON.parse(repaired, reviver));
110
+ }
111
+ }
112
+ return text;
76
113
  } catch (_error) {
77
114
  const text = await file.text();
78
- return Buffer.from(text);
115
+ if (isJson) {
116
+ try {
117
+ return JSON.stringify(JSON.parse(text, reviver));
118
+ } catch (_parseError) {
119
+ const repaired = jsonrepair(text);
120
+ return JSON.stringify(JSON.parse(repaired, reviver));
121
+ }
122
+ }
123
+ return text;
79
124
  }
80
125
  } catch (error) {
81
126
  }
82
127
  }
128
+ if (useStreaming && encoding) {
129
+ try {
130
+ const chunks = [];
131
+ const transform = new Transform({
132
+ transform(chunk, _encoding, callback) {
133
+ chunks.push(chunk.toString());
134
+ callback();
135
+ }
136
+ });
137
+ const readStream = createReadStream(path, { encoding, flags: flag });
138
+ await pipeline(readStream, transform);
139
+ const text = chunks.join("");
140
+ if (isJson) {
141
+ try {
142
+ return JSON.stringify(JSON.parse(text, reviver));
143
+ } catch (_parseError) {
144
+ const repaired = jsonrepair(text);
145
+ return JSON.stringify(JSON.parse(repaired, reviver));
146
+ }
147
+ }
148
+ return text;
149
+ } catch (streamError) {
150
+ }
151
+ }
83
152
  if (encoding) {
84
- return nodeReadFileAsync(path, { encoding, flag });
153
+ const text = await nodeReadFileAsync(path, { encoding, flag });
154
+ if (isJson) {
155
+ try {
156
+ return JSON.stringify(JSON.parse(text, reviver));
157
+ } catch (_parseError) {
158
+ const repaired = jsonrepair(text);
159
+ return JSON.stringify(JSON.parse(repaired, reviver));
160
+ }
161
+ }
162
+ return text;
85
163
  }
86
- return nodeReadFileAsync(path, { encoding: null, flag });
164
+ return await nodeReadFileAsync(path, { encoding: "utf8", flag });
87
165
  }
@@ -5,6 +5,12 @@ export interface ReadJsonOptions {
5
5
  throws?: boolean;
6
6
  defaultValue?: unknown;
7
7
  ensure?: boolean;
8
+ useStreaming?: boolean;
9
+ /**
10
+ * Whether to preserve comments when reading JSONC files
11
+ * @default false
12
+ */
13
+ preserveComments?: boolean;
8
14
  }
9
15
  /**
10
16
  * Reads a JSON file and then parses it into an object.