@impactor/nodejs 3.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/LICENSE +21 -0
- package/README.md +129 -0
- package/index.d.ts +7 -0
- package/index.js +11 -0
- package/nx.json +190 -0
- package/package.json +72 -0
- package/src/cache-fs.d.ts +8 -0
- package/src/cache-fs.js +32 -0
- package/src/cache-fs.spec.js +38 -0
- package/src/fs-sync.d.ts +41 -0
- package/src/fs-sync.js +212 -0
- package/src/fs-sync.spec.js +262 -0
- package/src/fs.d.ts +16 -0
- package/src/fs.js +188 -0
- package/src/fs.spec.js +251 -0
- package/src/https.d.ts +3 -0
- package/src/https.js +52 -0
- package/src/https.spec.js +19 -0
- package/src/process.d.ts +13 -0
- package/src/process.js +203 -0
- package/src/process.spec.js +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Dibo
|
|
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,129 @@
|
|
|
1
|
+
Nodejs utils
|
|
2
|
+
|
|
3
|
+
# FS operations
|
|
4
|
+
|
|
5
|
+
Working with files, directories, and paths.
|
|
6
|
+
all functions are available as promise or sync, for example:
|
|
7
|
+
|
|
8
|
+
- `read()` -> the promise version
|
|
9
|
+
- `readSync()` -> the sync version
|
|
10
|
+
|
|
11
|
+
The following are just a choosen examples, to see the full API check our docs.
|
|
12
|
+
|
|
13
|
+
### Reading a JSON file
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { read } from "@impactor/nodejs-utils";
|
|
17
|
+
|
|
18
|
+
let file = await read("./package.json");
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The content automatically pared as JSON.
|
|
22
|
+
|
|
23
|
+
### Reading a cache file if only it is not expired
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { read } from "@impactor/nodejs-utils";
|
|
27
|
+
|
|
28
|
+
let cache = await read("./cache.json", { maxAge: 10000 });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Writing a JSON data
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { write } from "@impactor/nodejs-utils";
|
|
35
|
+
|
|
36
|
+
write("./data/reports/report.json", { status: "ok" });
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The data will be stringified automatically.
|
|
40
|
+
also, you don't need to manually create the directory, because it is created recursively.
|
|
41
|
+
for instance if `./data` or `./data/reports` doesn't exist, it'll be created.
|
|
42
|
+
|
|
43
|
+
### copy or move a file or folder, you can filter the files to be copied.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// copy static non-typescript files
|
|
47
|
+
copy("src", "dist/assets", (file) => !file.endsWith(".ts"));
|
|
48
|
+
|
|
49
|
+
// move flat-structure project to use "src"
|
|
50
|
+
move(".", "./src", (file) => file.endsWith(".ts"));
|
|
51
|
+
|
|
52
|
+
// remove log files
|
|
53
|
+
remove("./data", (file) => file.endsWith(".log"));
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Parsing a path
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
let info = parsePath("./data/report.txt");
|
|
60
|
+
|
|
61
|
+
console.log(`type: ${info.type}`); // file or dir
|
|
62
|
+
console.log(`file extension: ${info.extension}`); // txt
|
|
63
|
+
console.log(`the containing dir: ${info.dir}`); // data
|
|
64
|
+
console.log(`file name: ${info.name}`); // report
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Get the total size of a file or directory
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
getSize("./data");
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Create the full path directory recursively
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
mkdir("./data/reports/summaries");
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
if one portion of the specified path doesn't exist, the full path will be created.
|
|
80
|
+
for example, if `./data` doesn't exist, it'll be created first, then `reports` then `summaries`.
|
|
81
|
+
It also accepts files, the containing directory will be created.
|
|
82
|
+
|
|
83
|
+
## get all or some files or directory.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// list first-level directories under "apps"
|
|
87
|
+
getEntries("apps", "dirs", 1);
|
|
88
|
+
|
|
89
|
+
// list all files under "reports" and its children
|
|
90
|
+
getEntries("reports", "files");
|
|
91
|
+
|
|
92
|
+
// list all JSON files under reports
|
|
93
|
+
getEntries("reports", "files", (entry) => entry.endsWith(".json"));
|
|
94
|
+
|
|
95
|
+
// list all summary log files under "reports"
|
|
96
|
+
// i.e. files that follow this pattern "summary-{number}.log"
|
|
97
|
+
getEntries("reports", "files", /summary-\d\.log/);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Apply an arbitrary action recursively
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// remove all "*.log" files under "reports" and its subdirectories, recursively.
|
|
104
|
+
recursive(
|
|
105
|
+
"reports", // the starting point
|
|
106
|
+
(entry) => unlinkSync(entry), // the action to be applied
|
|
107
|
+
(entry) => entry.endsWith(".log"), // the filter
|
|
108
|
+
);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
# Cache
|
|
112
|
+
|
|
113
|
+
Manage caches.
|
|
114
|
+
built on top of [@impactor/cache](https://www.npmjs.com/package/@impactor/cache), using file-system caching.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
let cache = await cacheFS(
|
|
118
|
+
// cache entries
|
|
119
|
+
["./report-today.json", "./report-yesterday.json"],
|
|
120
|
+
// data source
|
|
121
|
+
() => fetch("https://my-server.com/getReport"),
|
|
122
|
+
// cache options
|
|
123
|
+
{
|
|
124
|
+
maxAge: 1000,
|
|
125
|
+
maxStale: 2000,
|
|
126
|
+
// you don't need to define `read()` and `write()` here.
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
```
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./src/cache-fs";
|
|
2
|
+
export * from "./src/fs";
|
|
3
|
+
export * from "./src/fs-sync";
|
|
4
|
+
export * from "./src/https";
|
|
5
|
+
export * from "./src/process";
|
|
6
|
+
import { default as default2 } from "./src/cache-fs";
|
|
7
|
+
import { default as default3 } from "./src/https";
|
|
8
|
+
export {
|
|
9
|
+
default2 as cacheFs,
|
|
10
|
+
default3 as https
|
|
11
|
+
};
|
package/nx.json
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
|
3
|
+
"targetDefaults": {
|
|
4
|
+
"build": {
|
|
5
|
+
"executor": "@impactor/nx-manager:universal-builder",
|
|
6
|
+
"dependsOn": ["typecheck", "prebuild", "^build"],
|
|
7
|
+
"cache": true,
|
|
8
|
+
"inputs": ["default", "^default"],
|
|
9
|
+
"outputs": ["{projectRoot}/dist"],
|
|
10
|
+
"options": {
|
|
11
|
+
"forceRnDefaultPostBuild": true
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"serve": {
|
|
15
|
+
"executor": "nx:run-commands",
|
|
16
|
+
"dependsOn": ["build", "preserve"],
|
|
17
|
+
"continuous": true,
|
|
18
|
+
"options": {
|
|
19
|
+
"cwd": "{projectRoot}",
|
|
20
|
+
"command": "NODE_ENV=development pnpm tsx --env-file-if-exists=.env --env-file-if-exists=.env.local dist/main.js"
|
|
21
|
+
},
|
|
22
|
+
"configurations": {
|
|
23
|
+
"production": {
|
|
24
|
+
"command": "NODE_ENV=production pnpm tsx --env-file-if-exists=.env --env-file-if-exists=.env.local --env-file-if-exists=.env.production --env-file-if-exists=.env.production.local dist/main.js"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"nx-release-publish": {
|
|
29
|
+
"options": {
|
|
30
|
+
"packageRoot": "{projectRoot}/dist"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"semantic-release": {
|
|
34
|
+
"executor": "nx:run-commands",
|
|
35
|
+
"dependsOn": ["build", "prerelease"],
|
|
36
|
+
"options": {
|
|
37
|
+
"cwd": "{projectRoot}",
|
|
38
|
+
"command": "pnpm tsx node_modules/semantic-release/bin/semantic-release.js"
|
|
39
|
+
},
|
|
40
|
+
"configurations": {
|
|
41
|
+
"local": {
|
|
42
|
+
"command": "DOTENV_CONFIG_PATH=../../.env pnpm run release --no-ci"
|
|
43
|
+
},
|
|
44
|
+
"dry": {
|
|
45
|
+
"command": "DOTENV_CONFIG_PATH=../../.env pnpm run release --no-ci --dry-run"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"test": {
|
|
50
|
+
"inputs": ["test"],
|
|
51
|
+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
52
|
+
"dependsOn": ["^build", "pretest"],
|
|
53
|
+
"configurations": {
|
|
54
|
+
"unit": {
|
|
55
|
+
"args": [
|
|
56
|
+
"--testPathIgnorePatterns '.*\\.e2e\\.spec\\.ts$'",
|
|
57
|
+
"--testPathIgnorePatterns '/.*-e2e/'",
|
|
58
|
+
"--testPathIgnorePatterns '/.*-e2e/'"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"e2e": {
|
|
62
|
+
"args": [
|
|
63
|
+
"--testMatch '**/*-e2e/**/*.{spec,test}.[mc]?[jt]s?(x)'",
|
|
64
|
+
"--testMatch '**/e2e/**/*.{spec,test}.[mc]?[jt]s?(x)'",
|
|
65
|
+
"--testMatch '**/*.e2e.(spec|test).?([mc])[jt]s?(x)'"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"@angular/build:application": {
|
|
71
|
+
"cache": true,
|
|
72
|
+
"dependsOn": ["prebuild", "^build"],
|
|
73
|
+
"inputs": ["default", "^default"]
|
|
74
|
+
},
|
|
75
|
+
"@nx/angular:package": {
|
|
76
|
+
"cache": true,
|
|
77
|
+
"dependsOn": ["^build"],
|
|
78
|
+
"inputs": ["default", "^default"],
|
|
79
|
+
"outputs": ["{projectRoot}/dist"],
|
|
80
|
+
"options": {
|
|
81
|
+
"project": "{projectRoot}/ng-package.json",
|
|
82
|
+
"tsConfig": "{projectRoot}/tsconfig.lib.json"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"@nx/js:tsc": {
|
|
86
|
+
"cache": true,
|
|
87
|
+
"dependsOn": ["^build"],
|
|
88
|
+
"inputs": ["default", "^default"]
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"namedInputs": {
|
|
92
|
+
"default": [
|
|
93
|
+
"{projectRoot}/src/**/*",
|
|
94
|
+
"!{projectRoot}/**/*.(spec|test)(.e2e)?.[tj]sx?",
|
|
95
|
+
"!{projectRoot}/**/e2e/**/*",
|
|
96
|
+
"{projectRoot}/.env(.*)?",
|
|
97
|
+
"{workspaceRoot}/tasks/(post-)?build.ts",
|
|
98
|
+
"{projectRoot}/(project|package|tsconfig)(.+)?.json",
|
|
99
|
+
"{workspaceRoot}/tsconfig.base.json",
|
|
100
|
+
{
|
|
101
|
+
"runtime": "node --version"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"env": "NODE_ENV"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"test": [
|
|
108
|
+
"default",
|
|
109
|
+
"{projectRoot}/tsconfig.spec.json",
|
|
110
|
+
"{projectRoot}/jest.config.[jt]s",
|
|
111
|
+
"{workspaceRoot}/jest.config.[jt]s",
|
|
112
|
+
"{projectRoot}/**/*.(spec|test)(.e2e)?.[jt]sx?",
|
|
113
|
+
"{projectRoot}/**/e2e/**/*.[jt]sx?",
|
|
114
|
+
{
|
|
115
|
+
"externalDependencies": ["jest"]
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"plugins": [
|
|
120
|
+
{
|
|
121
|
+
"plugin": "@nx/js/typescript",
|
|
122
|
+
"options": {
|
|
123
|
+
"typecheck": {
|
|
124
|
+
"targetName": "typecheck"
|
|
125
|
+
},
|
|
126
|
+
"build": false
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"plugin": "@nx/jest/plugin",
|
|
131
|
+
"options": {
|
|
132
|
+
"targetName": "test",
|
|
133
|
+
"ciTargetName": "test-ci"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"tasksRunnerOptions": {
|
|
138
|
+
"default": {
|
|
139
|
+
"options": {
|
|
140
|
+
"useDaemonProcess": false
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"generators": {
|
|
145
|
+
"@nx/angular:library": {
|
|
146
|
+
"linter": "eslint",
|
|
147
|
+
"unitTestRunner": "jest"
|
|
148
|
+
},
|
|
149
|
+
"@nx/angular:component": {
|
|
150
|
+
"style": "scss"
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"release": {
|
|
154
|
+
"groups": {
|
|
155
|
+
"libs": {
|
|
156
|
+
"projects": ["libs/*"]
|
|
157
|
+
},
|
|
158
|
+
"apps": {
|
|
159
|
+
"projects": ["apps/*"],
|
|
160
|
+
"changelog": {
|
|
161
|
+
"projectChangelogs": {
|
|
162
|
+
"createRelease": "github"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"projectsRelationship": "independent",
|
|
168
|
+
"version": {
|
|
169
|
+
"conventionalCommits": true,
|
|
170
|
+
"updateDependents": "always",
|
|
171
|
+
"preVersionCommand": "pnpm nx run-many -t build",
|
|
172
|
+
"manifestRootsToUpdate": [
|
|
173
|
+
"{projectRoot}",
|
|
174
|
+
{
|
|
175
|
+
"path": "{projectRoot}/dist",
|
|
176
|
+
"preserveLocalDependencyProtocols": false
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
"releaseTag": {
|
|
181
|
+
"pattern": "{projectName}@{version}"
|
|
182
|
+
},
|
|
183
|
+
"changelog": {
|
|
184
|
+
"projectChangelogs": true
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"sync": {
|
|
188
|
+
"applyChanges": false
|
|
189
|
+
}
|
|
190
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@impactor/nodejs",
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "nodejs utils",
|
|
6
|
+
"private": false,
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"nodejs",
|
|
12
|
+
"javascript",
|
|
13
|
+
"js"
|
|
14
|
+
],
|
|
15
|
+
"nx": {
|
|
16
|
+
"projectType": "library",
|
|
17
|
+
"targets": {
|
|
18
|
+
"build": {},
|
|
19
|
+
"semantic-release": {}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"imports": {
|
|
23
|
+
"#*": "./src/*.js"
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./index.d.js",
|
|
28
|
+
"default": "./index.js"
|
|
29
|
+
},
|
|
30
|
+
"./package.json": {
|
|
31
|
+
"default": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
"./*": "./src/*"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"content-type": "^1.0.5",
|
|
37
|
+
"@impactor/cache": "3.0.1",
|
|
38
|
+
"@impactor/javascript": "3.0.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/content-type": "^1.1.9",
|
|
42
|
+
"semantic-release": "^25.0.2",
|
|
43
|
+
"semantic-release-monorepo": "^8.0.2",
|
|
44
|
+
"tsx": "^4.21.0"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/its-dibo/dibo.git"
|
|
52
|
+
},
|
|
53
|
+
"author": "Sherif Eldeeb <sh.eldeeb.2010+github@gmail.com> (https://github.com/its-dibo)",
|
|
54
|
+
"homepage": "https://github.com/its-dibo/dibo#readme",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/its-dibo/dibo/issues",
|
|
57
|
+
"email": "sh.eldeeb.2010+github@gmail.com"
|
|
58
|
+
},
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"contributors": [],
|
|
61
|
+
"funding": [
|
|
62
|
+
{
|
|
63
|
+
"type": "paypal",
|
|
64
|
+
"url": "https://paypal.me/group99001"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "patreon",
|
|
68
|
+
"url": "https://www.patreon.com/GoogleDev"
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"scripts": {}
|
|
72
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CacheOptions } from '@impactor/cache';
|
|
2
|
+
import { type PathLike } from 'node:fs';
|
|
3
|
+
import { type ReadOptions } from './fs-sync';
|
|
4
|
+
export interface CacheOpts extends Omit<CacheOptions, 'read' | 'write'> {
|
|
5
|
+
}
|
|
6
|
+
export interface CacheFSOptions extends CacheOptions, ReadOptions {
|
|
7
|
+
}
|
|
8
|
+
export default function cacheFS(files: PathLike | PathLike[], dataSource?: () => unknown, options?: CacheOpts): Promise<unknown>;
|
package/src/cache-fs.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cache } from "@impactor/cache";
|
|
2
|
+
import { readSync, resolve } from "./fs-sync";
|
|
3
|
+
import { write } from "./fs";
|
|
4
|
+
function getCache(entries, options) {
|
|
5
|
+
for (let filePath of entries) {
|
|
6
|
+
try {
|
|
7
|
+
let data = readSync(filePath, options);
|
|
8
|
+
if (data !== void 0) {
|
|
9
|
+
return data;
|
|
10
|
+
}
|
|
11
|
+
} catch {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
throw "no valid cache found";
|
|
15
|
+
}
|
|
16
|
+
function setCache(entry, data, _options) {
|
|
17
|
+
return write(entry, data);
|
|
18
|
+
}
|
|
19
|
+
function cacheFS(files, dataSource, options) {
|
|
20
|
+
let opts = {
|
|
21
|
+
read: (entries, options2) => getCache(entries, options2),
|
|
22
|
+
write: (entry, data, options2) => setCache(entry, data, options2),
|
|
23
|
+
...options
|
|
24
|
+
};
|
|
25
|
+
let cacheEntries = (Array.isArray(files) ? files : [files]).map(
|
|
26
|
+
(filePath) => resolve(filePath)
|
|
27
|
+
);
|
|
28
|
+
return cache(cacheEntries, dataSource, opts);
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
cacheFS as default
|
|
32
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { afterAll, beforeEach, expect, test } from "@jest/globals";
|
|
2
|
+
import cache from "./cache-fs";
|
|
3
|
+
import { remove, write } from "./fs";
|
|
4
|
+
import { resolve } from "./fs-sync";
|
|
5
|
+
let dir = resolve(import.meta.dirname, "./test!!/cache");
|
|
6
|
+
beforeEach(() => remove(`${dir}/file.txt`));
|
|
7
|
+
afterAll(() => remove(dir));
|
|
8
|
+
test("create a new cache", () => cache(`${dir}/new-file.txt`, () => "content").then(
|
|
9
|
+
(value) => expect(value).toEqual("content")
|
|
10
|
+
));
|
|
11
|
+
test("read from an existing cached file", () => write(`${dir}/file-uguihgkuhkgj.txt`, "content#1").then(() => cache(`${dir}/file-uguihgkuhkgj.txt`, () => "content#2")).then((value) => expect(value).toEqual("content#1")));
|
|
12
|
+
test("read from multiple cache paths, one of them exists - case1", () => write(`${dir}/multiple-case1/file.txt`, "content#1").then(
|
|
13
|
+
() => cache(
|
|
14
|
+
[
|
|
15
|
+
`${dir}/multiple-case1/file.txt`,
|
|
16
|
+
`${dir}/none1.txt`,
|
|
17
|
+
`${dir}/none2.txt`
|
|
18
|
+
],
|
|
19
|
+
() => "content#3"
|
|
20
|
+
)
|
|
21
|
+
).then((value) => expect(value).toEqual("content#1")));
|
|
22
|
+
test("read from multiple cache paths, one of them exists - case2", () => write(`${dir}/multiple-case2/file.txt`, "content#1").then(
|
|
23
|
+
() => cache(
|
|
24
|
+
[
|
|
25
|
+
`${dir}/none1.txt`,
|
|
26
|
+
`${dir}/multiple-case2/file.txt`,
|
|
27
|
+
`${dir}/none2.txt`
|
|
28
|
+
],
|
|
29
|
+
() => "content#3"
|
|
30
|
+
)
|
|
31
|
+
).then((value) => expect(value).toEqual("content#1")));
|
|
32
|
+
test("read from multiple cache paths, non exists", () => cache([`${dir}/none3.txt`, `${dir}/none4.txt`], () => "content").then(
|
|
33
|
+
(value) => expect(value).toEqual("content")
|
|
34
|
+
));
|
|
35
|
+
test("read from .json file", () => write(`${dir}/file.json`, { x: 1 }).then(() => cache(`${dir}/file.json`, () => "nothing")).then((value) => expect(value).toEqual({ x: 1 })));
|
|
36
|
+
test("read from a Promise dataSource", () => cache(`${dir}/promise.txt`, () => {
|
|
37
|
+
return new Promise((r) => r("content"));
|
|
38
|
+
}).then((value) => expect(value).toEqual("content")));
|
package/src/fs-sync.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Obj } from '@impactor/javascript';
|
|
2
|
+
import { type PathLike, type WriteFileOptions } from 'node:fs';
|
|
3
|
+
export declare function resolve(...paths: Array<PathLike | URL>): string;
|
|
4
|
+
export interface ParsePath {
|
|
5
|
+
type: 'dir' | 'file';
|
|
6
|
+
dir: string;
|
|
7
|
+
name: string;
|
|
8
|
+
extension: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function parsePath(path: PathLike): ParsePath;
|
|
11
|
+
export declare function getExtensionSync(file: PathLike): string;
|
|
12
|
+
export declare function getSizeSync(path: PathLike | PathLike[], unit?: 'b' | 'kb' | 'mb' | 'gb', filter?: Filter): number;
|
|
13
|
+
export declare function isDirSync(path: PathLike): boolean;
|
|
14
|
+
export declare function getModifiedTimeSync(path: PathLike): number;
|
|
15
|
+
export declare function mkdirSync(path: PathLike | PathLike[], mode?: number | string): void;
|
|
16
|
+
export declare enum MoveOptionsExisting {
|
|
17
|
+
'replace' = 0,
|
|
18
|
+
'rename' = 1,
|
|
19
|
+
'skip' = 2,
|
|
20
|
+
'stop' = 3,
|
|
21
|
+
'throw' = 4
|
|
22
|
+
}
|
|
23
|
+
export interface MoveOptions {
|
|
24
|
+
existing: MoveOptionsExisting | string | ((path: string) => string);
|
|
25
|
+
}
|
|
26
|
+
export declare function moveSync(path: PathLike, newPath: PathLike, _options?: MoveOptions): void;
|
|
27
|
+
export declare function removeSync(path: PathLike | PathLike[], filter?: Filter, keepDir?: boolean): void;
|
|
28
|
+
export declare function copySync(source: PathLike, destination: string, filter?: Filter): any;
|
|
29
|
+
export declare function writeSync(path: PathLike, data: any, options?: WriteFileOptions): void;
|
|
30
|
+
export interface ReadOptions {
|
|
31
|
+
encoding?: BufferEncoding | null;
|
|
32
|
+
flag?: 'a' | 'ax' | 'a+' | 'ax+' | 'as' | 'as+' | 'r' | 'r+' | 'rs+' | 'w' | 'wx' | 'w+' | 'wx+';
|
|
33
|
+
maxAge?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function readSync<R extends Buffer | string | Array<unknown> | Obj>(path: PathLike | URL, options?: ReadOptions | BufferEncoding): R;
|
|
36
|
+
export declare function stripComments(content: string): string;
|
|
37
|
+
export declare function getEntriesSync(dir?: string | string[], filter?: ((entry: string) => boolean) | RegExp | 'files' | 'dirs', depth?: number, skip?: ((entry: string) => boolean) | RegExp): Array<string>;
|
|
38
|
+
export type Filter = (path: string, type?: 'dir' | 'file') => boolean;
|
|
39
|
+
export declare function recursiveSync(path: PathLike | PathLike[], apply: (path: string, type: 'dir' | 'file') => void, filter?: Filter): any | any[];
|
|
40
|
+
export declare function toPosix(path: PathLike, removeDriverLetter?: boolean): string;
|
|
41
|
+
export declare function validFilePath(path: PathLike): string;
|