@cntwg/file-helper 0.0.1
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/CHANGELOG.md +3 -0
- package/LICENSE +9 -0
- package/README.md +30 -0
- package/doc/file-helper.md +157 -0
- package/index.js +30 -0
- package/lib/base-func.js +288 -0
- package/lib/json-func.js +205 -0
- package/package.json +33 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2025 Yuri Grachev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
>|***rev.*:**|0.0.2|
|
|
2
|
+
>|:---|---:|
|
|
3
|
+
>|date:|2025-04-08|
|
|
4
|
+
|
|
5
|
+
## Introduction
|
|
6
|
+
|
|
7
|
+
This module provide a small helper library for load and save file content.
|
|
8
|
+
|
|
9
|
+
## Content
|
|
10
|
+
|
|
11
|
+
- Functions
|
|
12
|
+
- `checkFsError`;
|
|
13
|
+
- `loadFromFileSync`;
|
|
14
|
+
- `saveToFileSync`;
|
|
15
|
+
- `loadJSONFromFileSync`;
|
|
16
|
+
- `saveJSONToFileSync`.
|
|
17
|
+
|
|
18
|
+
- Functions (async)
|
|
19
|
+
- `loadFromFile`;
|
|
20
|
+
- `saveToFile`;
|
|
21
|
+
- `loadJSONFromFile`;
|
|
22
|
+
- `saveJSONToFile`.
|
|
23
|
+
|
|
24
|
+
> For more details see `file-helper.md` in the module `doc` directory.
|
|
25
|
+
|
|
26
|
+
## Use cases
|
|
27
|
+
|
|
28
|
+
### Installation
|
|
29
|
+
|
|
30
|
+
`npm install @cntwg/file-helper`
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
>|***rev.*:**|0.0.1|
|
|
2
|
+
>|:---|---:|
|
|
3
|
+
>|date:|2025-04-08|
|
|
4
|
+
|
|
5
|
+
## Introduction
|
|
6
|
+
|
|
7
|
+
This paper describes a functions provided by `file-helper.js` module.
|
|
8
|
+
|
|
9
|
+
## Content
|
|
10
|
+
|
|
11
|
+
- Functions
|
|
12
|
+
- <a href="#checkFsError">checkFsError</a>
|
|
13
|
+
- <a href="#loadFromFileSync">loadFromFileSync</a>
|
|
14
|
+
- <a href="#saveToFileSync">saveToFileSync</a>
|
|
15
|
+
- <a href="#loadJSONFromFileSync">loadJSONFromFileSync</a>
|
|
16
|
+
- <a href="#saveJSONToFileSync">saveJSONToFileSync</a>
|
|
17
|
+
|
|
18
|
+
- Functions (async)
|
|
19
|
+
- <a href="#loadFromFile">loadFromFile</a>
|
|
20
|
+
- <a href="#saveToFile">saveToFile</a>
|
|
21
|
+
- <a href="#loadJSONFromFile">loadJSONFromFile</a>
|
|
22
|
+
- <a href="#saveJSONToFile">saveJSONToFile</a>
|
|
23
|
+
|
|
24
|
+
### Base type definitions
|
|
25
|
+
|
|
26
|
+
This section contains some definitions for a general types of the objects (e.g. options set) that frequently used in a function or a class method descriptions.
|
|
27
|
+
|
|
28
|
+
<a name="typedef+fsoDescr"></a>
|
|
29
|
+
#### `fsoDescr` - descriptor
|
|
30
|
+
|
|
31
|
+
This descriptor is an `object` that describes a status for an operation with some FS-object (*e.g. object such as a file*).
|
|
32
|
+
|
|
33
|
+
| property name | value type | optional | description |
|
|
34
|
+
|:---|---|---:|:---|
|
|
35
|
+
| `isERR` | `boolean` | no | a flag which indicates whether an error was happen |
|
|
36
|
+
| `errCode` | `number` | yes | an error code |
|
|
37
|
+
| `errEvent` | `string` | no | an error event identifier |
|
|
38
|
+
| `errMsg` | `string` | yes | an error message |
|
|
39
|
+
| `source` | `string` | yes | path to a file |
|
|
40
|
+
| `content` | `any` | yes | content |
|
|
41
|
+
|
|
42
|
+
### Module functions
|
|
43
|
+
|
|
44
|
+
<a name="checkFsError"></a>
|
|
45
|
+
#### **checkFsError(descr. err)** => `object`
|
|
46
|
+
|
|
47
|
+
Checks an error code of a fs ops and sets a descriptor if succeed.
|
|
48
|
+
|
|
49
|
+
| parameter name | value type | default value | description |
|
|
50
|
+
|:---|---|---:|:---|
|
|
51
|
+
| `descr` | `fsoDescr` | --- | event descriptor |
|
|
52
|
+
| `err` | `Error` | --- | error event |
|
|
53
|
+
|
|
54
|
+
The returned value is an `object` that contains a properties listed in a table below:
|
|
55
|
+
|
|
56
|
+
| property name | value type | description |
|
|
57
|
+
|:---|---|:---|
|
|
58
|
+
| `isSucceed` | `boolean` | ops flag |
|
|
59
|
+
| `descr` | `fsoDescr` | event descriptor |
|
|
60
|
+
|
|
61
|
+
<a name="loadFromFileSync"></a>
|
|
62
|
+
#### **loadFromFileSync(src)** => `fsoDescr`
|
|
63
|
+
|
|
64
|
+
Loads a content from the file located by a given path.
|
|
65
|
+
|
|
66
|
+
| parameter name | value type | default value | description |
|
|
67
|
+
|:---|---|---:|:---|
|
|
68
|
+
| `src` | `string` | --- | a path to some file |
|
|
69
|
+
|
|
70
|
+
<a name="saveToFileSync"></a>
|
|
71
|
+
#### **saveToFileSync(src, content, [opt])** => `fsoDescr`
|
|
72
|
+
|
|
73
|
+
Saves a content to the file located by a given path.
|
|
74
|
+
|
|
75
|
+
| parameter name | value type | default value | description |
|
|
76
|
+
|:---|---|---:|:---|
|
|
77
|
+
| `src` | `string` | --- | a path to some file |
|
|
78
|
+
| `content` | `string` | --- | a content to save |
|
|
79
|
+
| `opt` | `any` | --- | <*reserved*> |
|
|
80
|
+
|
|
81
|
+
<a name="loadJSONFromFileSync"></a>
|
|
82
|
+
#### **loadJSONFromFileSync(src, [opt])** => `object`
|
|
83
|
+
|
|
84
|
+
Loads a content in JSON-format from the file located by a given path.
|
|
85
|
+
|
|
86
|
+
| parameter name | value type | default value | description |
|
|
87
|
+
|:---|---|---:|:---|
|
|
88
|
+
| `src` | `string` | --- | a path to some file |
|
|
89
|
+
| `opt` | `any` | --- | <*reserved*> |
|
|
90
|
+
|
|
91
|
+
The returned value is an `object` that contains a properties listed in a table below:
|
|
92
|
+
|
|
93
|
+
| property name | value type | description |
|
|
94
|
+
|:---|---|:---|
|
|
95
|
+
| `descr` | `fsoDescr` | ops descriptor |
|
|
96
|
+
| `obj` | `any` | loaded content |
|
|
97
|
+
|
|
98
|
+
<a name="saveJSONToFileSync"></a>
|
|
99
|
+
#### **saveJSONToFileSync(src, content, [opt])** => `fsoDescr`
|
|
100
|
+
|
|
101
|
+
Saves a content to the file located by a given path.
|
|
102
|
+
|
|
103
|
+
| parameter name | value type | default value | description |
|
|
104
|
+
|:---|---|---:|:---|
|
|
105
|
+
| `src` | `string` | --- | a path to some file |
|
|
106
|
+
| `content` | `object` | --- | a content to save |
|
|
107
|
+
| `opt` | `any` | --- | <*reserved*> |
|
|
108
|
+
|
|
109
|
+
### Module functions (*async*)
|
|
110
|
+
|
|
111
|
+
<a name="loadFromFile"></a>
|
|
112
|
+
#### **loadFromFile(src)** => `Promise<fsoDescr, Error>`
|
|
113
|
+
|
|
114
|
+
Loads a content from the file located by a given path.
|
|
115
|
+
|
|
116
|
+
| parameter name | value type | default value | description |
|
|
117
|
+
|:---|---|---:|:---|
|
|
118
|
+
| `src` | `string` | --- | a path to some file |
|
|
119
|
+
|
|
120
|
+
<a name="saveToFile"></a>
|
|
121
|
+
#### **saveToFile(src, content, [opt])** => `Promise<fsoDescr, Error>`
|
|
122
|
+
|
|
123
|
+
Saves a content to the file located by a given path.
|
|
124
|
+
|
|
125
|
+
| parameter name | value type | default value | description |
|
|
126
|
+
|:---|---|---:|:---|
|
|
127
|
+
| `src` | `string` | --- | a path to some file |
|
|
128
|
+
| `content` | `string` | --- | a content to save |
|
|
129
|
+
| `opt` | `any` | --- | <*reserved*> |
|
|
130
|
+
|
|
131
|
+
<a name="loadJSONFromFile"></a>
|
|
132
|
+
#### **loadJSONFromFile(src, [opt])** => `Promise<object, Error>`
|
|
133
|
+
|
|
134
|
+
Loads a content in JSON-format from the file located by a given path.
|
|
135
|
+
|
|
136
|
+
| parameter name | value type | default value | description |
|
|
137
|
+
|:---|---|---:|:---|
|
|
138
|
+
| `src` | `string` | --- | a path to some file |
|
|
139
|
+
| `opt` | `any` | --- | <*reserved*> |
|
|
140
|
+
|
|
141
|
+
The returned value is an `object` containing a properties listed in a table below:
|
|
142
|
+
|
|
143
|
+
| property name | value type | description |
|
|
144
|
+
|:---|---|:---|
|
|
145
|
+
| `descr` | `fsoDescr` | ops descriptor |
|
|
146
|
+
| `obj` | `any` | loaded content |
|
|
147
|
+
|
|
148
|
+
<a name="saveJSONToFile"></a>
|
|
149
|
+
#### **saveJSONToFile(src, content, [opt])** => `Promise<fsoDescr, Error>`
|
|
150
|
+
|
|
151
|
+
Saves a content to the file located by a given path.
|
|
152
|
+
|
|
153
|
+
| parameter name | value type | default value | description |
|
|
154
|
+
|:---|---|---:|:---|
|
|
155
|
+
| `src` | `string` | --- | a path to some file |
|
|
156
|
+
| `content` | `object` | --- | a content to save |
|
|
157
|
+
| `opt` | `any` | --- | <*reserved*> |
|
package/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// [v0.1.001-20250408]
|
|
2
|
+
|
|
3
|
+
// === module init block ===
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
loadFromFile, loadFromFileSync,
|
|
7
|
+
saveToFile, saveToFileSync,
|
|
8
|
+
checkFsError,
|
|
9
|
+
} = require('#lib/base-func.js');
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
loadJSONFromFile, loadJSONFromFileSync,
|
|
13
|
+
saveJSONToFile, saveJSONToFileSync,
|
|
14
|
+
} = require('#lib/json-func.js');
|
|
15
|
+
|
|
16
|
+
// === module extra block (helper functions) ===
|
|
17
|
+
|
|
18
|
+
// === module main block ===
|
|
19
|
+
|
|
20
|
+
// === module exports block ===
|
|
21
|
+
|
|
22
|
+
module.exports.checkFsError = checkFsError;
|
|
23
|
+
module.exports.loadFromFile = loadFromFile;
|
|
24
|
+
module.exports.loadFromFileSync = loadFromFileSync;
|
|
25
|
+
module.exports.saveToFile = saveToFile;
|
|
26
|
+
module.exports.saveToFileSync = saveToFileSync;
|
|
27
|
+
module.exports.loadJSONFromFile = loadJSONFromFile;
|
|
28
|
+
module.exports.loadJSONFromFileSync = loadJSONFromFileSync;
|
|
29
|
+
module.exports.saveJSONToFile = saveJSONToFile;
|
|
30
|
+
module.exports.saveJSONToFileSync = saveJSONToFileSync;
|
package/lib/base-func.js
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
// [v0.1.030-20250408]
|
|
2
|
+
|
|
3
|
+
// === module init block ===
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const fse = fs.promises;
|
|
7
|
+
|
|
8
|
+
// === module extra block (helper functions) ===
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* a ref to the `Array.isArray()` method
|
|
12
|
+
* @param {any} value - some value to verify
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
const isArray = Array.isArray;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @function isPlainObject
|
|
19
|
+
* @param {any} value - some value to verify
|
|
20
|
+
* @returns {boolean}
|
|
21
|
+
* @description Checks if the given value is a plain object
|
|
22
|
+
* @todo consider if an instance of 'Set' or 'Map' can be treated as plain object
|
|
23
|
+
*/
|
|
24
|
+
function isPlainObject(value = null) {
|
|
25
|
+
return value !== null && typeof value === 'object' && !isArray(value);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// === module main block ===
|
|
29
|
+
|
|
30
|
+
/***
|
|
31
|
+
* (* constant definitions *)
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/***
|
|
35
|
+
* (* function definitions *)
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {Object} fsoDescr
|
|
40
|
+
* @property {boolean} isERR - flag
|
|
41
|
+
* @property {number} [errCode] - error code
|
|
42
|
+
* @property {string} errEvent - event ID
|
|
43
|
+
* @property {string} [errMsg] - event message
|
|
44
|
+
* @property {string} [source] - path to file
|
|
45
|
+
* @property {any} [content] - file content
|
|
46
|
+
* @description A fs ops description.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {Object} VCOR_evalerrfs
|
|
51
|
+
* @property {boolean} isSucceed - ops flag
|
|
52
|
+
* @property {fsoDescr} descr - description
|
|
53
|
+
* @description A result of an error check ops.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @function checkFsError
|
|
58
|
+
* @param {fsoDescr} descr - event descriptor
|
|
59
|
+
* @param {Error} err - error event
|
|
60
|
+
* @returns {VCOR_evalerrfs}
|
|
61
|
+
* @description Checks an error code of a fs ops and sets descr info if succeed
|
|
62
|
+
*/
|
|
63
|
+
function checkFsError(descr, err) {
|
|
64
|
+
let isSucceed = false;
|
|
65
|
+
if (isPlainObject(err) && isPlainObject(descr)) {
|
|
66
|
+
const id = err.code;
|
|
67
|
+
switch (id) {
|
|
68
|
+
case 'ENOENT':
|
|
69
|
+
case 'EISDIR':
|
|
70
|
+
case 'ENOTDIR':
|
|
71
|
+
case 'EPERM': {
|
|
72
|
+
descr.errCode = err.errno;
|
|
73
|
+
descr.errEvent = id;
|
|
74
|
+
descr.errMsg = `ERR_FILE_${id}`;
|
|
75
|
+
isSucceed = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
default: {}
|
|
79
|
+
};
|
|
80
|
+
if (isSucceed) descr.isERR = true;
|
|
81
|
+
};
|
|
82
|
+
return { isSucceed, descr };
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @function loadFromFileSync
|
|
87
|
+
* @param {string} src - a path to some file
|
|
88
|
+
* @returns {fsoDescr}
|
|
89
|
+
* @description Loads file by a given path
|
|
90
|
+
*/
|
|
91
|
+
function loadFromFileSync(src) {
|
|
92
|
+
/** @type {fsoDescr} */
|
|
93
|
+
const data = {
|
|
94
|
+
isERR: false,
|
|
95
|
+
errCode: 0,
|
|
96
|
+
errEvent: '',
|
|
97
|
+
errMsg: '',
|
|
98
|
+
source: '',
|
|
99
|
+
content: '',
|
|
100
|
+
};
|
|
101
|
+
if (typeof src !== 'string') {
|
|
102
|
+
if (src !== undefined) {
|
|
103
|
+
data.isERR = true;
|
|
104
|
+
data.errEvent = 'ERR_INVARG';
|
|
105
|
+
data.errMsg = 'The "source" argument must be a string';
|
|
106
|
+
};
|
|
107
|
+
} else {
|
|
108
|
+
const srcPath = src.trim();
|
|
109
|
+
if (srcPath !== '') {
|
|
110
|
+
data.source = srcPath;
|
|
111
|
+
try {
|
|
112
|
+
data.content = fs.readFileSync(srcPath, 'utf8');
|
|
113
|
+
} catch (err) {
|
|
114
|
+
const { isSucceed } = checkFsError(data, err);
|
|
115
|
+
if (!isSucceed) {
|
|
116
|
+
// // TODO: [?] consider check others
|
|
117
|
+
//console.log(`TEST_ERR-MSG:loadFromFileSync: ${err}`);
|
|
118
|
+
//throw err;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
return data;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @function loadFromFile
|
|
128
|
+
* @param {string} src - a path to some file
|
|
129
|
+
* @returns {Promise<fsoDescr, Error>}
|
|
130
|
+
* @async
|
|
131
|
+
* @description Loads file by a given path
|
|
132
|
+
*/
|
|
133
|
+
function loadFromFile(src) {
|
|
134
|
+
/**/// main part that return promise as a result
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
/** @type {fsoDescr} */
|
|
137
|
+
const data = {
|
|
138
|
+
isERR: false,
|
|
139
|
+
errCode: 0,
|
|
140
|
+
errEvent: '',
|
|
141
|
+
errMsg: '',
|
|
142
|
+
source: '',
|
|
143
|
+
content: '',
|
|
144
|
+
};
|
|
145
|
+
if (typeof src !== 'string') {
|
|
146
|
+
if (src !== undefined) {
|
|
147
|
+
data.isERR = true;
|
|
148
|
+
data.errEvent = 'ERR_INVARG';
|
|
149
|
+
data.errMsg = 'The "source" argument must be a string';
|
|
150
|
+
};
|
|
151
|
+
resolve(data);
|
|
152
|
+
} else {
|
|
153
|
+
const srcPath = src.trim();
|
|
154
|
+
if (srcPath === '') resolve(data);
|
|
155
|
+
data.source = srcPath;
|
|
156
|
+
fse.readFile(srcPath, 'utf8').then(result => {
|
|
157
|
+
data.content = result;
|
|
158
|
+
resolve(data);
|
|
159
|
+
}).catch(err => {
|
|
160
|
+
let { isSucceed } = checkFsError(data, err);
|
|
161
|
+
if (isSucceed) {
|
|
162
|
+
data.content = '';
|
|
163
|
+
resolve(data);
|
|
164
|
+
} else {
|
|
165
|
+
//console.log('CHECK: loadFromFile() => Error => '+err);
|
|
166
|
+
//console.log('CHECK: loadFromFile() => Error => '+err.code);
|
|
167
|
+
reject(err);
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @function saveToFileSync
|
|
176
|
+
* @param {string} src - a path to some file
|
|
177
|
+
* @param {string} content - some file content
|
|
178
|
+
* @param {any} [opt] - <reserved>
|
|
179
|
+
* @returns {fsoDescr}
|
|
180
|
+
* @description Saves a content to a file
|
|
181
|
+
*/
|
|
182
|
+
function saveToFileSync(src, content = '', opt) {
|
|
183
|
+
/** @type {fsoDescr} */
|
|
184
|
+
const data = {
|
|
185
|
+
isERR: false,
|
|
186
|
+
errCode: 0,
|
|
187
|
+
errEvent: '',
|
|
188
|
+
errMsg: '',
|
|
189
|
+
source: '',
|
|
190
|
+
content: '',
|
|
191
|
+
};
|
|
192
|
+
if (typeof src !== 'string') {
|
|
193
|
+
data.isERR = true;
|
|
194
|
+
data.errEvent = src === undefined ? 'ERR_NOSRC' : 'ERR_INVARG';
|
|
195
|
+
data.errMsg = 'The "source" argument must be a string';
|
|
196
|
+
} else if (typeof content === 'string') {
|
|
197
|
+
const srcPath = src.trim();
|
|
198
|
+
if (srcPath === '') {
|
|
199
|
+
data.isERR = true;
|
|
200
|
+
data.errEvent = 'ERR_NOSRC';
|
|
201
|
+
data.errMsg = 'No "source" path given';
|
|
202
|
+
} else {
|
|
203
|
+
data.source = srcPath;
|
|
204
|
+
try {
|
|
205
|
+
fs.writeFileSync(srcPath, content, 'utf8');
|
|
206
|
+
} catch (err) {
|
|
207
|
+
const { isSucceed } = checkFsError(data, err);
|
|
208
|
+
if (!isSucceed) {
|
|
209
|
+
// // TODO: [?] consider check others
|
|
210
|
+
//console.log(`TEST_ERR-MSG:saveToFileSync: ${err}`);
|
|
211
|
+
//throw err;
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
} else {
|
|
216
|
+
data.isERR = true;
|
|
217
|
+
data.errEvent = 'ERR_INVARG';
|
|
218
|
+
data.errMsg = 'The "content" argument must be a string';
|
|
219
|
+
};
|
|
220
|
+
return data;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @function saveToFile
|
|
225
|
+
* @param {string} src - a path to some file
|
|
226
|
+
* @param {string} content - some file content
|
|
227
|
+
* @param {any} [opt] - <reserved>
|
|
228
|
+
* @returns {Promise<fsoDescr, Error>}
|
|
229
|
+
* @async
|
|
230
|
+
* @description Saves a content to a file
|
|
231
|
+
*/
|
|
232
|
+
function saveToFile(src, content = '', opt) {
|
|
233
|
+
/**/// main part that return promise as a result
|
|
234
|
+
return new Promise((resolve, reject) => {
|
|
235
|
+
/** @type {fsoDescr} */
|
|
236
|
+
const data = {
|
|
237
|
+
isERR: false,
|
|
238
|
+
errCode: 0,
|
|
239
|
+
errEvent: '',
|
|
240
|
+
errMsg: '',
|
|
241
|
+
source: '',
|
|
242
|
+
content: '',
|
|
243
|
+
};
|
|
244
|
+
if (typeof src !== 'string') {
|
|
245
|
+
data.isERR = true;
|
|
246
|
+
data.errEvent = src === undefined ? 'ERR_NOSRC' : 'ERR_INVARG';
|
|
247
|
+
data.errMsg = 'The "source" argument must be a string';
|
|
248
|
+
resolve(data);
|
|
249
|
+
} else if (typeof content === 'string') {
|
|
250
|
+
const srcPath = src.trim();
|
|
251
|
+
if (srcPath === '') {
|
|
252
|
+
data.isERR = true;
|
|
253
|
+
data.errEvent = 'ERR_NOSRC';
|
|
254
|
+
data.errMsg = 'No "source" path given';
|
|
255
|
+
resolve(data);
|
|
256
|
+
} else {
|
|
257
|
+
data.source = srcPath;
|
|
258
|
+
fse.writeFile(srcPath, content, 'utf8').then(result => {
|
|
259
|
+
resolve(data);
|
|
260
|
+
}).catch(err => {
|
|
261
|
+
const { isSucceed } = checkFsError(data, err);
|
|
262
|
+
if (isSucceed) resolve(data);
|
|
263
|
+
// // TODO: [?] consider check others
|
|
264
|
+
//console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err);
|
|
265
|
+
//console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err.code);
|
|
266
|
+
reject(err);
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
} else {
|
|
270
|
+
data.isERR = true;
|
|
271
|
+
data.errEvent = 'ERR_INVARG';
|
|
272
|
+
data.errMsg = 'The "content" argument must be a string';
|
|
273
|
+
resolve(data);
|
|
274
|
+
};
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/***
|
|
279
|
+
* (* class definitions *)
|
|
280
|
+
*/
|
|
281
|
+
|
|
282
|
+
// === module exports block ===
|
|
283
|
+
|
|
284
|
+
module.exports.checkFsError = checkFsError;
|
|
285
|
+
module.exports.loadFromFile = loadFromFile;
|
|
286
|
+
module.exports.loadFromFileSync = loadFromFileSync;
|
|
287
|
+
module.exports.saveToFile = saveToFile;
|
|
288
|
+
module.exports.saveToFileSync = saveToFileSync;
|
package/lib/json-func.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// [v0.1.030-20250408]
|
|
2
|
+
|
|
3
|
+
// === module init block ===
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
loadFromFile, loadFromFileSync,
|
|
7
|
+
saveToFile, saveToFileSync,
|
|
8
|
+
} = require('./base-func');
|
|
9
|
+
|
|
10
|
+
// === module extra block (helper functions) ===
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* a ref to the `Array.isArray()` method
|
|
14
|
+
* @param {any} value - some value to verify
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
const isArray = Array.isArray;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @function isPlainObject
|
|
21
|
+
* @param {any} value - some value to verify
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
* @description Checks if the given value is a plain object
|
|
24
|
+
* @todo consider if an instance of 'Set' or 'Map' can be treated as plain object
|
|
25
|
+
*/
|
|
26
|
+
function isPlainObject(value = null) {
|
|
27
|
+
return value !== null && typeof value === 'object' && !isArray(value);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// === module main block ===
|
|
31
|
+
|
|
32
|
+
/***
|
|
33
|
+
* (* constant definitions *)
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/***
|
|
37
|
+
* (* function definitions *)
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @typedef {Object} RVAL_loadjsonff
|
|
42
|
+
* @property {fsoDescr} descr - ops description
|
|
43
|
+
* @property {any} obj - loaded content
|
|
44
|
+
* @description A result of `loadJSONFromFileSync`
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @function loadJSONFromFileSync
|
|
49
|
+
* @param {string} src - a path to some file
|
|
50
|
+
* @param {any} [opt] - <reserved>
|
|
51
|
+
* @returns {RVAL_loadjsonff}
|
|
52
|
+
* @description Loads a JSON-object from a file
|
|
53
|
+
*/
|
|
54
|
+
function loadJSONFromFileSync(src, opt) {
|
|
55
|
+
const data = loadFromFileSync(src);
|
|
56
|
+
let obj = null;
|
|
57
|
+
if (!data.isERR) {
|
|
58
|
+
if (data.content !== '') {
|
|
59
|
+
try {
|
|
60
|
+
obj = JSON.parse(data.content);
|
|
61
|
+
// if succeed clear <data.content>
|
|
62
|
+
data.content = '';
|
|
63
|
+
} catch (err) {
|
|
64
|
+
data.isERR = true;
|
|
65
|
+
//console.log(`TEST_ERR-CODE: [${err.code}](${err.errno})`);
|
|
66
|
+
//console.log(`TEST_ERR-MSG: ${err}`);
|
|
67
|
+
if (err instanceof SyntaxError) {
|
|
68
|
+
data.errEvent = 'ERR_JSON_BADDATA';
|
|
69
|
+
data.errMsg = err.message;
|
|
70
|
+
} else {
|
|
71
|
+
data.errEvent = 'ERR_JSON_UNKNOWN';
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
return { descr: data, obj };
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @function loadJSONFromFile
|
|
81
|
+
* @param {string} src - a path to some file
|
|
82
|
+
* @param {any} [opt] - <reserved>
|
|
83
|
+
* @returns {Promise<RVAL_loadjsonff, Error>}
|
|
84
|
+
* @async
|
|
85
|
+
* @description Loads a JSON-object from a file
|
|
86
|
+
*/
|
|
87
|
+
function loadJSONFromFile(src, opt) {
|
|
88
|
+
/**/// main part that return promise as a result
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
loadFromFile(src).then(data => {
|
|
91
|
+
let obj = null;
|
|
92
|
+
if (!data.isERR) {
|
|
93
|
+
if (data.content !== '') {
|
|
94
|
+
try {
|
|
95
|
+
obj = JSON.parse(data.content);
|
|
96
|
+
// if succeed clear <data.content>
|
|
97
|
+
data.content = '';
|
|
98
|
+
} catch (err) {
|
|
99
|
+
data.isERR = true;
|
|
100
|
+
//console.log(`TEST_ERR-CODE: [${err.code}](${err.errno})`);
|
|
101
|
+
//console.log(`TEST_ERR-MSG: ${err}`);
|
|
102
|
+
if (err instanceof SyntaxError) {
|
|
103
|
+
data.errEvent = 'ERR_JSON_BADDATA';
|
|
104
|
+
data.errMsg = err.message;
|
|
105
|
+
} else {
|
|
106
|
+
data.errEvent = 'ERR_JSON_UNKNOWN';
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
resolve({ descr: data, obj });
|
|
112
|
+
}).catch(err => {
|
|
113
|
+
//console.log('CHECK: TXEpgContentProvider.loadFromFile() => Error => '+err);
|
|
114
|
+
//console.log('CHECK: TXEpgContentProvider.loadFromFile() => Error => '+err.code);
|
|
115
|
+
reject(err);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @function saveJSONToFileSync
|
|
122
|
+
* @param {string} src - a path to some file
|
|
123
|
+
* @param {object} obj - some content
|
|
124
|
+
* @param {any} [opt] - <reserved>
|
|
125
|
+
* @returns {fsoDescr}
|
|
126
|
+
* @description Saves a JSON-object to a file
|
|
127
|
+
*/
|
|
128
|
+
function saveJSONToFileSync(src, obj, opt) {
|
|
129
|
+
/** @type {fsoDescr} */
|
|
130
|
+
let data = {
|
|
131
|
+
isERR: false,
|
|
132
|
+
errCode: 0,
|
|
133
|
+
errEvent: '',
|
|
134
|
+
errMsg: '',
|
|
135
|
+
source: '',
|
|
136
|
+
content: '',
|
|
137
|
+
};
|
|
138
|
+
try {
|
|
139
|
+
data.content = JSON.stringify(obj, null, 2);
|
|
140
|
+
} catch (err) {
|
|
141
|
+
data.isERR = true;
|
|
142
|
+
//console.log(`TEST_ERR-CODE: [${err.code}](${err.errno})`);
|
|
143
|
+
//console.log(`TEST_ERR-MSG: ${err}`);
|
|
144
|
+
data.errEvent = 'ERR_JSON_UNKNOWN';
|
|
145
|
+
};
|
|
146
|
+
if (!data.isERR) {
|
|
147
|
+
data = saveToFileSync(src, data.content, opt);
|
|
148
|
+
};
|
|
149
|
+
return data;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @function saveJSONToFile
|
|
154
|
+
* @param {string} src - a path to some file
|
|
155
|
+
* @param {object} obj - some content
|
|
156
|
+
* @param {any} [opt] - <reserved>
|
|
157
|
+
* @returns {Promise<fsoDescr, Error>}
|
|
158
|
+
* @throws {Error}
|
|
159
|
+
* @async
|
|
160
|
+
* @description Saves a JSON-object to a file
|
|
161
|
+
*/
|
|
162
|
+
function saveJSONToFile(src, obj, opt) {
|
|
163
|
+
/**/// main part that return promise as a result
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
/** @type {fsoDescr} */
|
|
166
|
+
let data = {
|
|
167
|
+
isERR: false,
|
|
168
|
+
errCode: 0,
|
|
169
|
+
errEvent: '',
|
|
170
|
+
errMsg: '',
|
|
171
|
+
source: '',
|
|
172
|
+
content: '',
|
|
173
|
+
};
|
|
174
|
+
(new Promise((resolve, reject) => {
|
|
175
|
+
data.content = JSON.stringify(obj, null, 2);
|
|
176
|
+
resolve(true);
|
|
177
|
+
})).then(result => {
|
|
178
|
+
saveToFile(src, data.content, null).then(data => {
|
|
179
|
+
resolve(data);
|
|
180
|
+
}).catch(err => {
|
|
181
|
+
// // TODO: [?] consider check others
|
|
182
|
+
//console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err);
|
|
183
|
+
//console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err.code);
|
|
184
|
+
reject(err);
|
|
185
|
+
});
|
|
186
|
+
}).catch(err => {
|
|
187
|
+
data.isERR = true;
|
|
188
|
+
//console.log(`TEST_ERR-CODE: [${err.code}](${err.errno})`);
|
|
189
|
+
//console.log(`TEST_ERR-MSG: ${err}`);
|
|
190
|
+
data.errEvent = 'ERR_JSON_UNKNOWN';
|
|
191
|
+
resolve(data);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/***
|
|
197
|
+
* (* class definitions *)
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
// === module exports block ===
|
|
201
|
+
|
|
202
|
+
module.exports.loadJSONFromFile = loadJSONFromFile;
|
|
203
|
+
module.exports.loadJSONFromFileSync = loadJSONFromFileSync;
|
|
204
|
+
module.exports.saveJSONToFile = saveJSONToFile;
|
|
205
|
+
module.exports.saveJSONToFileSync = saveJSONToFileSync;
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cntwg/file-helper",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A small helper library to load/save file content",
|
|
5
|
+
"author": "ygracs <cs70th-om@rambler.ru>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://gitlab.com/cntwg/file-helper.git"
|
|
10
|
+
},
|
|
11
|
+
"main": "./index.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"doc/file-helper.md",
|
|
14
|
+
"lib/base-func.js",
|
|
15
|
+
"lib/json-func.js",
|
|
16
|
+
"index.js",
|
|
17
|
+
"CHANGELOG.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "jest",
|
|
21
|
+
"build-doc-md": "jsdoc2md",
|
|
22
|
+
"build-doc-html": "jsdoc"
|
|
23
|
+
},
|
|
24
|
+
"imports": {
|
|
25
|
+
"#lib/*": "./lib/*",
|
|
26
|
+
"#test-dir/*": "./__test__/*"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"jest": "^29.7.0",
|
|
30
|
+
"jsdoc-to-markdown": "^9.1.1",
|
|
31
|
+
"minimist": "^1.2.8"
|
|
32
|
+
}
|
|
33
|
+
}
|