@jisan901/fs-browser 1.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.
- package/LICENSE +21 -0
- package/README.md +620 -0
- package/bin/withfs.js +276 -0
- package/package.json +67 -0
- package/plugin/fs-handlers.js +419 -0
- package/plugin/vite.js +67 -0
- package/src/index.d.ts +288 -0
- package/src/index.js +402 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 claude:sonnet4.5
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
# fs-browser
|
|
2
|
+
|
|
3
|
+
Browser-compatible filesystem API with Vite plugin support. Write Node.js-style fs code that works in the browser!
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 Node.js-like fs API for the browser
|
|
8
|
+
- 🔌 Vite plugin for seamless integration
|
|
9
|
+
- 📦 Supports all major file operations
|
|
10
|
+
- 💪 Full TypeScript support
|
|
11
|
+
- 🎯 Handles text, JSON, binary, and Blob data
|
|
12
|
+
- 🔒 Safe path resolution with base directory protection
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install fs-browser
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Development with Vite
|
|
23
|
+
|
|
24
|
+
**1. Setup Vite Plugin**
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
// vite.config.js
|
|
28
|
+
import { defineConfig } from 'vite';
|
|
29
|
+
import fsPlugin from 'fs-browser/plugin';
|
|
30
|
+
|
|
31
|
+
export default defineConfig({
|
|
32
|
+
plugins: [
|
|
33
|
+
fsPlugin({
|
|
34
|
+
baseDir: './data', // Base directory for file operations
|
|
35
|
+
apiPrefix: '/api/fs' // API route prefix
|
|
36
|
+
})
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**2. Use in Browser Code**
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
import { readFile, writeFile, mkdir } from 'fs-browser';
|
|
45
|
+
|
|
46
|
+
// Write a file
|
|
47
|
+
await writeFile('hello.txt', 'Hello World!');
|
|
48
|
+
|
|
49
|
+
// Read a file
|
|
50
|
+
const content = await readFile('hello.txt');
|
|
51
|
+
console.log(content); // "Hello World!"
|
|
52
|
+
|
|
53
|
+
// Create directory
|
|
54
|
+
await mkdir('myFolder', { recursive: true });
|
|
55
|
+
|
|
56
|
+
// Write JSON
|
|
57
|
+
await writeFile('data.json', { name: 'John', age: 30 });
|
|
58
|
+
|
|
59
|
+
// Write binary data
|
|
60
|
+
const blob = new Blob([imageData], { type: 'image/png' });
|
|
61
|
+
await writeFile('image.png', blob);
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
fs.configure({
|
|
66
|
+
apiBase: 'http://localhost:2300/api/fs'
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
### Production - Serve Built Projects
|
|
75
|
+
|
|
76
|
+
After building your project, use the `withfs` CLI to serve it with fs API support:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Build your project
|
|
80
|
+
npm run build
|
|
81
|
+
|
|
82
|
+
# Serve with fs API support
|
|
83
|
+
withfs ./dist --host
|
|
84
|
+
|
|
85
|
+
# Or with custom options
|
|
86
|
+
withfs ./dist --host --port 8080 --open
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**CLI Options:**
|
|
90
|
+
```bash
|
|
91
|
+
withfs [projectDir] [options]
|
|
92
|
+
|
|
93
|
+
Options:
|
|
94
|
+
--host, -h <host> Host (default: localhost, use --host for 0.0.0.0)
|
|
95
|
+
--port, -p <port> Port (default: 3000)
|
|
96
|
+
--base-dir, -b <dir> Base dir for fs operations (default: ./data)
|
|
97
|
+
--api-prefix, -a <prefix> API route prefix (default: /api/fs)
|
|
98
|
+
--open, -o Open browser automatically
|
|
99
|
+
--justfs Only run fs API (no static file serving)
|
|
100
|
+
--help Show help message
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Example Workflow:**
|
|
104
|
+
```bash
|
|
105
|
+
# Development
|
|
106
|
+
npm run dev
|
|
107
|
+
|
|
108
|
+
# Build
|
|
109
|
+
npm run build
|
|
110
|
+
|
|
111
|
+
# Production serve with fs API
|
|
112
|
+
withfs ./dist --host --open
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## Development with Other Frameworks
|
|
117
|
+
|
|
118
|
+
While `fs-browser` includes a Vite plugin, you can use it with any framework or development setup by running the `withfs` server separately.
|
|
119
|
+
|
|
120
|
+
### React (Create React App, Next.js)
|
|
121
|
+
|
|
122
|
+
**Option 1: Proxy (Recommended for CRA)**
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
// package.json (Create React App)
|
|
126
|
+
{
|
|
127
|
+
"proxy": "http://localhost:5001"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Terminal 1: fs API server
|
|
133
|
+
withfs --justfs --port 5001
|
|
134
|
+
|
|
135
|
+
# Terminal 2: React dev server
|
|
136
|
+
npm start
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
// App.js
|
|
141
|
+
import { readFile, writeFile } from 'fs-browser';
|
|
142
|
+
|
|
143
|
+
function App() {
|
|
144
|
+
const handleSave = async () => {
|
|
145
|
+
await writeFile('data.txt', 'Hello from React!');
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return <button onClick={handleSave}>Save File</button>;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Option 2: Configure API Base (Next.js, App Router)**
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
// lib/fs.js
|
|
156
|
+
import fs from 'fs-browser';
|
|
157
|
+
|
|
158
|
+
export default fs.configure({
|
|
159
|
+
apiBase: 'http://localhost:5001/api/fs'
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
// app/page.js
|
|
165
|
+
import fs from '@/lib/fs';
|
|
166
|
+
|
|
167
|
+
export default function Page() {
|
|
168
|
+
const saveFile = async () => {
|
|
169
|
+
await fs.writeFile('notes.txt', 'Hello Next.js!');
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
return <button onClick={saveFile}>Save</button>;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Vue (Vue CLI, Nuxt)
|
|
177
|
+
|
|
178
|
+
**Vue CLI with Proxy**
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
// vue.config.js
|
|
182
|
+
module.exports = {
|
|
183
|
+
devServer: {
|
|
184
|
+
proxy: {
|
|
185
|
+
'/api/fs': {
|
|
186
|
+
target: 'http://localhost:5001',
|
|
187
|
+
changeOrigin: true
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Terminal 1: fs API server
|
|
196
|
+
withfs --justfs --port 5001
|
|
197
|
+
|
|
198
|
+
# Terminal 2: Vue dev server
|
|
199
|
+
npm run serve
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```vue
|
|
203
|
+
<!-- App.vue -->
|
|
204
|
+
<script setup>
|
|
205
|
+
import { readFile, writeFile } from 'fs-browser';
|
|
206
|
+
|
|
207
|
+
const saveFile = async () => {
|
|
208
|
+
await writeFile('vue-data.json', { framework: 'Vue' });
|
|
209
|
+
};
|
|
210
|
+
</script>
|
|
211
|
+
|
|
212
|
+
<template>
|
|
213
|
+
<button @click="saveFile">Save File</button>
|
|
214
|
+
</template>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Nuxt 3 with Configuration**
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
// composables/useFs.js
|
|
221
|
+
import fs from 'fs-browser';
|
|
222
|
+
|
|
223
|
+
export const useFs = () => {
|
|
224
|
+
return fs.configure({
|
|
225
|
+
apiBase: 'http://localhost:5001/api/fs'
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```vue
|
|
231
|
+
<!-- pages/index.vue -->
|
|
232
|
+
<script setup>
|
|
233
|
+
const fs = useFs();
|
|
234
|
+
|
|
235
|
+
const saveData = async () => {
|
|
236
|
+
await fs.writeFile('nuxt-file.txt', 'Hello Nuxt!');
|
|
237
|
+
};
|
|
238
|
+
</script>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Angular
|
|
242
|
+
|
|
243
|
+
**Proxy Configuration**
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
// proxy.conf.json
|
|
247
|
+
{
|
|
248
|
+
"/api/fs": {
|
|
249
|
+
"target": "http://localhost:5001",
|
|
250
|
+
"secure": false,
|
|
251
|
+
"changeOrigin": true
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
// angular.json
|
|
258
|
+
{
|
|
259
|
+
"serve": {
|
|
260
|
+
"options": {
|
|
261
|
+
"proxyConfig": "proxy.conf.json"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Terminal 1: fs API server
|
|
269
|
+
withfs --justfs --port 5001
|
|
270
|
+
|
|
271
|
+
# Terminal 2: Angular dev server
|
|
272
|
+
ng serve
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// app.component.ts
|
|
277
|
+
import { readFile, writeFile } from 'fs-browser';
|
|
278
|
+
|
|
279
|
+
export class AppComponent {
|
|
280
|
+
async saveFile() {
|
|
281
|
+
await writeFile('angular-data.json', { framework: 'Angular' });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Svelte (SvelteKit)
|
|
287
|
+
|
|
288
|
+
**SvelteKit with Proxy**
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
// vite.config.js
|
|
292
|
+
import { sveltekit } from '@sveltejs/kit/vite';
|
|
293
|
+
|
|
294
|
+
export default {
|
|
295
|
+
plugins: [sveltekit()],
|
|
296
|
+
server: {
|
|
297
|
+
proxy: {
|
|
298
|
+
'/api/fs': {
|
|
299
|
+
target: 'http://localhost:5001',
|
|
300
|
+
changeOrigin: true
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Terminal 1: fs API server
|
|
309
|
+
withfs --justfs --port 5001
|
|
310
|
+
|
|
311
|
+
# Terminal 2: SvelteKit dev server
|
|
312
|
+
npm run dev
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
```svelte
|
|
316
|
+
<!-- +page.svelte -->
|
|
317
|
+
<script>
|
|
318
|
+
import { readFile, writeFile } from 'fs-browser';
|
|
319
|
+
|
|
320
|
+
async function saveFile() {
|
|
321
|
+
await writeFile('svelte-data.txt', 'Hello SvelteKit!');
|
|
322
|
+
}
|
|
323
|
+
</script>
|
|
324
|
+
|
|
325
|
+
<button on:click={saveFile}>Save File</button>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Astro
|
|
329
|
+
|
|
330
|
+
**With Astro Dev Server**
|
|
331
|
+
|
|
332
|
+
```javascript
|
|
333
|
+
// astro.config.mjs
|
|
334
|
+
import { defineConfig } from 'astro/config';
|
|
335
|
+
|
|
336
|
+
export default defineConfig({
|
|
337
|
+
vite: {
|
|
338
|
+
server: {
|
|
339
|
+
proxy: {
|
|
340
|
+
'/api/fs': {
|
|
341
|
+
target: 'http://localhost:5001',
|
|
342
|
+
changeOrigin: true
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
# Terminal 1: fs API server
|
|
352
|
+
withfs --justfs --port 5001
|
|
353
|
+
|
|
354
|
+
# Terminal 2: Astro dev server
|
|
355
|
+
npm run dev
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
```astro
|
|
359
|
+
---
|
|
360
|
+
// src/pages/index.astro
|
|
361
|
+
---
|
|
362
|
+
<script>
|
|
363
|
+
import { writeFile } from 'fs-browser';
|
|
364
|
+
|
|
365
|
+
document.querySelector('#save')?.addEventListener('click', async () => {
|
|
366
|
+
await writeFile('astro-data.json', { framework: 'Astro' });
|
|
367
|
+
});
|
|
368
|
+
</script>
|
|
369
|
+
|
|
370
|
+
<button id="save">Save File</button>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Vanilla JavaScript / HTML
|
|
374
|
+
|
|
375
|
+
**Direct Configuration**
|
|
376
|
+
|
|
377
|
+
```html
|
|
378
|
+
<!DOCTYPE html>
|
|
379
|
+
<html>
|
|
380
|
+
<head>
|
|
381
|
+
<title>fs-browser Demo</title>
|
|
382
|
+
</head>
|
|
383
|
+
<body>
|
|
384
|
+
<button id="save">Save File</button>
|
|
385
|
+
<button id="read">Read File</button>
|
|
386
|
+
<pre id="output"></pre>
|
|
387
|
+
|
|
388
|
+
<script type="module">
|
|
389
|
+
import fs from 'https://cdn.jsdelivr.net/npm/fs-browser/src/index.js';
|
|
390
|
+
|
|
391
|
+
// Configure to point to your fs server
|
|
392
|
+
const myFs = fs.configure({
|
|
393
|
+
apiBase: 'http://localhost:5001/api/fs'
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
document.getElementById('save').onclick = async () => {
|
|
397
|
+
await myFs.writeFile('demo.txt', 'Hello from vanilla JS!');
|
|
398
|
+
alert('File saved!');
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
document.getElementById('read').onclick = async () => {
|
|
402
|
+
const content = await myFs.readFile('demo.txt');
|
|
403
|
+
document.getElementById('output').textContent = content;
|
|
404
|
+
};
|
|
405
|
+
</script>
|
|
406
|
+
</body>
|
|
407
|
+
</html>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
# Run the fs API server
|
|
412
|
+
withfs --justfs --port 5001 --host
|
|
413
|
+
|
|
414
|
+
# Open the HTML file in browser
|
|
415
|
+
# Or use any simple HTTP server:
|
|
416
|
+
python -m http.server 8000
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Webpack Dev Server
|
|
420
|
+
|
|
421
|
+
**Proxy Configuration**
|
|
422
|
+
|
|
423
|
+
```javascript
|
|
424
|
+
// webpack.config.js
|
|
425
|
+
module.exports = {
|
|
426
|
+
devServer: {
|
|
427
|
+
proxy: {
|
|
428
|
+
'/api/fs': {
|
|
429
|
+
target: 'http://localhost:5001',
|
|
430
|
+
changeOrigin: true
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Parcel
|
|
438
|
+
|
|
439
|
+
**No configuration needed!** Just run both servers:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
# Terminal 1: fs API server
|
|
443
|
+
withfs --justfs --port 5001
|
|
444
|
+
|
|
445
|
+
# Terminal 2: Parcel dev server
|
|
446
|
+
npx parcel index.html
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
// Configure in your JS
|
|
451
|
+
import { configure } from 'fs-browser';
|
|
452
|
+
|
|
453
|
+
configure({ apiBase: 'http://localhost:5001/api/fs' });
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Production Deployment
|
|
457
|
+
|
|
458
|
+
For production, you have several options:
|
|
459
|
+
|
|
460
|
+
**Option 1: Same Server**
|
|
461
|
+
```bash
|
|
462
|
+
# Build your frontend
|
|
463
|
+
npm run build
|
|
464
|
+
|
|
465
|
+
# Serve everything together
|
|
466
|
+
withfs ./dist --host
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Option 2: Separate Services**
|
|
470
|
+
```bash
|
|
471
|
+
# Frontend on CDN/static host
|
|
472
|
+
# Backend fs API on separate server
|
|
473
|
+
withfs --justfs --host --port 5001
|
|
474
|
+
|
|
475
|
+
# Configure frontend to point to API
|
|
476
|
+
fs.configure({ apiBase: 'https://fs-api.example.com/api/fs' });
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**Option 3: Reverse Proxy (Nginx)**
|
|
480
|
+
```nginx
|
|
481
|
+
location /api/fs {
|
|
482
|
+
proxy_pass http://localhost:5001/api/fs;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
location / {
|
|
486
|
+
root /var/www/html;
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Environment Variables
|
|
491
|
+
|
|
492
|
+
Set API base via environment variables:
|
|
493
|
+
|
|
494
|
+
```javascript
|
|
495
|
+
// config/fs.js
|
|
496
|
+
import fs from 'fs-browser';
|
|
497
|
+
|
|
498
|
+
const API_BASE = import.meta.env.VITE_FS_API_BASE ||
|
|
499
|
+
process.env.REACT_APP_FS_API_BASE ||
|
|
500
|
+
'/api/fs';
|
|
501
|
+
|
|
502
|
+
export default fs.configure({ apiBase: API_BASE });
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
# .env
|
|
507
|
+
VITE_FS_API_BASE=http://localhost:5001/api/fs
|
|
508
|
+
# or
|
|
509
|
+
REACT_APP_FS_API_BASE=http://localhost:5001/api/fs
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Docker Setup
|
|
513
|
+
|
|
514
|
+
```dockerfile
|
|
515
|
+
# Dockerfile
|
|
516
|
+
FROM node:18
|
|
517
|
+
|
|
518
|
+
WORKDIR /app
|
|
519
|
+
|
|
520
|
+
# Install fs-browser globally
|
|
521
|
+
RUN npm install -g fs-browser
|
|
522
|
+
|
|
523
|
+
# Copy your built frontend
|
|
524
|
+
COPY ./dist ./dist
|
|
525
|
+
|
|
526
|
+
# Expose port
|
|
527
|
+
EXPOSE 3000
|
|
528
|
+
|
|
529
|
+
# Run withfs
|
|
530
|
+
CMD ["withfs", "./dist", "--host", "0.0.0.0", "--port", "3000"]
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
```yaml
|
|
534
|
+
# docker-compose.yml
|
|
535
|
+
version: '3'
|
|
536
|
+
services:
|
|
537
|
+
app:
|
|
538
|
+
build: .
|
|
539
|
+
ports:
|
|
540
|
+
- "3000:3000"
|
|
541
|
+
volumes:
|
|
542
|
+
- ./data:/app/data
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Summary
|
|
546
|
+
|
|
547
|
+
- **Development**: Run `withfs --justfs` on a separate port and use proxy or configure API base
|
|
548
|
+
- **Production**: Use `withfs ./dist --host` to serve everything together
|
|
549
|
+
- **Microservices**: Run `withfs --justfs` as a dedicated fs API service
|
|
550
|
+
- **Any Framework**: Works with any setup that can make HTTP requests!
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
## API Reference
|
|
554
|
+
|
|
555
|
+
### File Reading
|
|
556
|
+
|
|
557
|
+
- `readFile(path, options?)` - Read file contents
|
|
558
|
+
- `readdir(path, options?)` - List directory contents
|
|
559
|
+
- `stat(path)` - Get file/directory stats
|
|
560
|
+
- `lstat(path)` - Get stats without following symlinks
|
|
561
|
+
- `realpath(path)` - Get canonical path
|
|
562
|
+
- `readlink(path)` - Read symbolic link
|
|
563
|
+
- `exists(path)` - Check if file exists
|
|
564
|
+
|
|
565
|
+
### File Writing
|
|
566
|
+
|
|
567
|
+
- `writeFile(path, data, options?)` - Write data to file
|
|
568
|
+
- `appendFile(path, data, options?)` - Append data to file
|
|
569
|
+
- `copyFile(src, dest, flags?)` - Copy file
|
|
570
|
+
|
|
571
|
+
### Directory Operations
|
|
572
|
+
|
|
573
|
+
- `mkdir(path, options?)` - Create directory
|
|
574
|
+
- `rmdir(path, options?)` - Remove directory
|
|
575
|
+
- `rm(path, options?)` - Remove file or directory
|
|
576
|
+
|
|
577
|
+
### File Manipulation
|
|
578
|
+
|
|
579
|
+
- `rename(oldPath, newPath)` - Rename or move file/directory
|
|
580
|
+
- `unlink(path)` - Delete file
|
|
581
|
+
|
|
582
|
+
## TypeScript Support
|
|
583
|
+
|
|
584
|
+
Full TypeScript definitions included:
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
import { readFile, writeFile, Stats, Dirent } from 'fs-browser';
|
|
588
|
+
|
|
589
|
+
const content: string = await readFile('test.txt', 'utf8');
|
|
590
|
+
const stats: Stats = await stat('test.txt');
|
|
591
|
+
const files: Dirent[] = await readdir('.', { withFileTypes: true });
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
## Plugin Options
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
interface PluginOptions {
|
|
598
|
+
baseDir?: string; // Base directory for file operations (default: './data')
|
|
599
|
+
apiPrefix?: string; // API route prefix (default: '/api/fs')
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
## Data Types Supported
|
|
604
|
+
|
|
605
|
+
- **Text**: Plain text strings
|
|
606
|
+
- **JSON**: JavaScript objects (auto-serialized)
|
|
607
|
+
- **Binary**: Buffers, ArrayBuffers, TypedArrays
|
|
608
|
+
- **Blob**: Browser Blob objects
|
|
609
|
+
|
|
610
|
+
## Security
|
|
611
|
+
|
|
612
|
+
All file operations are restricted to the configured base directory. Attempts to access files outside this directory will throw an error.
|
|
613
|
+
|
|
614
|
+
## License
|
|
615
|
+
|
|
616
|
+
MIT © claude:sonnet4.5
|
|
617
|
+
|
|
618
|
+
## Contributing
|
|
619
|
+
|
|
620
|
+
Contributions welcome! Please open an issue or PR.
|