@fullstackunicorn/filesystem 1.0.1 → 1.0.4

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/index.dep.js ADDED
@@ -0,0 +1,4 @@
1
+ // NODE BUILT IN
2
+ export * as fsSync from 'fs'
3
+ export * as fsAsync from 'fs/promises'
4
+ export { constants } from 'fs'
package/index.js CHANGED
@@ -1,65 +1,2 @@
1
- import * as fsSync from 'fs'
2
- import * as fsAsync from 'fs/promises'
3
- import { constants } from 'fs'
4
-
5
- export const fss = {
6
- exists: (...args) => fsSync.existsSync(...args),
7
- readFile: (...args) => fss.exists(...args) ? fsSync.readFileSync(...args) : null,
8
- readText: (path) => fss.exists(path) ? fsSync.readFileSync(path, 'utf8') : null,
9
- readJSON: (...args) => {
10
- try { return fss.exists(...args) ? JSON.parse(fsSync.readFileSync(...args), 'utf8') : {} }
11
- catch { return {} }
12
- },
13
- writeJSON: (path, json) => fsSync.writeFileSync(path, JSON.stringify(json, null, 4)),
14
- readDir: (...args) => fss.exists(...args) ? fsSync.readdirSync(...args) : [],
15
- readDirVisible: (path) => (
16
- fss.readDir(path, { withFileTypes: true }) || []
17
- ).filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name),
18
- isDir: (path) => {
19
- try { return fsSync.statSync(path).isDirectory() }
20
- catch { return false }
21
- },
22
- ensureDir: (path) => { if (!fss.exists(path)) fsSync.mkdirSync(path, { recursive: true }) },
23
- writeText: (path, text) => fsSync.writeFileSync(path, text),
24
- listFiles: (path, ext = null) => fss.readDir(path).filter(f => !ext || f.endsWith(ext)),
25
- safeUnlink: (path) => { if (fss.exists(path)) fsSync.unlinkSync(path) },
26
- safeRemove: (path) => { if (fss.exists(path)) fsSync.rmSync(path, { recursive: true, force: true }) },
27
- copyFile: fsSync.copyFileSync,
28
- remove: fsSync.rmSync,
29
- writeDir: fsSync.mkdirSync,
30
- unlink: fsSync.unlinkSync,
31
- stat: fsSync.statSync,
32
- writeFile: fsSync.writeFileSync
33
- }
34
-
35
- export const fsa = {
36
- exists: async (path) => {
37
- try { await fsAsync.access(path, constants.F_OK); return true }
38
- catch { return false }
39
- },
40
- readFile: async (path) => await fsa.exists(path) ? await fsAsync.readFile(path) : null,
41
- readText: async (path) => await fsa.exists(path) ? await fsAsync.readFile(path, 'utf8') : null,
42
- readJSON: async (path) => {
43
- try { return await fsa.exists(path) ? JSON.parse(await fsAsync.readFile(path, 'utf8')) : {} }
44
- catch { return {} }
45
- },
46
- writeJSON: async (path, json) => await fsAsync.writeFile(path, JSON.stringify(json, null, 4)),
47
- readDir: async (path, opts) => await fsa.exists(path) ? await fsAsync.readdir(path, opts) : [],
48
- readDirVisible: async (path) => (await fsa.readDir(path, { withFileTypes: true }))
49
- .filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name),
50
- isDir: async (path) => {
51
- try { return (await fsAsync.stat(path)).isDirectory() }
52
- catch { return false }
53
- },
54
- ensureDir: async (path) => { if (!await fsa.exists(path)) await fsAsync.mkdir(path, { recursive: true }) },
55
- writeText: async (path, text) => await fsAsync.writeFile(path, text),
56
- listFiles: async (path, ext = null) => (await fsa.readDir(path)).filter(f => !ext || f.endsWith(ext)),
57
- safeUnlink: async (path) => { if (await fsa.exists(path)) await fsAsync.unlink(path) },
58
- safeRemove: async (path) => { if (await fsa.exists(path)) await fsAsync.rm(path, { recursive: true, force: true }) },
59
- copyFile: fsAsync.copyFile,
60
- remove: fsAsync.rm,
61
- writeDir: fsAsync.mkdir,
62
- unlink: fsAsync.unlink,
63
- stat: fsAsync.stat,
64
- writeFile: fsAsync.writeFile
65
- }
1
+ export { fsa } from '#@/modules/fsa.js'
2
+ export { fss } from '#@/modules/fss.js'
package/modules/fsa.js ADDED
@@ -0,0 +1,35 @@
1
+ import { fsAsync, constants } from '#@/index.dep.js'
2
+
3
+ export const fsa = {
4
+ chmod: fsAsync.chmod,
5
+ exists: async (path) => {
6
+ try { await fsAsync.access(path, constants.F_OK); return true }
7
+ catch { return false }
8
+ },
9
+ readFile: async (path) => await fsa.exists(path) ? await fsAsync.readFile(path) : null,
10
+ readText: async (path) => await fsa.exists(path) ? await fsAsync.readFile(path, 'utf8') : null,
11
+ readJSON: async (path) => {
12
+ try { return await fsa.exists(path) ? JSON.parse(await fsAsync.readFile(path, 'utf8')) : {} }
13
+ catch { return {} }
14
+ },
15
+ writeJSON: async (path, json) => await fsAsync.writeFile(path, JSON.stringify(json, null, 4)),
16
+ readDir: async (path, opts) => await fsa.exists(path) ? await fsAsync.readdir(path, opts) : [],
17
+ readDirVisible: async (path) => (await fsa.readDir(path, { withFileTypes: true }))
18
+ .filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name),
19
+ isDir: async (path) => {
20
+ try { return (await fsAsync.stat(path)).isDirectory() }
21
+ catch { return false }
22
+ },
23
+ ensureDir: async (path) => { if (!await fsa.exists(path)) await fsAsync.mkdir(path, { recursive: true }) },
24
+ writeText: async (path, text) => await fsAsync.writeFile(path, text),
25
+ listFiles: async (path, ext = null) => (await fsa.readDir(path)).filter(f => !ext || f.endsWith(ext)),
26
+ safeUnlink: async (path) => { if (await fsa.exists(path)) await fsAsync.unlink(path) },
27
+ safeRemove: async (path) => { if (await fsa.exists(path)) await fsAsync.rm(path, { recursive: true, force: true }) },
28
+ append: async (path, buffer) => await fsAsync.appendFile(path, buffer),
29
+ copyFile: fsAsync.copyFile,
30
+ remove: fsAsync.rm,
31
+ writeDir: fsAsync.mkdir,
32
+ unlink: fsAsync.unlink,
33
+ stat: fsAsync.stat,
34
+ writeFile: fsAsync.writeFile
35
+ }
package/modules/fss.js ADDED
@@ -0,0 +1,32 @@
1
+ import { fsSync } from '#@/index.dep.js'
2
+
3
+ export const fss = {
4
+ exists: (...args) => fsSync.existsSync(...args),
5
+ readFile: (...args) => fss.exists(...args) ? fsSync.readFileSync(...args) : null,
6
+ readText: (path) => fss.exists(path) ? fsSync.readFileSync(path, 'utf8') : null,
7
+ readJSON: (...args) => {
8
+ try { return fss.exists(...args) ? JSON.parse(fsSync.readFileSync(...args), 'utf8') : {} }
9
+ catch { return {} }
10
+ },
11
+ writeJSON: (path, json) => fsSync.writeFileSync(path, JSON.stringify(json, null, 4)),
12
+ readDir: (...args) => fss.exists(...args) ? fsSync.readdirSync(...args) : [],
13
+ readDirVisible: (path) => (
14
+ fss.readDir(path, { withFileTypes: true }) || []
15
+ ).filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name),
16
+ isDir: (path) => {
17
+ try { return fsSync.statSync(path).isDirectory() }
18
+ catch { return false }
19
+ },
20
+ ensureDir: (path) => { if (!fss.exists(path)) fsSync.mkdirSync(path, { recursive: true }) },
21
+ writeText: (path, text) => fsSync.writeFileSync(path, text),
22
+ listFiles: (path, ext = null) => fss.readDir(path).filter(f => !ext || f.endsWith(ext)),
23
+ safeUnlink: (path) => { if (fss.exists(path)) fsSync.unlinkSync(path) },
24
+ safeRemove: (path) => { if (fss.exists(path)) fsSync.rmSync(path, { recursive: true, force: true }) },
25
+ copyFile: fsSync.copyFileSync,
26
+ remove: fsSync.rmSync,
27
+ writeDir: fsSync.mkdirSync,
28
+ unlink: fsSync.unlinkSync,
29
+ stat: fsSync.statSync,
30
+ writeFile: fsSync.writeFileSync,
31
+ writeStream: (...args) => fsSync.createWriteStream(...args),
32
+ }
package/package.json CHANGED
@@ -1,13 +1,22 @@
1
1
  {
2
+ "version": "1.0.4",
2
3
  "name": "@fullstackunicorn/filesystem",
3
- "author": "lucanigido[](https://fullstackunicorn.dev/author/lucanigido)",
4
- "version": "1.0.1",
5
- "main": "index.js",
6
- "type": "module",
4
+ "author": "lucanigido (https://fullstackunicorn.dev/author/lucanigido)",
5
+ "description": "A simple sync/async file system wrapper for Node.js",
7
6
  "license": "MIT",
7
+ "type": "module",
8
8
  "private": false,
9
- "description": "A simple sync/async file system wrapper for Node.js",
10
- "readme": "README.md",
9
+ "readme": "package.readme.md",
10
+ "main": "index.js",
11
+ "files": [
12
+ "index.js",
13
+ "index.dep.js",
14
+ "modules/"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://gitlab.com/fullstackunicorn/filesystem.git"
19
+ },
11
20
  "keywords": [
12
21
  "filesystem",
13
22
  "fs",
@@ -15,14 +24,12 @@
15
24
  "sync",
16
25
  "async"
17
26
  ],
18
- "repository": {
19
- "type": "git",
20
- "url": "https://gitlab.com/fullstackunicorn/filesystem.git"
27
+ "imports": {
28
+ "#@": "./",
29
+ "#@/*": "./*"
21
30
  },
22
- "files": [
23
- "index.js"
24
- ],
25
31
  "scripts": {
26
- "test": "echo \"Error: no test specified\" && exit 1"
32
+ "test": "exit 1",
33
+ "cli": "chmod +x ./config.cli.sh && ./config.cli.sh"
27
34
  }
28
- }
35
+ }
package/readme.md DELETED
@@ -1,122 +0,0 @@
1
- # @fullstackunicorn/filesystem
2
-
3
- [![NPM version](https://badge.fury.io/js/%40fullstackunicorn%2Ffilesystem.svg)](https://www.npmjs.com/package/@fullstackunicorn/filesystem)
4
- [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
- [![Node.js Version](https://img.shields.io/badge/node-v20-green.svg)](https://nodejs.org/)
6
-
7
- A lightweight, zero-dependency wrapper for Node.js's built-in `fs` module. It provides safe, crash-proof sync (`fss`) and async (`fsa`) APIs for common file system tasks. The goal is simplicity: one-liners that handle edge cases like non-existent paths or files, ensuring your code doesn't throw unexpected errors.
8
-
9
- Perfect for scripts, CLIs, or apps where you need reliable file I/O without boilerplate checks.
10
-
11
- ## Features
12
- - **Safe by Default**: Built-in existence checks prevent crashes (e.g., `readJSON` returns `{}` if file missing or invalid).
13
- - **One-Line Operations**: Write JSON to a new dir? `fss.writeJSON('./new/dir/config.json', data);`—it auto-creates dirs.
14
- - **Sync & Async**: Choose blocking (`fss`) or promise-based (`fsa`) methods.
15
- - **No Dependencies**: Pure Node.js (requires Node 14+ for `rm` support).
16
- - **Clear API**: Consistent methods like `readJSON`, `writeJSON`, `safeUnlink`.
17
-
18
- ## Installation
19
- ```bash
20
- npm install @fullstackunicorn/filesystem
21
- ```
22
- ```bash
23
- yarn add @fullstackunicorn/filesystem
24
- ```
25
-
26
- ## Quick Start
27
- ```javascript
28
- import { fss, fsa } from '@fullstackunicorn/filesystem';
29
-
30
- // Sync: Safe JSON read (returns {} if missing)
31
- const config = fss.readJSON('./config.json');
32
- console.log(config);
33
-
34
- // Sync: Write JSON (auto-creates dir if needed)
35
- fss.writeJSON('./logs/app.json', { message: 'Hello, safe FS!' });
36
-
37
- // Async: List files with extension filter
38
- const jsFiles = await fsa.listFiles('./src', '.js');
39
- console.log(jsFiles);
40
-
41
- // Safe removal (no error if missing)
42
- fss.safeRemove('./temp/dir');
43
- ```
44
-
45
- ## API Reference
46
-
47
- ### Sync API (`fss`)
48
- All methods are synchronous and return fallbacks on errors (e.g., `null`, `[]`, `{}`).
49
-
50
- | Method | Description | Parameters | Returns |
51
- |--------|-------------|------------|---------|
52
- | `exists(path)` | Checks if path exists. | `path: string` | `boolean` |
53
- | `readFile(path)` | Reads file as Buffer. | `path: string` | `Buffer \| null` |
54
- | `readText(path)` | Reads file as UTF-8 string. | `path: string` | `string \| null` |
55
- | `readJSON(path)` | Reads and parses JSON. | `path: string` | `object` (empty `{}` on error) |
56
- | `writeJSON(path, json)` | Writes pretty JSON (creates dir if needed). | `path: string`, `json: object` | `void` |
57
- | `readDir(path, opts?)` | Lists dir contents. | `path: string`, `opts?: object` | `string[]` |
58
- | `readDirVisible(path)` | Lists visible subdirs (no `.` hidden). | `path: string` | `string[]` |
59
- | `isDir(path)` | Checks if path is directory. | `path: string` | `boolean` |
60
- | `ensureDir(path)` | Creates dir recursively if missing. | `path: string` | `void` |
61
- | `writeText(path, text)` | Writes UTF-8 text. | `path: string`, `text: string` | `void` |
62
- | `listFiles(path, ext?)` | Lists files (optional extension filter). | `path: string`, `ext?: string` | `string[]` |
63
- | `safeUnlink(path)` | Removes file (no-op if missing). | `path: string` | `void` |
64
- | `safeRemove(path)` | Removes file/dir recursively (no-op if missing). | `path: string` | `void` |
65
- | `copyFile(src, dest)` | Copies file. | `src: string`, `dest: string` | `void` |
66
-
67
- ### Async API (`fsa`)
68
- Promise-based equivalents of `fss` methods. Use `await` for results.
69
-
70
- | Method | Description | Parameters | Returns |
71
- |--------|-------------|------------|---------|
72
- | `exists(path)` | Checks if path exists. | `path: string` | `Promise<boolean>` |
73
- | `readFile(path)` | Reads file as Buffer. | `path: string` | `Promise<Buffer \| null>` |
74
- | `readText(path)` | Reads file as UTF-8 string. | `path: string` | `Promise<string \| null>` |
75
- | `readJSON(path)` | Reads and parses JSON. | `path: string` | `Promise<object>` (empty `{}` on error) |
76
- | `writeJSON(path, json)` | Writes pretty JSON (creates dir if needed). | `path: string`, `json: object` | `Promise<void>` |
77
- | `readDir(path, opts?)` | Lists dir contents. | `path: string`, `opts?: object` | `Promise<string[]>` |
78
- | `readDirVisible(path)` | Lists visible subdirs (no `.` hidden). | `path: string` | `Promise<string[]>` |
79
- | `isDir(path)` | Checks if path is directory. | `path: string` | `Promise<boolean>` |
80
- | `ensureDir(path)` | Creates dir recursively if missing. | `path: string` | `Promise<void>` |
81
- | `writeText(path, text)` | Writes UTF-8 text. | `path: string`, `text: string` | `Promise<void>` |
82
- | `listFiles(path, ext?)` | Lists files (optional extension filter). | `path: string`, `ext?: string` | `Promise<string[]>` |
83
- | `safeUnlink(path)` | Removes file (no-op if missing). | `path: string` | `Promise<void>` |
84
- | `safeRemove(path)` | Removes file/dir recursively (no-op if missing). | `path: string` | `Promise<void>` |
85
- | `copyFile(src, dest)` | Copies file. | `src: string`, `dest: string` | `Promise<void>` |
86
-
87
- **Notes**:
88
- - JSON methods use 4-space pretty-printing.
89
- - `readDir` supports `{ withFileTypes: true }` for Dirent objects.
90
- - Errors are swallowed where possible (e.g., invalid JSON → `{}`); use `try-catch` for strict error handling.
91
-
92
- ## Examples
93
- ### Safe Config Management
94
- ```javascript
95
- import { fss } from '@fullstackunicorn/filesystem';
96
-
97
- function loadOrCreateConfig() {
98
- let config = fss.readJSON('./config.json');
99
- if (Object.keys(config).length === 0) {
100
- config = { theme: 'dark', lang: 'en' };
101
- fss.writeJSON('./config.json', config);
102
- }
103
- return config;
104
- }
105
- ```
106
-
107
- ### Async Dir Cleanup
108
- ```javascript
109
- import { fsa } from '@fullstackunicorn/filesystem';
110
-
111
- async function cleanupTemp() {
112
- await fsa.ensureDir('./temp');
113
- // ... write temp files ...
114
- await fsa.safeRemove('./temp'); // Safe even if empty/missing
115
- }
116
- ```
117
-
118
- ## Contributing
119
- Fork the repo, make changes, and submit a PR. Tests welcome!
120
-
121
- ## License
122
- MIT © [fullstackunicorn.dev/author/lucanigido](https://fullstackunicorn.dev/author/lucanigido)