@reliverse/relifso 1.4.1 → 1.4.3
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.
- package/README.md +66 -1
- package/bin/impl/copy.d.ts +2 -2
- package/bin/impl/copy.js +2 -2
- package/bin/impl/move.d.ts +3 -0
- package/bin/impl/read-file.d.ts +4 -4
- package/bin/impl/read-file.js +19 -19
- package/bin/impl/write-file.d.ts +3 -3
- package/bin/impl/write-file.js +71 -151
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
- 🧯 Gracefully handles errors like `EMFILE` (reading or writing a lot of files at once) and other edge cases
|
|
14
14
|
- 📚 Consistent error-first behavior — even for legacy APIs like `fs.exists()`
|
|
15
15
|
- 📦 First-class ESM and full TypeScript support — no config hacks required
|
|
16
|
-
- 🧼 Zero bloat — small size
|
|
16
|
+
- 🧼 Zero bloat — small size, zero deps, modern code, no monkey-patching
|
|
17
17
|
- 🎯 Supports all Node.js v16+ features — optimized for Node.js v22+
|
|
18
18
|
- 🧪 Soon: Ready for upcoming Node.js v22+ experimental features
|
|
19
19
|
- ✌️ Bun v1.2+ ready — ships with Bun-aware enhancements out of the box
|
|
@@ -129,6 +129,71 @@ console.log(config); // { hello: 'world' }
|
|
|
129
129
|
await remove(".reliverse");
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
+
## Run Example
|
|
133
|
+
|
|
134
|
+
Install this repository locally and run the example by using `bun dev`:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
$ bun e-mod.ts
|
|
138
|
+
✓ Running examples with Bun...
|
|
139
|
+
Created directory ./tests-runtime
|
|
140
|
+
[env] writeJson was successfully executed in Bun (for JSON)
|
|
141
|
+
Wrote JSON tests-runtime\config.json
|
|
142
|
+
[env] readJson was successfully executed in Bun
|
|
143
|
+
Read JSON {"hello":"world","ts":"2025-06-02T19:01:53.291Z"}
|
|
144
|
+
[env] copy was successfully executed in Bun
|
|
145
|
+
Moved → Copied (with overwrite) tests-runtime\config.old.json → tests-runtime\config.copy.json
|
|
146
|
+
[env] readFile was successfully executed in Bun
|
|
147
|
+
Wrote & read text file Hello Relifso!
|
|
148
|
+
[env] writeFile was successfully executed in Bun
|
|
149
|
+
[env] writeFile was successfully executed in Bun
|
|
150
|
+
Ensured nested & output files
|
|
151
|
+
[env] writeJson was successfully executed in Bun (for JSON)
|
|
152
|
+
[env] readJson was successfully executed in Bun
|
|
153
|
+
writeJson / readJson round-trip {"foo":"bar"}
|
|
154
|
+
[env] writeJson was successfully executed in Bun (for JSONC)
|
|
155
|
+
Wrote JSONC tests-runtime\config.jsonc
|
|
156
|
+
[env] readJson was successfully executed in Bun
|
|
157
|
+
Read JSONC {
|
|
158
|
+
"name": "relifso",
|
|
159
|
+
"version": "1.0.0",
|
|
160
|
+
"features": [
|
|
161
|
+
"file operations",
|
|
162
|
+
"directory operations",
|
|
163
|
+
"JSONC support"
|
|
164
|
+
],
|
|
165
|
+
"settings": {
|
|
166
|
+
"debug": true,
|
|
167
|
+
"verbose": false
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
Emptied directory tests-runtime\empty-me
|
|
171
|
+
[env] writeFileSync was successfully executed in Bun
|
|
172
|
+
[env] writeJsonSync was successfully executed in Bun (for JSON)
|
|
173
|
+
Sync JSON round-trip {"sync":true}
|
|
174
|
+
[env] copySync was successfully executed in Bun
|
|
175
|
+
copySync → moveSync → removeSync chain complete
|
|
176
|
+
Directory structure via dive
|
|
177
|
+
• tests-runtime\config-sync.json
|
|
178
|
+
• tests-runtime\config.copy.json
|
|
179
|
+
• tests-runtime\config.jsonc
|
|
180
|
+
• tests-runtime\config.old.json
|
|
181
|
+
• tests-runtime\config2.json
|
|
182
|
+
• tests-runtime\hello.txt
|
|
183
|
+
• tests-runtime\nested\deep\file.txt
|
|
184
|
+
• tests-runtime\output-file.txt
|
|
185
|
+
Directory structure via diveSync
|
|
186
|
+
• tests-runtime\config-sync.json
|
|
187
|
+
• tests-runtime\config.copy.json
|
|
188
|
+
• tests-runtime\config.jsonc
|
|
189
|
+
• tests-runtime\config.old.json
|
|
190
|
+
• tests-runtime\config2.json
|
|
191
|
+
• tests-runtime\hello.txt
|
|
192
|
+
• tests-runtime\nested\deep\file.txt
|
|
193
|
+
• tests-runtime\output-file.txt
|
|
194
|
+
Removed directory ./tests-runtime
|
|
195
|
+
```
|
|
196
|
+
|
|
132
197
|
## Sync vs Async vs Legacy
|
|
133
198
|
|
|
134
199
|
You choose your flavor:
|
package/bin/impl/copy.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface CopyOptions {
|
|
2
|
-
/**
|
|
2
|
+
/** @deprecated Use `overwrite` instead. This option will be removed in a future. */
|
|
3
3
|
force?: boolean;
|
|
4
|
-
/** Whether to overwrite existing files.
|
|
4
|
+
/** Whether to overwrite existing files. Default: true */
|
|
5
5
|
overwrite?: boolean;
|
|
6
6
|
/** @deprecated Use `overwrite`. */
|
|
7
7
|
clobber?: boolean;
|
package/bin/impl/copy.js
CHANGED
|
@@ -29,7 +29,7 @@ export function copySync(src, dest, options = {}) {
|
|
|
29
29
|
const {
|
|
30
30
|
overwrite = options.clobber ?? true,
|
|
31
31
|
force = true,
|
|
32
|
-
recursive =
|
|
32
|
+
recursive = true,
|
|
33
33
|
dereference = false,
|
|
34
34
|
errorOnExist = false,
|
|
35
35
|
ensureSource = true,
|
|
@@ -124,7 +124,7 @@ export async function copy(src, dest, options = {}) {
|
|
|
124
124
|
const {
|
|
125
125
|
overwrite = options.clobber ?? true,
|
|
126
126
|
force = true,
|
|
127
|
-
recursive =
|
|
127
|
+
recursive = true,
|
|
128
128
|
dereference = false,
|
|
129
129
|
errorOnExist = false,
|
|
130
130
|
ensureSource = true,
|
package/bin/impl/move.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export interface MoveOptions {
|
|
2
|
+
/** @deprecated Use `overwrite` instead. This option will be removed in a future. */
|
|
3
|
+
force?: boolean;
|
|
4
|
+
/** Whether to overwrite existing files. Default: false */
|
|
2
5
|
overwrite?: boolean;
|
|
3
6
|
/** @deprecated Use `overwrite`. */
|
|
4
7
|
clobber?: boolean;
|
package/bin/impl/read-file.d.ts
CHANGED
|
@@ -10,9 +10,9 @@ export interface ReadFileOptions {
|
|
|
10
10
|
*
|
|
11
11
|
* @param path - The path to the file.
|
|
12
12
|
* @param options - Options for reading the file. Can be an encoding string or an object.
|
|
13
|
-
* @returns The contents of the file.
|
|
13
|
+
* @returns The contents of the file as a string.
|
|
14
14
|
*/
|
|
15
|
-
export declare function readFileSync(path: string, options?: BufferEncoding | ReadFileOptions): string
|
|
15
|
+
export declare function readFileSync(path: string, options?: BufferEncoding | ReadFileOptions): string;
|
|
16
16
|
export declare function readFileSync(path: string, encoding: BufferEncoding): string;
|
|
17
17
|
export declare function readFileSync(path: string, options: {
|
|
18
18
|
encoding: BufferEncoding;
|
|
@@ -22,9 +22,9 @@ export declare function readFileSync(path: string, options: {
|
|
|
22
22
|
*
|
|
23
23
|
* @param path - The path to the file.
|
|
24
24
|
* @param options - Options for reading the file. Can be an encoding string or an object.
|
|
25
|
-
* @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.
|
|
26
26
|
*/
|
|
27
|
-
export declare function readFile(path: string, options?: BufferEncoding | ReadFileOptions): Promise<string
|
|
27
|
+
export declare function readFile(path: string, options?: BufferEncoding | ReadFileOptions): Promise<string>;
|
|
28
28
|
export declare function readFile(path: string, encoding: BufferEncoding): Promise<string>;
|
|
29
29
|
export declare function readFile(path: string, options: {
|
|
30
30
|
encoding: BufferEncoding;
|
package/bin/impl/read-file.js
CHANGED
|
@@ -38,13 +38,13 @@ export function readFileSync(path, options) {
|
|
|
38
38
|
if (buffer instanceof Promise) {
|
|
39
39
|
throw new Error("Bun's arrayBuffer() returned a Promise in sync context");
|
|
40
40
|
}
|
|
41
|
-
return Buffer.from(buffer);
|
|
41
|
+
return Buffer.from(buffer).toString(encoding || "utf8");
|
|
42
42
|
} catch (_error) {
|
|
43
43
|
const text = file.text();
|
|
44
44
|
if (text instanceof Promise) {
|
|
45
45
|
throw new Error("Bun's text() returned a Promise in sync context");
|
|
46
46
|
}
|
|
47
|
-
return
|
|
47
|
+
return text;
|
|
48
48
|
}
|
|
49
49
|
} catch (error) {
|
|
50
50
|
}
|
|
@@ -52,7 +52,7 @@ export function readFileSync(path, options) {
|
|
|
52
52
|
if (encoding) {
|
|
53
53
|
return nodeReadFileSync(path, { encoding, flag });
|
|
54
54
|
}
|
|
55
|
-
return nodeReadFileSync(path, { encoding:
|
|
55
|
+
return nodeReadFileSync(path, { encoding: "utf8", flag });
|
|
56
56
|
}
|
|
57
57
|
export async function readFile(path, options) {
|
|
58
58
|
let encoding;
|
|
@@ -77,10 +77,10 @@ export async function readFile(path, options) {
|
|
|
77
77
|
const result = await file.text();
|
|
78
78
|
if (isJson) {
|
|
79
79
|
try {
|
|
80
|
-
return JSON.parse(result, reviver);
|
|
80
|
+
return JSON.stringify(JSON.parse(result, reviver));
|
|
81
81
|
} catch (_parseError) {
|
|
82
82
|
const repaired = jsonrepair(result);
|
|
83
|
-
return JSON.parse(repaired, reviver);
|
|
83
|
+
return JSON.stringify(JSON.parse(repaired, reviver));
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
return result;
|
|
@@ -89,10 +89,10 @@ export async function readFile(path, options) {
|
|
|
89
89
|
const text = Buffer.from(buffer).toString(encoding);
|
|
90
90
|
if (isJson) {
|
|
91
91
|
try {
|
|
92
|
-
return JSON.parse(text, reviver);
|
|
92
|
+
return JSON.stringify(JSON.parse(text, reviver));
|
|
93
93
|
} catch (_parseError) {
|
|
94
94
|
const repaired = jsonrepair(text);
|
|
95
|
-
return JSON.parse(repaired, reviver);
|
|
95
|
+
return JSON.stringify(JSON.parse(repaired, reviver));
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
return text;
|
|
@@ -100,27 +100,27 @@ export async function readFile(path, options) {
|
|
|
100
100
|
}
|
|
101
101
|
try {
|
|
102
102
|
const buffer = await file.arrayBuffer();
|
|
103
|
+
const text = Buffer.from(buffer).toString(encoding || "utf8");
|
|
103
104
|
if (isJson) {
|
|
104
|
-
const text = Buffer.from(buffer).toString();
|
|
105
105
|
try {
|
|
106
|
-
return JSON.parse(text, reviver);
|
|
106
|
+
return JSON.stringify(JSON.parse(text, reviver));
|
|
107
107
|
} catch (_parseError) {
|
|
108
108
|
const repaired = jsonrepair(text);
|
|
109
|
-
return JSON.parse(repaired, reviver);
|
|
109
|
+
return JSON.stringify(JSON.parse(repaired, reviver));
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
return
|
|
112
|
+
return text;
|
|
113
113
|
} catch (_error) {
|
|
114
114
|
const text = await file.text();
|
|
115
115
|
if (isJson) {
|
|
116
116
|
try {
|
|
117
|
-
return JSON.parse(text, reviver);
|
|
117
|
+
return JSON.stringify(JSON.parse(text, reviver));
|
|
118
118
|
} catch (_parseError) {
|
|
119
119
|
const repaired = jsonrepair(text);
|
|
120
|
-
return JSON.parse(repaired, reviver);
|
|
120
|
+
return JSON.stringify(JSON.parse(repaired, reviver));
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
return
|
|
123
|
+
return text;
|
|
124
124
|
}
|
|
125
125
|
} catch (error) {
|
|
126
126
|
}
|
|
@@ -139,10 +139,10 @@ export async function readFile(path, options) {
|
|
|
139
139
|
const text = chunks.join("");
|
|
140
140
|
if (isJson) {
|
|
141
141
|
try {
|
|
142
|
-
return JSON.parse(text, reviver);
|
|
142
|
+
return JSON.stringify(JSON.parse(text, reviver));
|
|
143
143
|
} catch (_parseError) {
|
|
144
144
|
const repaired = jsonrepair(text);
|
|
145
|
-
return JSON.parse(repaired, reviver);
|
|
145
|
+
return JSON.stringify(JSON.parse(repaired, reviver));
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
return text;
|
|
@@ -153,13 +153,13 @@ export async function readFile(path, options) {
|
|
|
153
153
|
const text = await nodeReadFileAsync(path, { encoding, flag });
|
|
154
154
|
if (isJson) {
|
|
155
155
|
try {
|
|
156
|
-
return JSON.parse(text, reviver);
|
|
156
|
+
return JSON.stringify(JSON.parse(text, reviver));
|
|
157
157
|
} catch (_parseError) {
|
|
158
158
|
const repaired = jsonrepair(text);
|
|
159
|
-
return JSON.parse(repaired, reviver);
|
|
159
|
+
return JSON.stringify(JSON.parse(repaired, reviver));
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
return text;
|
|
163
163
|
}
|
|
164
|
-
return nodeReadFileAsync(path, { encoding:
|
|
164
|
+
return await nodeReadFileAsync(path, { encoding: "utf8", flag });
|
|
165
165
|
}
|
package/bin/impl/write-file.d.ts
CHANGED
|
@@ -15,16 +15,16 @@ type WriteTarget = PathLike | number | URL | WriteStream;
|
|
|
15
15
|
* Ensures the directory exists before writing.
|
|
16
16
|
*
|
|
17
17
|
* @param file - Path to the file, file descriptor, URL, or special streams (stdout/stderr).
|
|
18
|
-
* @param data - The data to write.
|
|
18
|
+
* @param data - The data to write. Will be converted to string if not already a string.
|
|
19
19
|
* @param options - Options for writing the file. Can be an encoding string or an object.
|
|
20
20
|
*/
|
|
21
|
-
export declare function writeFileSync(file: WriteTarget, data: string | NodeJS.ArrayBufferView | Blob | Response, options?: WriteFileOptions): void;
|
|
21
|
+
export declare function writeFileSync(file: WriteTarget, data: string | NodeJS.ArrayBufferView | Blob | Response | unknown, options?: WriteFileOptions): void;
|
|
22
22
|
/**
|
|
23
23
|
* Asynchronously writes data to a file, replacing the file if it already exists.
|
|
24
24
|
* Ensures the directory exists before writing.
|
|
25
25
|
*
|
|
26
26
|
* @param file - Path to the file, file descriptor, URL, or special streams (stdout/stderr).
|
|
27
|
-
* @param data - The data to write.
|
|
27
|
+
* @param data - The data to write. Will be converted to string if not already a string.
|
|
28
28
|
* @param options - Options for writing the file. Can be an encoding string or an object.
|
|
29
29
|
*/
|
|
30
30
|
export declare function writeFile(file: WriteTarget, data: string | NodeJS.ArrayBufferView | Blob | Response | unknown, options?: WriteFileOptions): Promise<void>;
|
package/bin/impl/write-file.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { writeFileSync as nodeWriteFileSync, createWriteStream } from "node:fs";
|
|
2
|
-
import { mkdir, writeFile as nodeWriteFileAsync
|
|
2
|
+
import { mkdir, writeFile as nodeWriteFileAsync } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { Transform } from "node:stream";
|
|
5
5
|
import { pipeline } from "node:stream/promises";
|
|
@@ -17,45 +17,53 @@ function isPathLike(target) {
|
|
|
17
17
|
return !isStdStream(target) && !isFileDescriptor(target) && !(target instanceof URL);
|
|
18
18
|
}
|
|
19
19
|
export function writeFileSync(file, data, options) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
let isJson = false;
|
|
21
|
+
let replacer;
|
|
22
|
+
let spaces;
|
|
23
|
+
let encoding;
|
|
24
|
+
let mode;
|
|
25
|
+
let flag;
|
|
26
|
+
if (options) {
|
|
27
|
+
isJson = options.isJson ?? isJson;
|
|
28
|
+
replacer = options.replacer;
|
|
29
|
+
spaces = options.spaces;
|
|
30
|
+
encoding = options.encoding;
|
|
31
|
+
mode = options.mode ? Number(options.mode) : void 0;
|
|
32
|
+
flag = options.flag;
|
|
33
|
+
}
|
|
34
|
+
let stringData;
|
|
35
|
+
if (typeof data === "string") {
|
|
36
|
+
stringData = data;
|
|
37
|
+
} else if (data instanceof Uint8Array) {
|
|
38
|
+
stringData = Buffer.from(data).toString(encoding || "utf8");
|
|
39
|
+
} else if (data instanceof Blob || data instanceof Response) {
|
|
40
|
+
throw new Error("Blob and Response are not supported in sync context");
|
|
41
|
+
} else if (data instanceof ArrayBuffer) {
|
|
42
|
+
stringData = Buffer.from(new Uint8Array(data)).toString(encoding || "utf8");
|
|
43
|
+
} else if (ArrayBuffer.isView(data)) {
|
|
44
|
+
stringData = Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString(encoding || "utf8");
|
|
45
|
+
} else if (isJson) {
|
|
46
|
+
try {
|
|
47
|
+
stringData = JSON.stringify(data, replacer, spaces);
|
|
48
|
+
if (stringData === void 0) {
|
|
49
|
+
throw new Error("Failed to stringify JSON object");
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
throw new Error(`Failed to stringify JSON data: ${err}`);
|
|
33
53
|
}
|
|
54
|
+
} else {
|
|
55
|
+
stringData = String(data);
|
|
56
|
+
}
|
|
57
|
+
if (isStdStream(file)) {
|
|
58
|
+
file.write(stringData);
|
|
34
59
|
return;
|
|
35
60
|
}
|
|
36
61
|
if (isFileDescriptor(file)) {
|
|
37
62
|
if (isBun) {
|
|
38
|
-
|
|
39
|
-
if (typeof data === "string") {
|
|
40
|
-
writeData = data;
|
|
41
|
-
} else if (data instanceof Uint8Array) {
|
|
42
|
-
writeData = data;
|
|
43
|
-
} else if (data instanceof Blob || data instanceof Response) {
|
|
44
|
-
throw new Error("Blob and Response are not supported in sync context with Bun");
|
|
45
|
-
} else if (data instanceof ArrayBuffer) {
|
|
46
|
-
writeData = new Uint8Array(data);
|
|
47
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
48
|
-
writeData = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
49
|
-
} else {
|
|
50
|
-
throw new Error("Unsupported data type for Bun file descriptor writing");
|
|
51
|
-
}
|
|
52
|
-
Bun.write(Bun.file(file), writeData);
|
|
63
|
+
Bun.write(Bun.file(file), stringData);
|
|
53
64
|
return;
|
|
54
65
|
}
|
|
55
|
-
|
|
56
|
-
throw new Error("Blob and Response are not supported for file descriptors in sync context");
|
|
57
|
-
}
|
|
58
|
-
nodeWriteFileSync(file, data, options);
|
|
66
|
+
nodeWriteFileSync(file, stringData, { encoding: encoding || "utf8", mode, flag });
|
|
59
67
|
return;
|
|
60
68
|
}
|
|
61
69
|
if (file instanceof URL) {
|
|
@@ -72,38 +80,12 @@ export function writeFileSync(file, data, options) {
|
|
|
72
80
|
if (isBun) {
|
|
73
81
|
try {
|
|
74
82
|
const filePath = file.toString();
|
|
75
|
-
|
|
76
|
-
if (typeof data === "string") {
|
|
77
|
-
writeData = data;
|
|
78
|
-
} else if (data instanceof Uint8Array) {
|
|
79
|
-
writeData = data;
|
|
80
|
-
} else if (data instanceof Blob || data instanceof Response) {
|
|
81
|
-
throw new Error("Blob and Response are not supported in sync context with Bun");
|
|
82
|
-
} else if (data instanceof ArrayBuffer) {
|
|
83
|
-
writeData = new Uint8Array(data);
|
|
84
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
85
|
-
writeData = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
86
|
-
} else {
|
|
87
|
-
throw new Error("Unsupported data type for Bun file writing");
|
|
88
|
-
}
|
|
89
|
-
Bun.write(filePath, writeData);
|
|
83
|
+
Bun.write(filePath, stringData);
|
|
90
84
|
return;
|
|
91
85
|
} catch (_error) {
|
|
92
86
|
}
|
|
93
87
|
}
|
|
94
|
-
|
|
95
|
-
if (data instanceof Blob || data instanceof Response) {
|
|
96
|
-
throw new Error("Blob and Response are not supported in sync context");
|
|
97
|
-
} else if (typeof data === "string") {
|
|
98
|
-
nodeData = data;
|
|
99
|
-
} else if (data instanceof ArrayBuffer) {
|
|
100
|
-
nodeData = Buffer.from(new Uint8Array(data));
|
|
101
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
102
|
-
nodeData = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
103
|
-
} else {
|
|
104
|
-
throw new Error("Unsupported data type for Node.js file writing");
|
|
105
|
-
}
|
|
106
|
-
nodeWriteFileSync(file, nodeData, options);
|
|
88
|
+
nodeWriteFileSync(file, stringData, { encoding: encoding || "utf8", mode, flag });
|
|
107
89
|
}
|
|
108
90
|
export async function writeFile(file, data, options) {
|
|
109
91
|
let isJson = false;
|
|
@@ -122,56 +104,42 @@ export async function writeFile(file, data, options) {
|
|
|
122
104
|
mode = options.mode ? Number(options.mode) : void 0;
|
|
123
105
|
flag = options.flag;
|
|
124
106
|
}
|
|
125
|
-
|
|
107
|
+
let stringData;
|
|
108
|
+
if (typeof data === "string") {
|
|
109
|
+
stringData = data;
|
|
110
|
+
} else if (data instanceof Uint8Array) {
|
|
111
|
+
stringData = Buffer.from(data).toString(encoding || "utf8");
|
|
112
|
+
} else if (data instanceof Blob) {
|
|
113
|
+
stringData = await data.text();
|
|
114
|
+
} else if (data instanceof Response) {
|
|
115
|
+
stringData = await data.text();
|
|
116
|
+
} else if (data instanceof ArrayBuffer) {
|
|
117
|
+
stringData = Buffer.from(new Uint8Array(data)).toString(encoding || "utf8");
|
|
118
|
+
} else if (ArrayBuffer.isView(data)) {
|
|
119
|
+
stringData = Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString(encoding || "utf8");
|
|
120
|
+
} else if (isJson) {
|
|
126
121
|
try {
|
|
127
|
-
|
|
128
|
-
if (
|
|
122
|
+
stringData = JSON.stringify(data, replacer, spaces);
|
|
123
|
+
if (stringData === void 0) {
|
|
129
124
|
throw new Error("Failed to stringify JSON object");
|
|
130
125
|
}
|
|
131
|
-
data = jsonString;
|
|
132
126
|
} catch (err) {
|
|
133
127
|
throw new Error(`Failed to stringify JSON data: ${err}`);
|
|
134
128
|
}
|
|
129
|
+
} else {
|
|
130
|
+
stringData = String(data);
|
|
135
131
|
}
|
|
136
132
|
if (isStdStream(file)) {
|
|
137
|
-
|
|
138
|
-
file.write(data);
|
|
139
|
-
} else if (data instanceof Uint8Array) {
|
|
140
|
-
file.write(data);
|
|
141
|
-
} else if (data instanceof Blob || data instanceof Response) {
|
|
142
|
-
throw new Error("Blob and Response are not supported for stdout/stderr in sync context");
|
|
143
|
-
} else if (data instanceof ArrayBuffer) {
|
|
144
|
-
file.write(Buffer.from(new Uint8Array(data)));
|
|
145
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
146
|
-
file.write(Buffer.from(data.buffer, data.byteOffset, data.byteLength));
|
|
147
|
-
} else {
|
|
148
|
-
throw new Error("Unsupported data type for stream writing");
|
|
149
|
-
}
|
|
133
|
+
file.write(stringData);
|
|
150
134
|
return;
|
|
151
135
|
}
|
|
152
136
|
if (isFileDescriptor(file)) {
|
|
153
137
|
if (isBun) {
|
|
154
|
-
|
|
155
|
-
if (typeof data === "string") {
|
|
156
|
-
writeData = data;
|
|
157
|
-
} else if (data instanceof Uint8Array) {
|
|
158
|
-
writeData = data;
|
|
159
|
-
} else if (data instanceof Blob || data instanceof Response) {
|
|
160
|
-
throw new Error("Blob and Response are not supported in sync context with Bun");
|
|
161
|
-
} else if (data instanceof ArrayBuffer) {
|
|
162
|
-
writeData = new Uint8Array(data);
|
|
163
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
164
|
-
writeData = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
165
|
-
} else {
|
|
166
|
-
throw new Error("Unsupported data type for Bun file descriptor writing");
|
|
167
|
-
}
|
|
168
|
-
Bun.write(Bun.file(file), writeData);
|
|
138
|
+
await Bun.write(Bun.file(file), stringData);
|
|
169
139
|
return;
|
|
170
140
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
return nodeWriteFileSync(file, data, options);
|
|
141
|
+
await nodeWriteFileAsync(file, stringData, { encoding: encoding || "utf8", mode, flag });
|
|
142
|
+
return;
|
|
175
143
|
}
|
|
176
144
|
if (file instanceof URL) {
|
|
177
145
|
if (file.protocol !== "file:") {
|
|
@@ -183,30 +151,16 @@ export async function writeFile(file, data, options) {
|
|
|
183
151
|
throw new Error("Invalid file target");
|
|
184
152
|
}
|
|
185
153
|
const dir = path.dirname(file.toString());
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
} catch (_error) {
|
|
189
|
-
if (_error.code === "ENOENT") {
|
|
190
|
-
await mkdir(dir, { recursive: true });
|
|
191
|
-
} else {
|
|
192
|
-
throw _error;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
if (useStreaming && typeof data === "string") {
|
|
154
|
+
await mkdir(dir, { recursive: true });
|
|
155
|
+
if (useStreaming) {
|
|
196
156
|
try {
|
|
197
|
-
const writeStream = createWriteStream(file
|
|
198
|
-
encoding,
|
|
199
|
-
mode,
|
|
200
|
-
flags: flag
|
|
201
|
-
});
|
|
157
|
+
const writeStream = createWriteStream(file, { encoding: encoding || "utf8", mode, flags: flag });
|
|
202
158
|
const transform = new Transform({
|
|
203
159
|
transform(chunk, _encoding, callback) {
|
|
204
160
|
callback(null, chunk);
|
|
205
161
|
}
|
|
206
162
|
});
|
|
207
|
-
transform
|
|
208
|
-
transform.end();
|
|
209
|
-
await pipeline(transform, writeStream);
|
|
163
|
+
await pipeline(stringData, transform, writeStream);
|
|
210
164
|
return;
|
|
211
165
|
} catch (streamError) {
|
|
212
166
|
}
|
|
@@ -214,44 +168,10 @@ export async function writeFile(file, data, options) {
|
|
|
214
168
|
if (isBun) {
|
|
215
169
|
try {
|
|
216
170
|
const filePath = file.toString();
|
|
217
|
-
|
|
218
|
-
if (typeof data === "string") {
|
|
219
|
-
writeData = data;
|
|
220
|
-
} else if (data instanceof Uint8Array) {
|
|
221
|
-
writeData = data;
|
|
222
|
-
} else if (data instanceof Blob) {
|
|
223
|
-
const buffer = await data.arrayBuffer();
|
|
224
|
-
writeData = new Uint8Array(buffer);
|
|
225
|
-
} else if (data instanceof Response) {
|
|
226
|
-
const buffer = await data.arrayBuffer();
|
|
227
|
-
writeData = new Uint8Array(buffer);
|
|
228
|
-
} else if (data instanceof ArrayBuffer) {
|
|
229
|
-
writeData = new Uint8Array(data);
|
|
230
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
231
|
-
writeData = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
232
|
-
} else {
|
|
233
|
-
throw new Error("Unsupported data type for Bun file writing");
|
|
234
|
-
}
|
|
235
|
-
await Bun.write(filePath, writeData);
|
|
171
|
+
await Bun.write(filePath, stringData);
|
|
236
172
|
return;
|
|
237
173
|
} catch (_error) {
|
|
238
174
|
}
|
|
239
175
|
}
|
|
240
|
-
|
|
241
|
-
if (data instanceof Blob) {
|
|
242
|
-
const buffer = await data.arrayBuffer();
|
|
243
|
-
nodeData = Buffer.from(buffer);
|
|
244
|
-
} else if (data instanceof Response) {
|
|
245
|
-
const buffer = await data.arrayBuffer();
|
|
246
|
-
nodeData = Buffer.from(buffer);
|
|
247
|
-
} else if (typeof data === "string") {
|
|
248
|
-
nodeData = data;
|
|
249
|
-
} else if (data instanceof ArrayBuffer) {
|
|
250
|
-
nodeData = Buffer.from(new Uint8Array(data));
|
|
251
|
-
} else if (ArrayBuffer.isView(data)) {
|
|
252
|
-
nodeData = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
253
|
-
} else {
|
|
254
|
-
throw new Error("Unsupported data type for Node.js file writing");
|
|
255
|
-
}
|
|
256
|
-
await nodeWriteFileAsync(file, nodeData, options);
|
|
176
|
+
await nodeWriteFileAsync(file, stringData, { encoding: encoding || "utf8", mode, flag });
|
|
257
177
|
}
|